diff options
| author | 2026-04-23 13:14:19 +0200 | |
|---|---|---|
| committer | 2026-04-23 16:10:47 +0200 | |
| commit | 2bc3d912401c3aadb2ddf8b8005de8b1c6b73cd4 (patch) | |
| tree | e7b4ffac584f56ebcf93182e5177d53f2a699691 | |
| parent | c01cc03f03ec15edd0c9a67cfb654bca75810225 (diff) | |
sony/smc777.cpp: implement 640x200x2bpp mode, improve DE-9 handling
| -rw-r--r-- | hash/smc777.xml | 16 | ||||
| -rw-r--r-- | src/mame/sony/smc777.cpp | 105 |
2 files changed, 84 insertions, 37 deletions
diff --git a/hash/smc777.xml b/hash/smc777.xml index 08bde1e2a36..89ddd70f6ac 100644 --- a/hash/smc777.xml +++ b/hash/smc777.xml @@ -155,7 +155,8 @@ File viewer, useful for executing non autobootable disks in drive B: <year>198?</year> <publisher><unknown></publisher> <notes><![CDATA[ -Unreadable graphics, should require [kanji] hookup +[MC6845] uses 640x200x2bpp color mode +Requires [kanji] hookup ]]></notes> <part name="flop1" interface="floppy_3_5"> @@ -170,7 +171,8 @@ Unreadable graphics, should require [kanji] hookup <year>198?</year> <publisher><unknown></publisher> <notes><![CDATA[ -Unreadable graphics, should require [kanji] hookup +[MC6845] uses 640x200x2bpp color mode +Requires [kanji] hookup ]]></notes> <part name="flop1" interface="floppy_3_5"> @@ -442,7 +444,7 @@ Untested [floppy] saving <year>1984</year> <publisher>ブレーンメディア (Brain Media)</publisher> <notes><![CDATA[ -Black screen +Black screen, uses [MC6845] DE readback for something ]]></notes> <info name="alt_title" value="ファイアドラゴン"/> @@ -802,7 +804,8 @@ Unresponsive [keyboard] <year>1983</year> <publisher>光栄 (Koei)</publisher> <notes><![CDATA[ -[MC6845] bad colors on graphic layer (similar to kanjicpm) +[MC6845] uses 640x200x2bpp color mode +Untested [FDC] saving ]]></notes> <info name="alt_title" value="信長の野望"/> @@ -1092,6 +1095,7 @@ Standalone version of MAHJONG.COM in compinv d88: Floppy disk has excess of heads for this drive that will be discarded (floppy heads=2, drive heads=1) ]]></notes> <info name="alt_title" value="野球狂" /> + <sharedfeat name="joystick2_default" value="joystick" /> <part name="flop1" interface="floppy_3_5"> <dataarea name="flop" size="70352"> @@ -1105,9 +1109,11 @@ d88: Floppy disk has excess of heads for this drive that will be discarded (flop <year>1984</year> <publisher>ハドソン (Hudson Soft)</publisher> <notes><![CDATA[ -[MC6845] bad colors on graphic layer (same as nobunaga?) +[MC6845] uses 640x200x2bpp color mode +Player-2 inputs doesn't work ]]></notes> <info name="alt_title" value="野球狂" /> + <sharedfeat name="joystick2_default" value="joystick" /> <part name="flop1" interface="floppy_3_5"> <dataarea name="flop" size="322208"> diff --git a/src/mame/sony/smc777.cpp b/src/mame/sony/smc777.cpp index 058488ab0ca..d70ba9bfa13 100644 --- a/src/mame/sony/smc777.cpp +++ b/src/mame/sony/smc777.cpp @@ -120,10 +120,13 @@ private: uint8_t vsync_irq_status_r(); void vsync_irq_enable_w(uint8_t data); void palette_init(palette_device &palette) const; - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); void vsync_w(int state); TIMER_DEVICE_CALLBACK_MEMBER(keyboard_callback); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + void graphic_320x200x4(bitmap_ind16 &bitmap, const rectangle &cliprect); + void graphic_640x200x2(bitmap_ind16 &bitmap, const rectangle &cliprect); + uint8_t fdc_r(offs_t offset); void fdc_w(offs_t offset, uint8_t data); uint8_t fdc1_fast_status_r(); @@ -170,6 +173,7 @@ private: uint8_t m_crtc_addr = 0; bool m_vsync_idf = false; bool m_vsync_ief = false; + uint8_t m_de; }; @@ -192,49 +196,75 @@ void smc777_state::video_start() } // TODO: cleanup, move to device, honor cliprect -uint32_t smc777_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +void smc777_state::graphic_320x200x4(bitmap_ind16 &bitmap, const rectangle &cliprect) { - bitmap.fill(m_palette->pen(m_backdrop_pen), cliprect); + const u16 bitmap_pitch = mc6845_h_display * 2; - int x_width = BIT(m_display_reg, 7); + for(int y = 0; y < mc6845_v_display; y++) + { + const u32 base_address = y * bitmap_pitch + mc6845_start_addr * 2; + const int res_y = y * 8 + CRTC_MIN_Y; + + for(int x = 0; x < bitmap_pitch; x++) + { + const int res_x = x * 4 + CRTC_MIN_X; + for(int yi = 0; yi < 8; yi++) + { + const u8 dot = m_gvram[base_address + x + yi * 0x1000]; + u8 color = (dot & 0xf0) >> 4; + bitmap.pix(res_y + yi, res_x + 0) = m_palette->pen(color); + bitmap.pix(res_y + yi, res_x + 1) = m_palette->pen(color); + + color = (dot & 0x0f) >> 0; + bitmap.pix(res_y + yi, res_x + 2) = m_palette->pen(color); + bitmap.pix(res_y + yi, res_x + 3) = m_palette->pen(color); + } + } + } +} +void smc777_state::graphic_640x200x2(bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + const u8 color_table[8] = { 0x00, 0x04, 0x02, 0x01, 0x00, 0x04, 0x02, 0x07 }; const u16 bitmap_pitch = mc6845_h_display * 2; + const u8 color_bank = BIT(m_display_reg, 5) << 2; + for(int y = 0; y < mc6845_v_display; y++) { // comp2:HETZER uses start address for double buffering const u32 base_address = y * bitmap_pitch + mc6845_start_addr * 2; + const int res_y = y * 8 + CRTC_MIN_Y; + for(int x = 0; x < bitmap_pitch; x++) { + const int res_x = x * 4 + CRTC_MIN_X; for(int yi = 0; yi < 8; yi++) { - u8 color = (m_gvram[base_address + x + yi * 0x1000] & 0xf0) >> 4; - - //if(x_width) + const u8 dot = m_gvram[base_address + x + yi * 0x1000]; + for (int xi = 0; xi < 4; xi++) { - bitmap.pix(y * 8 + yi + CRTC_MIN_Y, x * 4 + 0 + CRTC_MIN_X) = m_palette->pen(color); - bitmap.pix(y * 8 + yi + CRTC_MIN_Y, x * 4 + 1 + CRTC_MIN_X) = m_palette->pen(color); + u8 color = (dot >> (6 - (xi * 2))) & 3; + color |= color_bank; + bitmap.pix(res_y + yi, res_x + xi) = m_palette->pen(color_table[color]); } - //else - //{ - // bitmap.pix(y+yi+CRTC_MIN_Y, x*2+0+CRTC_MIN_X) = m_palette->pen(color); - //} - - color = (m_gvram[base_address + x + yi * 0x1000] & 0x0f) >> 0; - //if(x_width) - { - bitmap.pix(y * 8 + yi + CRTC_MIN_Y, x * 4 + 2 + CRTC_MIN_X) = m_palette->pen(color); - bitmap.pix(y * 8 + yi + CRTC_MIN_Y, x * 4 + 3 + CRTC_MIN_X) = m_palette->pen(color); - } - //else - //{ - // bitmap.pix(y+yi+CRTC_MIN_Y, x*2+1+CRTC_MIN_X) = m_palette->pen(color); - //} - } } } +} +uint32_t smc777_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + bitmap.fill(m_palette->pen(m_backdrop_pen), cliprect); + + int x_width = BIT(m_display_reg, 7); + + if (BIT(m_display_reg, 3)) + graphic_640x200x2(bitmap, cliprect); + else + graphic_320x200x4(bitmap, cliprect); + + // TODO: remove count usage u16 count = 0x0000; for(int y = 0; y < mc6845_v_display; y++) @@ -604,7 +634,7 @@ void smc777_state::color_mode_w(offs_t offset, uint8_t data) { switch(data & 0x07) { - case 0x05: m_joystick_port[BIT(offset, 8)]->pin_8_w(BIT(data, 4)); break; + case 0x05: m_joystick_port[!BIT(offset, 8)]->pin_8_w(BIT(data, 4)); break; case 0x06: m_pal_mode = (data & 0x10) ^ 0x10; break; default: logerror("Color FF %02x\n",data); break; } @@ -696,7 +726,7 @@ void smc777_state::vsync_irq_enable_w(uint8_t data) logerror("Irq mask = %02x\n",data & 0xfe); // IRQ mask - m_vsync_ief = BIT(data,0); + m_vsync_ief = BIT(data, 0); // TODO: clear idf on 1->0 irq mask transition? } @@ -738,8 +768,18 @@ void smc777_state::io_map(address_map &map) // map(0x40, 0x47) ieee-488 / TMS9914A I/F map(0x44, 0x44).mirror(0xff00).portr("GPDSW"); // normally unmapped in GPIB interface // map(0x48, 0x49) hdd (winchester) + // joystick read (all active low) + // x--- ---- /BL, in blanking + // -x-- ---- /CS, joystick 2 present + // --x- ---- /USER, DE-9 port 2 button 2 (unconnected on port 1) + // ---x xxxx from DE-9 map(0x51, 0x51).select(0xff00).lr8(NAME([this] (offs_t offset) { - return m_joystick_port[BIT(offset, 8)]->read() & 0x7f; + const u8 joy_select = !BIT(offset, 8); + const u8 mask = 0x1f | (joy_select << 5); + const u8 joy2_cs = (!m_joystick_port[1]->exists()) << 6; + const u8 joy_in = m_joystick_port[!BIT(offset, 8)]->read() & mask; + + return joy_in | joy2_cs | m_de; })).w(FUNC(smc777_state::color_mode_w)); map(0x52, 0x52).select(0xff00).w(FUNC(smc777_state::ramdac_w)); map(0x53, 0x53).mirror(0xff00).w("sn1", FUNC(sn76489a_device::write)); @@ -1163,6 +1203,7 @@ void smc777_state::smc777(machine_config &config) m_crtc->set_show_border_area(true); m_crtc->set_char_width(8); m_crtc->out_vsync_callback().set(FUNC(smc777_state::vsync_w)); + m_crtc->out_de_callback().set([this] (int state) { m_de = state << 7; }); // TODO: MB8877A really MB8876(config, m_fdc, MASTER_CLOCK / 32); // divider not confirmed @@ -1177,10 +1218,10 @@ void smc777_state::smc777(machine_config &config) QUICKLOAD(config, "quickload", "com,cpm", attotime::from_seconds(3)).set_load_callback(FUNC(smc777_state::quickload_cb)); // No clue about bundled defaults but: - // - dragon expects joystick in port 2 - // - comp2:SMCPAINT expects mouse in port 1 - MSX_GENERAL_PURPOSE_PORT(config, m_joystick_port[0], msx_general_purpose_port_devices, "mouse"); - MSX_GENERAL_PURPOSE_PORT(config, m_joystick_port[1], msx_general_purpose_port_devices, "joystick"); + // - dragon expects joystick in port 1 + // - comp2:SMCPAINT expects mouse in port 2 + MSX_GENERAL_PURPOSE_PORT(config, m_joystick_port[0], msx_general_purpose_port_devices, "joystick"); + MSX_GENERAL_PURPOSE_PORT(config, m_joystick_port[1], msx_general_purpose_port_devices, "mouse"); SPEAKER(config, "mono").front_center(); |
