diff options
author | arbee <rb6502@users.noreply.github.com> | 2020-08-01 21:52:03 -0400 |
---|---|---|
committer | arbee <rb6502@users.noreply.github.com> | 2020-08-01 21:52:03 -0400 |
commit | e7697364dded3511a0f0e478db4816ea5951f19b (patch) | |
tree | b138c2311177b547957e99c9253146853ef2cf64 | |
parent | e3d9c0afd88a5c605df09b4a1365e4d60f164f45 (diff) |
apple2e: Add RGB monitor mode, including monochrome and mixed color/mono DHGR and full-color text. [R. Belmont]
-rw-r--r-- | src/mame/drivers/apple2e.cpp | 11 | ||||
-rw-r--r-- | src/mame/video/apple2.cpp | 160 | ||||
-rw-r--r-- | src/mame/video/apple2.h | 4 |
3 files changed, 158 insertions, 17 deletions
diff --git a/src/mame/drivers/apple2e.cpp b/src/mame/drivers/apple2e.cpp index 9a3b5f01b43..3366c68a326 100644 --- a/src/mame/drivers/apple2e.cpp +++ b/src/mame/drivers/apple2e.cpp @@ -3100,7 +3100,7 @@ void apple2e_state::apple2c_map(address_map &map) map(0xc000, 0xc07f).rw(FUNC(apple2e_state::c000_iic_r), FUNC(apple2e_state::c000_iic_w)); map(0xc080, 0xc0ff).rw(FUNC(apple2e_state::c080_r), FUNC(apple2e_state::c080_w)); map(0xc098, 0xc09b).rw(m_acia1, FUNC(mos6551_device::read), FUNC(mos6551_device::write)); - map(0xc0a8, 0xc0ab).rw(IIC_ACIA2_TAG, FUNC(mos6551_device::read), FUNC(mos6551_device::write)); + map(0xc0a8, 0xc0ab).rw(m_acia2, FUNC(mos6551_device::read), FUNC(mos6551_device::write)); map(0xc100, 0xc2ff).m(m_c100bank, FUNC(address_map_bank_device::amap8)); map(0xc300, 0xc3ff).m(m_c300bank, FUNC(address_map_bank_device::amap8)); map(0xc400, 0xc7ff).m(m_c400bank, FUNC(address_map_bank_device::amap8)); @@ -3119,7 +3119,7 @@ void apple2e_state::apple2c_memexp_map(address_map &map) map(0xc000, 0xc07f).rw(FUNC(apple2e_state::c000_iic_r), FUNC(apple2e_state::c000_iic_w)); map(0xc080, 0xc0ff).rw(FUNC(apple2e_state::c080_r), FUNC(apple2e_state::c080_w)); map(0xc098, 0xc09b).rw(m_acia1, FUNC(mos6551_device::read), FUNC(mos6551_device::write)); - map(0xc0a8, 0xc0ab).rw(IIC_ACIA2_TAG, FUNC(mos6551_device::read), FUNC(mos6551_device::write)); + map(0xc0a8, 0xc0ab).rw(m_acia2, FUNC(mos6551_device::read), FUNC(mos6551_device::write)); map(0xc0c0, 0xc0c3).rw(FUNC(apple2e_state::memexp_r), FUNC(apple2e_state::memexp_w)); map(0xc100, 0xc2ff).m(m_c100bank, FUNC(address_map_bank_device::amap8)); map(0xc300, 0xc3ff).m(m_c300bank, FUNC(address_map_bank_device::amap8)); @@ -3352,11 +3352,12 @@ TIMER_DEVICE_CALLBACK_MEMBER(apple2e_state::ay3600_repeat) static INPUT_PORTS_START( apple2_sysconfig ) PORT_START("a2_config") - PORT_CONFNAME(0x03, 0x00, "Composite monitor type") + PORT_CONFNAME(0x07, 0x00, "Monitor type") PORT_CONFSETTING(0x00, "Color") PORT_CONFSETTING(0x01, "B&W") PORT_CONFSETTING(0x02, "Green") PORT_CONFSETTING(0x03, "Amber") + PORT_CONFSETTING(0x04, "Video-7 RGB") PORT_CONFNAME(0x10, 0x00, "CPU type") PORT_CONFSETTING(0x00, "Standard") @@ -4691,10 +4692,12 @@ void apple2e_state::apple2c(machine_config &config) MOS6551(config, m_acia1, 0); m_acia1->set_xtal(XTAL(14'318'181) / 8); // ~1.789 MHz m_acia1->txd_handler().set(PRINTER_PORT_TAG, FUNC(rs232_port_device::write_txd)); + m_acia1->irq_handler().set(FUNC(apple2e_state::a2bus_irq_w)); MOS6551(config, m_acia2, 0); - m_acia2->set_xtal(XTAL(1'843'200)); // matches SSC so modem software is compatible + m_acia2->set_xtal(1.8432_MHz_XTAL); // matches SSC so modem software is compatible m_acia2->txd_handler().set("modem", FUNC(rs232_port_device::write_txd)); + m_acia2->irq_handler().set(FUNC(apple2e_state::a2bus_irq_w)); rs232_port_device &printer(RS232_PORT(config, PRINTER_PORT_TAG, default_rs232_devices, nullptr)); printer.rxd_handler().set(m_acia1, FUNC(mos6551_device::write_rxd)); diff --git a/src/mame/video/apple2.cpp b/src/mame/video/apple2.cpp index b3eeec75eb6..37e3819052c 100644 --- a/src/mame/video/apple2.cpp +++ b/src/mame/video/apple2.cpp @@ -118,6 +118,7 @@ void a2_video_device::device_start() save_item(NAME(m_GSborder)); save_item(NAME(m_newvideo)); save_item(NAME(m_monochrome)); + save_item(NAME(m_rgbmode)); save_item(NAME(m_shr_palette)); } @@ -136,6 +137,7 @@ void a2_video_device::device_reset() m_80store = false; m_monohgr = false; m_newvideo = 0x01; + m_rgbmode = 3; // default to color DHGR } WRITE_LINE_MEMBER(a2_video_device::txt_w) @@ -174,6 +176,14 @@ WRITE_LINE_MEMBER(a2_video_device::dhires_w) { // select double hi-res screen().update_now(); + + // RGB cards shift in a mode bit on the rising edge + if ((m_dhires) && (state)) + { + m_rgbmode = (m_rgbmode << 1) & 3; + m_rgbmode |= m_80col ? 1 : 0; + } + m_dhires = !state; } @@ -453,7 +463,7 @@ void a2_video_device::lores_update(screen_device &screen, bitmap_ind16 &bitmap, switch (m_sysconfig & 0x03) { - case 0: fg = WHITE; break; + case 0: case 4: fg = WHITE; break; case 1: fg = WHITE; break; case 2: fg = GREEN; break; case 3: fg = ORANGE; break; @@ -570,7 +580,7 @@ void a2_video_device::dlores_update(screen_device &screen, bitmap_ind16 &bitmap, switch (m_sysconfig & 0x03) { - case 0: fg = WHITE; break; + case 0: case 4: fg = WHITE; break; case 1: fg = WHITE; break; case 2: fg = GREEN; break; case 3: fg = ORANGE; break; @@ -750,13 +760,14 @@ void a2_video_device::text_update(screen_device &screen, bitmap_ind16 &bitmap, c int fg = 0; int bg = 0; + if (m_aux_ptr) + { + aux_page = m_aux_ptr; + } + if (m_80col) { start_address = 0x400; - if (m_aux_ptr) - { - aux_page = m_aux_ptr; - } } else { @@ -768,7 +779,7 @@ void a2_video_device::text_update(screen_device &screen, bitmap_ind16 &bitmap, c switch (m_sysconfig & 0x03) { - case 0: fg = WHITE; break; + case 0: case 4: fg = WHITE; break; case 1: fg = WHITE; break; case 2: fg = GREEN; break; case 3: fg = ORANGE; break; @@ -795,6 +806,13 @@ void a2_video_device::text_update(screen_device &screen, bitmap_ind16 &bitmap, c { /* calculate address */ address = start_address + ((((row/8) & 0x07) << 7) | (((row/8) & 0x18) * 5 + col)); + if (((m_sysconfig & 7) == 4) && (m_dhires)) + { + u8 tmp = aux_page[address]; + fg = tmp>>4; + bg = tmp & 0xf; + } + plot_text_character(bitmap, col * 14, row, 2, m_ram_ptr[address], m_char_ptr, m_char_size, fg, bg); } @@ -815,7 +833,7 @@ void a2_video_device::text_update_orig(screen_device &screen, bitmap_ind16 &bitm switch (m_sysconfig & 0x03) { - case 0: fg = WHITE; break; + case 0: case 4: fg = WHITE; break; case 1: fg = WHITE; break; case 2: fg = GREEN; break; case 3: fg = ORANGE; break; @@ -1027,6 +1045,12 @@ void a2_video_device::hgr_update(screen_device &screen, bitmap_ind16 &bitmap, co mon_type = 1; } + // IIgs $C021 monochrome HGR + if (m_monochrome & 0x80) + { + mon_type = 1; + } + switch (mon_type) { case 0: @@ -1225,6 +1249,8 @@ void a2_video_device::dhgr_update(screen_device &screen, bitmap_ind16 &bitmap, c uint32_t w; int page = m_page2 ? 0x4000 : 0x2000; int mon_type = m_sysconfig & 0x03; + bool bIsRGB = ((m_sysconfig & 7) == 4); + bool bIsRGBMixed = ((bIsRGB) && (m_rgbmode == 1)); // IIgs force-monochrome-DHR setting if (m_newvideo & 0x20) @@ -1232,6 +1258,12 @@ void a2_video_device::dhgr_update(screen_device &screen, bitmap_ind16 &bitmap, c mon_type = 1; } + // IIe RGB card monochrome DHR + if ((bIsRGB) && (m_rgbmode == 0)) + { + mon_type = 1; + } + /* sanity checks */ if (beginrow < cliprect.top()) beginrow = cliprect.top(); @@ -1265,19 +1297,96 @@ void a2_video_device::dhgr_update(screen_device &screen, bitmap_ind16 &bitmap, c p = &bitmap.pix16(row); + // RGB DHR 160-wide mode + if ((bIsRGB) && (m_rgbmode == 2)) + { + mon_type = 4; + } + for (col = 0; col < 80; col++) { w = (((uint32_t) vram_row[col+0] & 0x7f) << 0) | (((uint32_t) vram_row[col+1] & 0x7f) << 7) | (((uint32_t) vram_row[col+2] & 0x7f) << 14); + /* + DHGR pixel layout: + column & 3 = 0 1 2 3 + nBBBAAAA nDDCCCCB nFEEEEDD nGGGGFFF + + n is don't care on the stock hardware's NTSC output. + + On RGB cards, in mixed mode (DHGR with special mode value == 1), n + controls if a pixel quad starting in that byte is color or monochrome. + Pixel quads A&B are controlled by n in byte 0, C&D by n in byte 1, + E&F by n in byte 2, and G by n in byte 3. + */ + switch (mon_type) { case 0: - for (b = 0; b < 7; b++) + // every 3rd column, the first pixel quad is controlled by the previous + // byte's MSB, because we always draw 2 quads per column. + if ((bIsRGBMixed) && ((col & 3) == 3)) { - v = m_dhires_artifact_map[((((w >> (b + 7-1)) & 0x0F) * 0x11) >> (((2-(col*7+b))) & 0x03)) & 0x0F]; - *(p++) = v; + uint32_t tw = (w >> 6); + + if (!(vram_row[col-1] & 0x80)) + { + for (b = 0; b < 4; b++) + { + v = (tw & 1); + tw >>= 1; + *(p++) = v ? WHITE : BLACK; + } + } + else + { + for (b = 0; b < 4; b++) + { + v = m_dhires_artifact_map[((((w >> (b + 7-1)) & 0x0F) * 0x11) >> (((2-(col*7+b))) & 0x03)) & 0x0F]; + *(p++) = v; + } + } + + if (!(vram_row[col] & 0x80)) + { + for (b = 4; b < 7; b++) + { + v = (tw & 1); + tw >>= 1; + *(p++) = v ? WHITE : BLACK; + } + } + else + { + for (b = 4; b < 7; b++) + { + v = m_dhires_artifact_map[((((w >> (b + 7-1)) & 0x0F) * 0x11) >> (((2-(col*7+b))) & 0x03)) & 0x0F]; + *(p++) = v; + } + } + } + else + { + if ((bIsRGBMixed) && !(vram_row[col] & 0x80)) + { + uint32_t tw = (w >> 6); + for (b = 0; b < 7; b++) + { + v = (tw & 1); + tw >>= 1; + *(p++) = v ? WHITE : BLACK; + } + } + else + { + for (b = 0; b < 7; b++) + { + v = m_dhires_artifact_map[((((w >> (b + 7-1)) & 0x0F) * 0x11) >> (((2-(col*7+b))) & 0x03)) & 0x0F]; + *(p++) = v; + } + } } break; @@ -1310,6 +1419,35 @@ void a2_video_device::dhgr_update(screen_device &screen, bitmap_ind16 &bitmap, c *(p++) = v ? ORANGE : BLACK; } break; + + // RGB 160-wide mode (which has a much simpler VRAM layout) + case 4: + if (col == 0) + { + // Center the 480-wide image in the 560-wide display. + // Aspect ratio won't be perfect, but it's in range. + for (b = 0; b < 40; b++) + { + *(p++) = BLACK; + } + } + v = vram_row[col]; + *(p++) = v & 0xf; + *(p++) = v & 0xf; + *(p++) = v & 0xf; + v >>= 4; + *(p++) = v & 0xf; + *(p++) = v & 0xf; + *(p++) = v & 0xf; + break; + } + } + + if (mon_type == 4) + { + for (b = 0; b < 40; b++) + { + *(p++) = BLACK; } } } diff --git a/src/mame/video/apple2.h b/src/mame/video/apple2.h index c5256f37728..a87c2aab6ce 100644 --- a/src/mame/video/apple2.h +++ b/src/mame/video/apple2.h @@ -32,8 +32,8 @@ public: bool m_an2; bool m_80store; bool m_monohgr; - uint8_t m_GSfg, m_GSbg, m_GSborder, m_newvideo, m_monochrome; - uint32_t m_GSborder_colors[16], m_shr_palette[256]; + u8 m_GSfg, m_GSbg, m_GSborder, m_newvideo, m_monochrome, m_rgbmode; + u32 m_GSborder_colors[16], m_shr_palette[256]; std::unique_ptr<bitmap_ind16> m_8bit_graphics; std::unique_ptr<uint16_t[]> m_hires_artifact_map; std::unique_ptr<uint16_t[]> m_dhires_artifact_map; |