diff --git a/Components/9918/Implementation/9918.cpp b/Components/9918/Implementation/9918.cpp index 65a4ea339..7ffa65dc6 100644 --- a/Components/9918/Implementation/9918.cpp +++ b/Components/9918/Implementation/9918.cpp @@ -560,7 +560,7 @@ void Base::write_register(uint8_t value) { write_phase_ = false; if(value & 0x80) { if constexpr (is_yamaha_vdp(personality)) { - value &= 0x7f; + value &= 0x3f; } else if constexpr (is_sega_vdp(personality)) { if(value & 0x40) { Storage::cram_is_selected_ = true; @@ -571,17 +571,10 @@ void Base::write_register(uint8_t value) { value &= 0x7; } - // This is a write to a register. + // This is a write to a register; handle all generic + // TMS registers here (with potential extra bits). switch(value) { case 0: - if constexpr (is_sega_vdp(personality)) { - Storage::vertical_scroll_lock_ = low_write_ & 0x80; - Storage::horizontal_scroll_lock_ = low_write_ & 0x40; - Storage::hide_left_column_ = low_write_ & 0x20; - enable_line_interrupts_ = low_write_ & 0x10; - Storage::shift_sprites_8px_left_ = low_write_ & 0x08; - Storage::mode4_enable_ = low_write_ & 0x04; - } mode2_enable_ = low_write_ & 0x02; break; @@ -600,10 +593,6 @@ void Base::write_register(uint8_t value) { case 2: pattern_name_address_ = size_t((low_write_ & 0xf) << 10) | 0x3ff; - - if constexpr (is_sega_vdp(personality)) { - Storage::pattern_name_address_ = pattern_name_address_ | ((personality == TMS::SMSVDP) ? 0x000 : 0x400); - } break; case 3: @@ -616,16 +605,10 @@ void Base::write_register(uint8_t value) { case 5: sprite_attribute_table_address_ = size_t((low_write_ & 0x7f) << 7) | 0x7f; - if constexpr (is_sega_vdp(personality)) { - Storage::sprite_attribute_table_address_ = sprite_attribute_table_address_ | ((personality == TMS::SMSVDP) ? 0x00 : 0x80); - } break; case 6: sprite_generator_table_address_ = size_t((low_write_ & 0x07) << 11) | 0x7ff; - if constexpr (is_sega_vdp(personality)) { - Storage::sprite_generator_table_address_ = sprite_generator_table_address_ | ((personality == TMS::SMSVDP) ? 0x0000 : 0x1800); - } break; case 7: @@ -633,39 +616,196 @@ void Base::write_register(uint8_t value) { background_colour_ = low_write_ & 0xf; break; - case 8: - if constexpr (is_sega_vdp(personality)) { + default: break; + } + + if constexpr (is_sega_vdp(personality)) { + switch(value) { + default: break; + + case 0: + Storage::vertical_scroll_lock_ = low_write_ & 0x80; + Storage::horizontal_scroll_lock_ = low_write_ & 0x40; + Storage::hide_left_column_ = low_write_ & 0x20; + enable_line_interrupts_ = low_write_ & 0x10; + Storage::shift_sprites_8px_left_ = low_write_ & 0x08; + Storage::mode4_enable_ = low_write_ & 0x04; + break; + + case 2: + Storage::pattern_name_address_ = pattern_name_address_ | ((personality == TMS::SMSVDP) ? 0x000 : 0x400); + break; + + case 5: + Storage::sprite_attribute_table_address_ = sprite_attribute_table_address_ | ((personality == TMS::SMSVDP) ? 0x00 : 0x80); + break; + + case 6: + Storage::sprite_generator_table_address_ = sprite_generator_table_address_ | ((personality == TMS::SMSVDP) ? 0x0000 : 0x1800); + break; + + case 8: Storage::horizontal_scroll_ = low_write_; - } else { - LOG("Unknown TMS write: " << int(low_write_) << " to " << int(value)); - } - break; + break; - case 9: - if constexpr (is_sega_vdp(personality)) { + case 9: Storage::vertical_scroll_ = low_write_; - } else { - LOG("Unknown TMS write: " << int(low_write_) << " to " << int(value)); - } - break; + break; - case 10: - if constexpr (is_sega_vdp(personality)) { + case 10: line_interrupt_target_ = low_write_; - } else { - LOG("Unknown TMS write: " << int(low_write_) << " to " << int(value)); - } - break; + break; + } + } - case 15: - if constexpr (is_yamaha_vdp(personality)) { + if constexpr (is_yamaha_vdp(personality)) { + switch(value) { + default: break; + + case 0: + LOG("TODO: Yamaha additional mode selection; " << PADHEX(2) << +low_write_); + // b1–b3: M3–M5 + // b4: enable horizontal retrace interrupt + // b5: enable light pen interrupts + // b6: set colour bus to input or output mode + break; + + case 8: + LOG("TODO: Yamaha VRAM organisation, sprite disable, etc; " << PADHEX(2) << +low_write_); + // b7: "1 = input on colour bus, enable mouse; 1 = output on colour bus, disable mouse" [documentation clearly in error] + // b6: 1 = enable light pen + // b5: sets the colour of code 0 to the colour of the palette (???) + // b4: 1 = colour bus in input mode; 0 = colour bus in output mode + // b3: 1 = VRAM is 64kx1 or 64kx4; 0 = 16kx1 or 16kx4; affects refresh. + // b1: 1 = disable sprites (and release sprite access slots) + // b0: 1 = output in grayscale + break; + + case 9: + LOG("TODO: Yamaha line count, interlace, etc; " << PADHEX(2) << +low_write_); + // b7: 1 = 212 lines of pixels; 0 = 192 + // b5 & b4: select simultaneous mode (seems to relate to line length and in-phase colour?) + // b3: 1 = interlace on + // b2: 1 = display two graphic screens interchangeably by even/odd field + // b1: 1 = PAL mode; 0 = NTSC mode + // b0: 1 = [dot clock] DLCLK is input; 0 = DLCLK is output + break; + + case 10: + LOG("TODO: Yamaha colour table high bits; " << PADHEX(2) << +low_write_); + // b0–b2: A14–A16 of the colour table. + break; + + case 11: + LOG("TODO: Yamaha sprite table high bits; " << PADHEX(2) << +low_write_); + // b0–b1: A15–A16 of the sprite table. + break; + + case 12: + LOG("TODO: Yamaha text and background blink colour; " << PADHEX(2) << +low_write_); + // as per register 7, but in blink mode. + break; + + case 13: + LOG("TODO: Yamaha blink display times; " << PADHEX(2) << +low_write_); + // b0–b3: display time for odd page; + // b4–b7: display time for even page. + break; + + case 14: + LOG("TODO: Yamaha A14–A16 selection; " << PADHEX(2) << +low_write_); + // b0–b2: A14–A16 of address counter (i.e. ram_pointer_) + break; + + case 15: Storage::selected_status_ = low_write_ & 0xf; - } - break; + break; - default: - LOG("Unknown TMS write: " << int(low_write_) << " to " << int(value)); - break; + case 16: + LOG("TODO: Yamaha palette index selection; " << PADHEX(2) << +low_write_); + // b0–b3: palette entry for writing on port 2; autoincrements upon every write. + break; + + case 17: + LOG("TODO: Yamaha indirect addressing; " << PADHEX(2) << +low_write_); + // b7: 1 = disable autoincrementing; 0 = enable. + // b5–b0: register number + break; + + case 18: + LOG("TODO: Yamaha position adjustment; " << PADHEX(2) << +low_write_); + // b0-b3: horizontal adjustment + // b4-b7: vertical adjustment + break; + + case 19: + LOG("TODO: Yamaha interrupt line; " << PADHEX(2) << +low_write_); + // b0–b7: line to match for interrupts (if eabled) + break; + + case 20: + case 21: + case 22: + LOG("TODO: Yamaha colour burst selection; " << PADHEX(2) << +low_write_); + // Documentation is "fill with 0s for no colour burst; magic pattern for colour burst" + break; + + case 23: + LOG("TODO: Yamaha vertical offset; " << PADHEX(2) << +low_write_); + // i.e. scrolling. + break; + + case 32: + case 33: + LOG("TODO: Yamaha command source x; " << PADHEX(2) << +low_write_); + break; + + case 34: + case 35: + LOG("TODO: Yamaha command source y; " << PADHEX(2) << +low_write_); + break; + + case 36: + case 37: + LOG("TODO: Yamaha command destination x; " << PADHEX(2) << +low_write_); + break; + + case 38: + case 39: + LOG("TODO: Yamaha command destination y; " << PADHEX(2) << +low_write_); + break; + + case 40: + case 41: + LOG("TODO: Yamaha command size x; " << PADHEX(2) << +low_write_); + break; + + case 42: + case 43: + LOG("TODO: Yamaha command size y; " << PADHEX(2) << +low_write_); + break; + + case 44: + LOG("TODO: Yamaha command colour; " << PADHEX(2) << +low_write_); + break; + + case 45: + LOG("TODO: Yamaha VRAM bank selection addressing and command arguments; " << PADHEX(2) << +low_write_); + // b6: 0 = video RAM; 1 = expandion RAM. + // b5: MXD (???) + // b4: MXS + // b3: DIY + // b2: DIX + // b1: EQ + // b0: MAJ + break; + + case 46: + LOG("TODO: Yamaha command; " << PADHEX(2) << +low_write_); + // b0–b3: LO0–LO3 (???) + // b4–b7: CM0-CM3 (???) + break; + } } } else { // This is an access via the RAM pointer.