summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author angelosa <lordkale4@gmail.com>2026-04-23 13:14:19 +0200
committer angelosa <lordkale4@gmail.com>2026-04-23 16:10:47 +0200
commit2bc3d912401c3aadb2ddf8b8005de8b1c6b73cd4 (patch)
treee7b4ffac584f56ebcf93182e5177d53f2a699691
parentc01cc03f03ec15edd0c9a67cfb654bca75810225 (diff)
sony/smc777.cpp: implement 640x200x2bpp mode, improve DE-9 handling
-rw-r--r--hash/smc777.xml16
-rw-r--r--src/mame/sony/smc777.cpp105
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>&lt;unknown&gt;</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>&lt;unknown&gt;</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();