From 28d2fc3ad6efc4447f2c37973c2eee30aa305aaf Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Wed, 26 Oct 2022 17:15:27 +0200 Subject: mtu130: Implement mirroring of bfcx, implement lightpen --- src/mame/misc/mtu130.cpp | 165 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 155 insertions(+), 10 deletions(-) diff --git a/src/mame/misc/mtu130.cpp b/src/mame/misc/mtu130.cpp index 6864d7a0eff..40d4c2511ac 100644 --- a/src/mame/misc/mtu130.cpp +++ b/src/mame/misc/mtu130.cpp @@ -13,7 +13,6 @@ // - MTUTAPE, a kind of digital tape? // - MTUNET, some proprietary network // - Sound on user via cb2, it's weird -// - Light pen, need working demo code // Implemented extension boards: // - DATAMOVER, a 68k-based board, used by BASIC 1.5 to accelerate floating point operations @@ -22,9 +21,6 @@ // - PROGRAMMOVER, a z80-based board // - MultI-O, an i/o board -// Probable bug somewhere making the BASIC (light pen, game) demos -// fail in the demonstration disk. - #include "emu.h" #include "cpu/m6502/m6502.h" #include "imagedev/floppy.h" @@ -99,7 +95,10 @@ public: m_id(*this, "id"), m_keyboard(*this, "K%X", 0L), m_keyboard_meta(*this, "KM"), - m_jumpers(*this, "jumpers") + m_jumpers(*this, "jumpers"), + m_lightpen_w(*this, "lightpen_w"), + m_lightpen_x(*this, "lightpen_x"), + m_lightpen_y(*this, "lightpen_y") { } void mtu130(machine_config &config); @@ -166,13 +165,23 @@ private: required_ioport_array<16> m_keyboard; required_ioport m_keyboard_meta; required_ioport m_jumpers; + required_ioport m_lightpen_w; + required_ioport m_lightpen_x; + required_ioport m_lightpen_y; memory_interface *m_maincpu_intf; + emu_timer *m_timer_lightpen_hit; + + int m_lightpen_hit_x, m_lightpen_hit_y; + uint16_t m_dma_adr; u8 m_keyboard_col; u8 m_dac_level; u8 m_id_adr; + + u8 m_lightpen_status, m_lightpen_low, m_lightpen_high; + bool m_dma_direction; bool m_video_unblank; bool m_video_bw; @@ -189,6 +198,15 @@ private: void dma_adr_w(u8 data); DECLARE_WRITE_LINE_MEMBER(dma_drq_w); + TIMER_CALLBACK_MEMBER(lightpen_hit); + void lightpen_trigger(int state); + u8 lightpen_status_r(); + u8 lightpen_low_r(); + u8 lightpen_high_r(); + void lightpen_clear_w(u8); + + void tape_w(u8); + void keyboard_col_clear_w(u8); void user_cb2_w(int line); void sys1_pb_w(u8 data); @@ -345,6 +363,11 @@ void mtu130_state::machine_start() m_video_unblank = true; m_video_bw = true; m_fdc_irq_enabled = false; + m_lightpen_hit_x = 0; + m_lightpen_hit_y = 0; + m_lightpen_status = 0; + m_lightpen_low = 0; + m_lightpen_high = 0; save_item(NAME(m_dma_adr)); save_item(NAME(m_dma_direction)); @@ -354,6 +377,13 @@ void mtu130_state::machine_start() save_item(NAME(m_video_unblank)); save_item(NAME(m_video_bw)); save_item(NAME(m_fdc_irq_enabled)); + save_item(NAME(m_lightpen_hit_x)); + save_item(NAME(m_lightpen_hit_y)); + save_item(NAME(m_lightpen_status)); + save_item(NAME(m_lightpen_low)); + save_item(NAME(m_lightpen_high)); + + m_timer_lightpen_hit = timer_alloc(FUNC(mtu130_state::lightpen_hit), this); m_fdc->set_rate(500000); m_io_view.select(1); @@ -554,6 +584,110 @@ void mtu130_state::keyboard_col_clear_w(u8) m_keyboard_col = 0; } +u8 mtu130_state::lightpen_status_r() +{ + return m_lightpen_status; +} + +u8 mtu130_state::lightpen_low_r() +{ + return m_lightpen_low; +} + +u8 mtu130_state::lightpen_high_r() +{ + return m_lightpen_high; +} + +void mtu130_state::lightpen_clear_w(u8) +{ + m_lightpen_status &= ~8; +} + +void mtu130_state::lightpen_trigger(int state) +{ + if(state && m_lightpen_w->read()) { + m_lightpen_hit_x = m_lightpen_x->read(); + m_lightpen_hit_y = m_lightpen_y->read(); + m_timer_lightpen_hit->adjust(m_screen->time_until_pos(m_lightpen_hit_y, m_lightpen_hit_x + 120)); + } +} + +TIMER_CALLBACK_MEMBER(mtu130_state::lightpen_hit) +{ + if(m_lightpen_status & 8) + return; + + // aaaa aaaa .ppp ...s (a = address, p = pixel, s = skew) + // The os-provided coordinates decoding routine cannot generate x >= 474 + static const uint16_t x_to_address[480] = { + 0x0261, 0x0271, 0x0300, 0x0310, 0x0320, 0x0330, 0x0340, 0x0350, 0x0360, 0x0370, + 0x0301, 0x0311, 0x0421, 0x0431, 0x0440, 0x0450, 0x0460, 0x0470, 0x0400, 0x0410, + 0x0420, 0x0430, 0x0540, 0x0550, 0x0560, 0x0570, 0x0501, 0x0511, 0x0521, 0x0531, + 0x0541, 0x0551, 0x0660, 0x0670, 0x0700, 0x0710, 0x0720, 0x0730, 0x0740, 0x0750, + 0x0760, 0x0770, 0x0801, 0x0811, 0x0821, 0x0831, 0x0840, 0x0850, 0x0860, 0x0870, + 0x0800, 0x0810, 0x0820, 0x0830, 0x0940, 0x0950, 0x0960, 0x0970, 0x0901, 0x0911, + 0x0921, 0x0931, 0x0a41, 0x0a51, 0x0a61, 0x0a71, 0x0a00, 0x0a10, 0x0a20, 0x0a30, + 0x0a40, 0x0a50, 0x0a60, 0x0a70, 0x0c00, 0x0c10, 0x0c20, 0x0c30, 0x0c40, 0x0c50, + 0x0c61, 0x0c71, 0x0d00, 0x0d10, 0x0d20, 0x0d30, 0x0d40, 0x0d50, 0x0d60, 0x0d70, + 0x0d01, 0x0d11, 0x0e21, 0x0e31, 0x0e40, 0x0e50, 0x0e60, 0x0e70, 0x0e00, 0x0e10, + 0x0e20, 0x0e30, 0x0f40, 0x0f50, 0x0f60, 0x0f70, 0x0f01, 0x0f11, 0x0f21, 0x0f31, + 0x0f41, 0x0f51, 0x1060, 0x1070, 0x1100, 0x1110, 0x1120, 0x1130, 0x1140, 0x1150, + 0x1160, 0x1170, 0x1201, 0x1211, 0x1221, 0x1231, 0x1240, 0x1250, 0x1260, 0x1270, + 0x1200, 0x1210, 0x1220, 0x1230, 0x1340, 0x1350, 0x1360, 0x1370, 0x1301, 0x1311, + 0x1321, 0x1331, 0x1441, 0x1451, 0x1461, 0x1471, 0x1400, 0x1410, 0x1420, 0x1430, + 0x1440, 0x1450, 0x1460, 0x1470, 0x1600, 0x1610, 0x1620, 0x1630, 0x1640, 0x1650, + 0x1661, 0x1671, 0x1700, 0x1710, 0x1720, 0x1730, 0x1740, 0x1750, 0x1760, 0x1770, + 0x1701, 0x1711, 0x1821, 0x1831, 0x1840, 0x1850, 0x1860, 0x1870, 0x1800, 0x1810, + 0x1820, 0x1830, 0x1940, 0x1950, 0x1960, 0x1970, 0x1901, 0x1911, 0x1921, 0x1931, + 0x1941, 0x1951, 0x1a60, 0x1a70, 0x1b00, 0x1b10, 0x1b20, 0x1b30, 0x1b40, 0x1b50, + 0x1b60, 0x1b70, 0x1c01, 0x1c11, 0x1c21, 0x1c31, 0x1c40, 0x1c50, 0x1c60, 0x1c70, + 0x1c00, 0x1c10, 0x1c20, 0x1c30, 0x1d40, 0x1d50, 0x1d60, 0x1d70, 0x1d01, 0x1d11, + 0x1d21, 0x1d31, 0x1e41, 0x1e51, 0x1e61, 0x1e71, 0x1e00, 0x1e10, 0x1e20, 0x1e30, + 0x1e40, 0x1e50, 0x1e60, 0x1e70, 0x2000, 0x2010, 0x2020, 0x2030, 0x2040, 0x2050, + 0x2061, 0x2071, 0x2100, 0x2110, 0x2120, 0x2130, 0x2140, 0x2150, 0x2160, 0x2170, + 0x2101, 0x2111, 0x2221, 0x2231, 0x2240, 0x2250, 0x2260, 0x2270, 0x2200, 0x2210, + 0x2220, 0x2230, 0x2340, 0x2350, 0x2360, 0x2370, 0x2301, 0x2311, 0x2321, 0x2331, + 0x2341, 0x2351, 0x2460, 0x2470, 0x2500, 0x2510, 0x2520, 0x2530, 0x2540, 0x2550, + 0x2560, 0x2570, 0x2601, 0x2611, 0x2621, 0x2631, 0x2640, 0x2650, 0x2660, 0x2670, + 0x2600, 0x2610, 0x2620, 0x2630, 0x2740, 0x2750, 0x2760, 0x2770, 0x2701, 0x2711, + 0x2721, 0x2731, 0x2841, 0x2851, 0x2861, 0x2871, 0x2800, 0x2810, 0x2820, 0x2830, + 0x2840, 0x2850, 0x2860, 0x2870, 0x2a00, 0x2a10, 0x2a20, 0x2a30, 0x2a40, 0x2a50, + 0x2a61, 0x2a71, 0x2b00, 0x2b10, 0x2b20, 0x2b30, 0x2b40, 0x2b50, 0x2b60, 0x2b70, + 0x2b01, 0x2b11, 0x2c21, 0x2c31, 0x2c40, 0x2c50, 0x2c60, 0x2c70, 0x2c00, 0x2c10, + 0x2c20, 0x2c30, 0x2d40, 0x2d50, 0x2d60, 0x2d70, 0x2d01, 0x2d11, 0x2d21, 0x2d31, + 0x2d41, 0x2d51, 0x2e60, 0x2e70, 0x2f00, 0x2f10, 0x2f20, 0x2f30, 0x2f40, 0x2f50, + 0x2f60, 0x2f70, 0x3001, 0x3011, 0x3021, 0x3031, 0x3040, 0x3050, 0x3060, 0x3070, + 0x3000, 0x3010, 0x3020, 0x3030, 0x3140, 0x3150, 0x3160, 0x3170, 0x3101, 0x3111, + 0x3121, 0x3131, 0x3241, 0x3251, 0x3261, 0x3271, 0x3200, 0x3210, 0x3220, 0x3230, + 0x3240, 0x3250, 0x3260, 0x3270, 0x3400, 0x3410, 0x3420, 0x3430, 0x3440, 0x3450, + 0x3461, 0x3471, 0x3500, 0x3510, 0x3520, 0x3530, 0x3540, 0x3550, 0x3560, 0x3570, + 0x3501, 0x3511, 0x3621, 0x3631, 0x3640, 0x3650, 0x3660, 0x3670, 0x3600, 0x3610, + 0x3620, 0x3630, 0x3740, 0x3750, 0x3760, 0x3770, 0x3701, 0x3711, 0x3721, 0x3731, + 0x3741, 0x3751, 0x3860, 0x3870, 0x3900, 0x3910, 0x3920, 0x3930, 0x3940, 0x3950, + 0x3960, 0x3970, 0x3a01, 0x3a11, 0x3a21, 0x3a31, 0x3a40, 0x3a50, 0x3a60, 0x3a70, + 0x3a00, 0x3a10, 0x3a20, 0x3a30, 0x3b40, 0x3b50, 0x3b60, 0x3b70, 0x3b01, 0x3b11, + 0x3b21, 0x3b31, 0x3c41, 0x3c51, 0x3c61, 0x3c71, 0x3c00, 0x3c10, 0x3c20, 0x3c30, + 0x3c40, 0x3c50, 0x3c60, 0x3c70, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + }; + + uint16_t base = x_to_address[m_lightpen_hit_x]; + if(!base) + return; + + uint16_t pixel = (base >> 4) & 7; + uint16_t skew = base & 1; + uint16_t address = (base >> 8) + 60*m_lightpen_hit_y; + + m_lightpen_status = pixel | 8; + m_lightpen_low = address & 0xff; + m_lightpen_high = ((address >> 8) & 0x3f) | (skew ? 0x80 : 0x00); +} + +void mtu130_state::tape_w(u8) +{ + logerror("tape_w\n"); +} void mtu130_state::map(address_map &map) { @@ -563,10 +697,10 @@ void mtu130_state::map(address_map &map) map(0x0be00, 0x0bfff).view(m_io_view); // I/O dynamically overrides part of the main ram m_io_view[1](0x0be00, 0x0bfff).unmaprw(); // Fully mask out the ram when active - m_io_view[1](0x0bfc3, 0x0bfc3).r(FUNC(mtu130_state::id_r)); - m_io_view[1](0x0bfc3, 0x0bfc3).w(FUNC(mtu130_state::id_reset_w)); - m_io_view[1](0x0bfc5, 0x0bfc5).w(FUNC(mtu130_state::keyboard_col_clear_w)); - m_io_view[1](0x0bfc7, 0x0bfc7).w(FUNC(mtu130_state::id_reset_w)); + m_io_view[1](0x0bfc0, 0x0bfc0).rw(FUNC(mtu130_state::lightpen_status_r), FUNC(mtu130_state::lightpen_clear_w)).mirror(4); + m_io_view[1](0x0bfc1, 0x0bfc1).rw(FUNC(mtu130_state::lightpen_low_r), FUNC(mtu130_state::keyboard_col_clear_w)).mirror(4); + m_io_view[1](0x0bfc2, 0x0bfc2).rw(FUNC(mtu130_state::lightpen_high_r), FUNC(mtu130_state::tape_w)).mirror(4); + m_io_view[1](0x0bfc3, 0x0bfc3).rw(FUNC(mtu130_state::id_r), FUNC(mtu130_state::id_reset_w)).mirror(4); m_io_view[1](0x0bfc8, 0x0bfcb).rw(m_acia, FUNC(mos6551_device::read), FUNC(mos6551_device::write)); m_io_view[1](0x0bfd0, 0x0bfdf).m(m_user_6522, FUNC(via6522_device::map)); m_io_view[1](0x0bfe0, 0x0bfef).m(m_sys1_6522, FUNC(via6522_device::map)); @@ -626,6 +760,7 @@ void mtu130_state::mtu130(machine_config &config) m_screen->set_screen_update(FUNC(mtu130_state::screen_update)); m_screen->set_palette(m_palette); m_screen->screen_vblank().set(m_sys2_6522, FUNC(via6522_device::write_ca2)); + m_screen->screen_vblank().append(FUNC(mtu130_state::lightpen_trigger)); PALETTE(config, m_palette).set_entries(4); @@ -686,6 +821,16 @@ static INPUT_PORTS_START(mtu130) PORT_CONFSETTING(0x00, "FDC rom") PORT_CONFSETTING(0x01, "ROM1 rom (aka rom F)") + PORT_START("lightpen_w") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) + PORT_BIT(0xfe, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("lightpen_x") + PORT_BIT(0x1ff, 0x000, IPT_LIGHTGUN_X) PORT_MINMAX(0, 479) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(45) PORT_KEYDELTA(15) + + PORT_START("lightpen_y") + PORT_BIT(0x0ff, 0x000, IPT_LIGHTGUN_Y) PORT_MINMAX(0, 255) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(45) PORT_KEYDELTA(15) + PORT_START("K0") PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_2) PORT_NAME("RIGHT SHIFT") @@ -832,7 +977,7 @@ ROM_START(mtu130) // address 1 unused f // address 2-6 vendor 00102 // address 7-b group 00000 - // address c-f,0 user 00175 (used by BASIC 1.5 for system-locking) + // address c-f,0 user 00175 (used by BASIC 1.0 and 1.5 for system-locking) ROM_LOAD("6301.u24", 0, 0x100, CRC(7ebc5451) SHA1(402bd7bf343d995bc9c857fe4f3a23e0a8e7bd1c)) ROM_END -- cgit v1.2.3