summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/misc/mtu130.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/misc/mtu130.cpp')
-rw-r--r--src/mame/misc/mtu130.cpp182
1 files changed, 164 insertions, 18 deletions
diff --git a/src/mame/misc/mtu130.cpp b/src/mame/misc/mtu130.cpp
index 59594ad7efa..913f560c178 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"
@@ -58,7 +54,7 @@ public:
protected:
virtual void device_start() override;
- virtual image_init_result call_load() override;
+ virtual std::pair<std::error_condition, std::string> call_load() override;
virtual void call_unload() override;
private:
@@ -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;
@@ -187,7 +196,16 @@ private:
void fdc_ctrl_w(u8 data);
void fdc_irq_w(int state);
void dma_adr_w(u8 data);
- DECLARE_WRITE_LINE_MEMBER(dma_drq_w);
+ void dma_drq_w(int state);
+
+ 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);
@@ -219,11 +237,11 @@ void mtu130_rom_device::device_start()
memset(m_romdata + m_load_offset, 0xff, 4096);
}
-image_init_result mtu130_rom_device::call_load()
+std::pair<std::error_condition, std::string> mtu130_rom_device::call_load()
{
u32 len = !loaded_through_softlist() ? length() : get_software_region_length("rom");
if(!len || len > 4096 || (4096 % len))
- return image_init_result::FAIL;
+ return std::make_pair(image_error::INVALIDLENGTH, std::string());
if (!loaded_through_softlist())
fread(m_romdata + m_load_offset, len);
@@ -238,7 +256,7 @@ image_init_result mtu130_rom_device::call_load()
}
}
- return image_init_result::PASS;
+ return std::make_pair(std::error_condition(), std::string());
}
void mtu130_rom_device::call_unload()
@@ -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);
@@ -443,7 +473,7 @@ void mtu130_state::dma_adr_w(u8 data)
m_dma_adr = data << 6;
}
-WRITE_LINE_MEMBER(mtu130_state::dma_drq_w)
+void mtu130_state::dma_drq_w(int state)
{
while(m_fdc->get_drq()) {
if(m_dma_direction) {
@@ -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,9 +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](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));
@@ -625,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);
@@ -685,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")
@@ -828,10 +974,10 @@ ROM_START(mtu130)
ROM_LOAD("6301.u55", 0, 0x100, CRC(1541eb91) SHA1(78ab124865dc6ffd646abd2fcab5b881edd619c1))
ROM_REGION(0x100, "id", 0) // 4-bit prom, only first 16 nibbles reachable, rest all f
- // 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 1 unused f
+ // address 2-6 vendor 00102
+ // address 7-b group 00000
+ // 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