1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-10 00:29:40 +00:00

Fix top line of cursor, add pretend cursor, page video separately.

This commit is contained in:
Thomas Harte 2024-12-18 21:48:03 -05:00
parent 81398d58a2
commit 096f48be33
2 changed files with 64 additions and 31 deletions

View File

@ -114,7 +114,7 @@ public:
m6502_(*this),
interrupts_(*this),
timers_(interrupts_),
video_(map_, interrupts_)
video_(video_map_, interrupts_)
{
set_clock_rate(PALclock);
@ -132,7 +132,9 @@ public:
Memory::Fuzz(ram_);
map_.page<PagerSide::ReadWrite, 0, 65536>(ram_.data());
page_rom();
page_cpu_rom();
video_map_.page<PagerSide::ReadWrite, 0, 65536>(ram_.data());
insert_media(target.media);
}
@ -255,6 +257,12 @@ public:
case 0xff12:
ff12_ = *value & 0x3f;
video_.write<0xff12>(*value);
if((*value & 4)) {
page_video_rom();
} else {
page_video_ram();
}
break;
case 0xff13:
ff13_ = *value & 0xfe;
@ -270,8 +278,8 @@ public:
case 0xff18: video_.write<0xff18>(*value); break;
case 0xff19: video_.write<0xff19>(*value); break;
case 0xff3e: page_rom(); break;
case 0xff3f: page_ram(); break;
case 0xff3e: page_cpu_rom(); break;
case 0xff3f: page_cpu_ram(); break;
// TODO: audio is 0xff10, 0xff11, 0xff0e, 0xff0f and shares 0xff18.
@ -294,13 +302,21 @@ private:
m6502_.set_ready_line(active);
}
void page_rom() {
void page_video_rom() {
video_map_.page<PagerSide::Read, 0x8000, 16384>(basic_.data());
video_map_.page<PagerSide::Read, 0xc000, 16384>(kernel_.data());
}
void page_video_ram() {
video_map_.page<PagerSide::Read, 0x8000, 32768>(&ram_[0x8000]);
}
void page_cpu_rom() {
// TODO: allow other ROM selection. And no ROM?
map_.page<PagerSide::Read, 0x8000, 16384>(basic_.data());
map_.page<PagerSide::Read, 0xc000, 16384>(kernel_.data());
rom_is_paged_ = true;
}
void page_ram() {
void page_cpu_ram() {
map_.page<PagerSide::Read, 0x8000, 32768>(&ram_[0x8000]);
rom_is_paged_ = false;
}
@ -323,6 +339,7 @@ private:
}
Commodore::Plus4::Pager map_;
Commodore::Plus4::Pager video_map_;
std::array<uint8_t, 65536> ram_;
std::vector<uint8_t> kernel_;
std::vector<uint8_t> basic_;

View File

@ -25,8 +25,6 @@ public:
pager_(pager),
interrupts_(interrupts)
{
// TODO: perfect crop.
// crt_.set_visible_area(Outputs::Display::Rect(0.075f - 0.00877193f, 0.065f, 0.85f, 0.85f));
crt_.set_visible_area(crt_.get_rect_for_area(
311 - 257 - 4,
208 + 8,
@ -87,7 +85,7 @@ public:
break;
case 0xff12:
// bitmap_base_ = uint16_t((value & 0x3c) << 10);
bitmap_base_ = uint16_t((value & 0x3c) << 10);
break;
case 0xff13:
character_generator_address_ = uint16_t((value & 0xfc) << 8);
@ -175,6 +173,7 @@ public:
//
const auto attribute_fetch_start = [&] {
character_address_ = 0;
fetch_phase_ = FetchPhase::Waiting;
};
switch(vertical_counter_) {
case 261: // End of screen NTSC. [and hence 0: Attribute fetch start].
@ -239,19 +238,39 @@ public:
fetch_count_ += period;
auto &line = lines_[line_pointer_];
// uint8_t attributes[40];
// uint8_t characters[40];
// } lines_[2];
// int line_pointer_ = 0;
for(int x = start; x < end; x++) {
// line.attributes[x] = pager_.read(character_generator_address_ + x * 8 + (row & 7));
// line.characters[x] = pager_.read(uint16_t(line_character_address_ + x + screen_memory_address_ + 0x400));
const auto offset = (line.characters[x] << 3) + (character_line_ & 7);
bitmap_[x] = pager_.read(uint16_t(
character_generator_address_ +
offset
));
}
// switch(fetch_phase_) {
// case FetchPh
// }
switch(fetch_phase_) {
default: break;
case FetchPhase::FetchingCharacters: {
auto &character_line = lines_[line_pointer_ ^ 1];
for(int x = start; x < end; x++) {
character_line.characters[x] = pager_.read(
screen_memory_address_ + 0x400 +
uint16_t(character_address_ + x)
);
// TEST of cursor position.
if(character_address_ + x == cursor_address_) {
character_line.characters[x] = ']';
}
}
} break;
case FetchPhase::FetchingAttributes:
for(int x = start; x < end; x++) {
line.attributes[x] = pager_.read(
screen_memory_address_ +
uint16_t(character_address_ + x)
);
}
break;
}
}
@ -284,16 +303,11 @@ public:
}
// Output pixels.
// TODO: properly. THIS HACKS IN TEXT OUTPUT. IT IS NOT CORRECT. NOT AS TO TIMING, NOT AS TO CONTENT.
// TODO: properly. Accounting for mode, attributes, etc.
if(pixels_) {
for(int c = 0; c < period; c++) {
const auto pixel = time_in_state_ + c;
const auto row = vertical_counter_ - 4;
const auto index = (row >> 3) * 40 + (pixel >> 3);
const uint8_t character = pager_.read(uint16_t(index + screen_memory_address_ + 0x400));
const uint8_t glyph = pager_.read(character_generator_address_ + character * 8 + (row & 7));
const uint8_t glyph = bitmap_[pixel >> 3];
pixels_[c] = glyph & (0x80 >> (pixel & 7)) ? 0xff00 : 0xffff;
}
pixels_ += period;
@ -314,21 +328,24 @@ public:
case BeginExternalFetchWindow:
external_fetch_ = true;
++character_line_;
// At this point fetch_phase_ is whichever phase is **ending**.
switch(fetch_phase_) {
case FetchPhase::Waiting:
++character_line_;
// TODO: the < 200 is obviously phoney baloney. Figure out what the actual condition is here.
if(vertical_counter_ < 200 && (vertical_counter_&7) == y_scroll_ && vertical_window_) {
if(vertical_counter_ < 200 && (vertical_counter_&7) == y_scroll_) {
fetch_phase_ = FetchPhase::FetchingCharacters;
}
break;
case FetchPhase::FetchingCharacters:
fetch_phase_ = FetchPhase::FetchingAttributes;
character_line_ = 0;
line_pointer_ ^= 1;
break;
case FetchPhase::FetchingAttributes:
fetch_phase_ = FetchPhase::Waiting;
character_address_ += 40;
break;
}
interrupts_.bus().set_ready_line(fetch_phase_ != FetchPhase::Waiting);
@ -337,7 +354,6 @@ public:
break;
case LatchCharacterPosition:
line_character_address_ = character_address_;
break;
case EndCharacterFetchWindow:
@ -426,6 +442,7 @@ private:
uint16_t character_row_address_ = 0;
uint16_t character_generator_address_ = 0;
uint16_t screen_memory_address_ = 0;
uint16_t bitmap_base_ = 0;
int raster_interrupt_ = 0x1ff;
@ -443,7 +460,6 @@ private:
uint8_t ff06_;
uint16_t character_address_ = 0;
uint16_t line_character_address_ = 0;
bool fetch_characters_ = false;
bool external_fetch_ = false;
bool output_pixels_ = false;