diff --git a/src/mess/drivers/ql.c b/src/mess/drivers/ql.c index ef9163c16e9..df6f2251e57 100644 --- a/src/mess/drivers/ql.c +++ b/src/mess/drivers/ql.c @@ -95,6 +95,18 @@ #define LOG_DISK_WRITE 0 #define LOG_DISK_READ 0 +void ql_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (id) + { + case TIMER_MOUSE_TICK: + mouse_tick(); + break; + default: + assert_always(FALSE, "Unknown id in ql_state::device_timer"); + } +} + //************************************************************************** // INTELLIGENT PERIPHERAL CONTROLLER //************************************************************************** @@ -276,6 +288,10 @@ READ8_MEMBER( ql_state::disk_io_r ) case 0x0001 : result=m_fdc->read(space, offset); break; case 0x0002 : result=m_fdc->read(space, offset); break; case 0x0003 : result=m_fdc->read(space, offset); break; + case 0x000C : if(IS_SANDY_DISK(m_disk_type)) + result = (m_mouse_int ^ MOUSE_DIRX) | m_mouseb->read() | 0x01; break; + case 0x0010 : if(IS_SANDY_DISK(m_disk_type)) + m_mouse_int &= ~MOUSE_INT_MASK; break; default : logerror("%s DiskIO undefined read : from %08X\n",machine().describe_context(),m_disk_io_base+offset); break; } @@ -293,10 +309,12 @@ WRITE8_MEMBER( ql_state::disk_io_w ) case 0x0001 : m_fdc->write(space, offset, data); break; case 0x0002 : m_fdc->write(space, offset, data); break; case 0x0003 : m_fdc->write(space, offset, data); break; - case 0x0004 : if(m_disk_type==DISK_TYPE_SANDY) + case 0x0004 : if(IS_SANDY_DISK(m_disk_type)) sandy_set_control(data);break; - case 0x0008 : if(m_disk_type==DISK_TYPE_SANDY) - m_printer_char=data; + case 0x0008 : if(IS_SANDY_DISK(m_disk_type)) + sandy_print_char(data); break; + case 0x0010 : if(IS_SANDY_DISK(m_disk_type)) + m_mouse_int &= ~MOUSE_INT_MASK; break; case 0x2000 : if(m_disk_type==DISK_TYPE_TRUMP) trump_card_set_control(data);break; default : logerror("%s DiskIO undefined write : %02X to %08X\n",machine().describe_context(),data,m_disk_io_base+offset); break; @@ -344,8 +362,6 @@ void ql_state::sandy_set_control(UINT8 data) { //logerror("sandy_set_control:%02X\n",data); - m_disk_io_byte=data; - if(data & SANDY_DRIVE0_MASK) m_fdc->set_drive(0); @@ -366,11 +382,30 @@ void ql_state::sandy_set_control(UINT8 data) if(data & SANDY_PRINTER_INTMASK) m_zx8302->extint_w(ASSERT_LINE); } + + m_disk_io_byte=data; +} + +void ql_state::sandy_print_char(UINT8 data) +{ + // latch the data until it's strobed out + m_printer_char=data; + +// m_centronics->write(data); +} + +WRITE_LINE_MEMBER( ql_state::sandy_printer_busy ) +{ + if ((state == ASSERT_LINE) && (m_disk_io_byte & SANDY_PRINTER_INTMASK)) + { + logerror("sandy_print_char : triggering extint\n"); + m_zx8302->extint_w(ASSERT_LINE); + } } READ_LINE_MEMBER(ql_state::disk_io_dden_r) { - if(m_disk_type==DISK_TYPE_SANDY) + if(IS_SANDY_DISK(m_disk_type)) return ((m_disk_io_byte & SANDY_DDEN_MASK) >> SANDY_DDEN_SHIFT); else return 0; @@ -386,6 +421,92 @@ WRITE_LINE_MEMBER(ql_state::disk_io_drq_w) //logerror("DiskIO:drq = %d\n",state); } +void ql_state::mouse_tick() +{ + UINT8 x = m_mousex->read(); + UINT8 y = m_mousey->read(); + UINT8 do_int = 0; + + //m_mouse_int = 0; + + // Set X interupt flag and direction if x has changed + if (x > m_ql_mouse_x) + { + m_mouse_int |= MOUSE_INTX; + m_mouse_int |= MOUSE_DIRX; + } + else if (x < m_ql_mouse_x) + { + m_mouse_int |= MOUSE_INTX; + m_mouse_int &= ~MOUSE_DIRX; + } + + // Set Y interupt flag and direction if y has changed + if (y > m_ql_mouse_y) + { + m_mouse_int |= MOUSE_INTY; + m_mouse_int &= ~MOUSE_DIRY; + } + else if (y < m_ql_mouse_y) + { + m_mouse_int |= MOUSE_INTY; + m_mouse_int |= MOUSE_DIRY; + } + + // Update saved location + m_ql_mouse_x = x; + m_ql_mouse_y = y; + + // if it is a QIMI, then always do int if triggered. + // if this is a Sandy mouse, only trigger an int if it is enabled in the mask register + if (m_config->read() & QIMI_MOUSE) + do_int = 1; + else + do_int = IS_SANDY_DISK(m_disk_type) && (m_disk_io_byte & SANDY_MOUSE_INTMASK); + + //logerror("m_mouse_int=%02X, MOUSE_INT_MASK=%02X, m_disk_io_byte=%02X, (m_disk_io_byte & SANDY_MOUSE_INTMASK)=%02x\n",m_mouse_int,MOUSE_INT_MASK,m_disk_io_byte,(m_disk_io_byte & SANDY_MOUSE_INTMASK)); + + // if mouse moved trigger external int + if((m_mouse_int & MOUSE_INT_MASK) && do_int) + { + m_zx8302->extint_w(ASSERT_LINE); + } +} + +READ8_MEMBER( ql_state::qimi_io_r ) +{ + UINT8 result = 0; + UINT8 buttons; + + switch (offset) + { + // 0x1bf9c, button status + case 0x00 : + buttons = m_mouseb->read(); + result = ((buttons & MOUSE_RIGHT) << 2) | ((buttons & MOUSE_LEFT) << 2); + break; + + // 0x1bfbc, direction status + case 0x20 : + result = ((m_mouse_int & MOUSE_INTX) >> 5) | ((m_mouse_int & MOUSE_INTY) >> 1) | + ((m_mouse_int & MOUSE_DIRX) >> 1) | ((m_mouse_int & MOUSE_DIRY) >> 4); + break; + case 0x22 : + m_mouse_int &= ~MOUSE_INT_MASK; + break; + } + + return result; +} + +WRITE8_MEMBER( ql_state::qimi_io_w ) +{ + // write to 0x1bfbe resets int status + if (offset == 0x22) + { + m_mouse_int = 0; + } +} //************************************************************************** // ADDRESS MAPS @@ -540,10 +661,27 @@ static INPUT_PORTS_START( ql ) PORT_START(QL_CONFIG_PORT) - PORT_DIPNAME( DISK_TYPE_MASK, DISK_TYPE_NONE, "Disk interface select") - PORT_DIPSETTING(DISK_TYPE_NONE, DEF_STR( None )) - PORT_DIPSETTING(DISK_TYPE_TRUMP, "Miracle Trump card") - PORT_DIPSETTING(DISK_TYPE_SANDY, "Sandy Superdisk") + PORT_CONFNAME( QIMI_PORT_MASK, QIMI_NONE, "QIMI enabled") + PORT_CONFSETTING( QIMI_NONE, "No" ) + PORT_CONFSETTING( QIMI_MOUSE, "Yes" ) + + PORT_CONFNAME( DISK_TYPE_MASK, DISK_TYPE_NONE, "Disk interface select" ) + PORT_CONFSETTING(DISK_TYPE_NONE, DEF_STR( None )) + PORT_CONFSETTING(DISK_TYPE_TRUMP, "Miracle Trump card") + PORT_CONFSETTING(DISK_TYPE_SANDY_SD, "Sandy Superdisk") + PORT_CONFSETTING(DISK_TYPE_SANDY_SQB,"Sandy SuperQBoard") + + + PORT_START(MOUSEX_TAG) + PORT_BIT( 0xff, 0x00, IPT_MOUSE_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(5) PORT_MINMAX(0, 255) PORT_PLAYER(1) + + PORT_START(MOUSEY_TAG) + PORT_BIT( 0xff, 0x00, IPT_MOUSE_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(5) PORT_MINMAX(0, 255) PORT_PLAYER(1) + + PORT_START(MOUSEB_TAG) /* Mouse buttons */ + PORT_BIT( MOUSE_RIGHT, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Mouse Button 1") PORT_CODE(MOUSECODE_BUTTON1) + PORT_BIT( MOUSE_LEFT, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("Mouse Button 2") PORT_CODE(MOUSECODE_BUTTON2) + PORT_BIT( MOUSE_MIDDLE, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_NAME("Mouse Button 3") PORT_CODE(MOUSECODE_BUTTON3) INPUT_PORTS_END @@ -826,7 +964,6 @@ wd17xx_interface ql_wd17xx_interface = {FLOPPY_0, FLOPPY_1, FLOPPY_2, FLOPPY_3} }; - //------------------------------------------------- // MICRODRIVE_CONFIG( mdv1_config ) //------------------------------------------------- @@ -875,19 +1012,28 @@ void ql_state::machine_start() save_item(NAME(m_baudx4)); save_item(NAME(m_printer_char)); save_item(NAME(m_disk_io_byte)); + + // QIMI QL Internal Mouse Interface + if (m_mousex) + { + m_mouse_timer = timer_alloc(TIMER_MOUSE_TICK); + m_mouse_timer->adjust(attotime::zero, 0, attotime::from_hz(500)); + } } void ql_state::machine_reset() { address_space &program = m_maincpu->space(AS_PROGRAM); - m_disk_type=ioport(QL_CONFIG_PORT)->read() & DISK_TYPE_MASK; + m_disk_type=m_config->read() & DISK_TYPE_MASK; logerror("disktype=%d\n",m_disk_type); m_printer_char=0; m_disk_io_byte=0; - - logerror("Configuring RAM\n"); + m_mouse_int = 0; + + logerror("Configuring RAM %d\n",m_ram->size() / 1024); + // configure RAM switch (m_ram->size()) { @@ -914,22 +1060,40 @@ void ql_state::machine_reset() switch (m_disk_type) { - case DISK_TYPE_SANDY : - logerror("Configuring SandySuperDisk\n"); - program.install_rom(0x0c0000, 0x0c3fff, &memregion(M68008_TAG)->base()[SANDY_ROM_BASE]); + case DISK_TYPE_SANDY_SD : + logerror("Configuring Sandy SuperDisk\n"); + program.install_rom(0x0c0000, 0x0c3fff, &memregion(M68008_TAG)->base()[SANDY_ROM_BASE_SD]); program.install_read_handler(SANDY_IO_BASE, SANDY_IO_END, 0, 0, read8_delegate(FUNC(ql_state::disk_io_r), this)); program.install_write_handler(SANDY_IO_BASE, SANDY_IO_END, 0, 0, write8_delegate(FUNC(ql_state::disk_io_w), this)); m_disk_io_base=SANDY_IO_BASE; break; + + case DISK_TYPE_SANDY_SQB : + logerror("Configuring Sandy SuperQBoard\n"); + program.install_rom(0x0c0000, 0x0c7fff, &memregion(M68008_TAG)->base()[SANDY_ROM_BASE_SQB]); + program.install_read_handler(SANDY_IO_BASE, SANDY_IO_END, 0, 0, read8_delegate(FUNC(ql_state::disk_io_r), this)); + program.install_write_handler(SANDY_IO_BASE, SANDY_IO_END, 0, 0, write8_delegate(FUNC(ql_state::disk_io_w), this)); + m_disk_io_base=SANDY_IO_BASE; + break; + case DISK_TYPE_TRUMP : logerror("Configuring TrumpCard\n"); program.install_read_handler(CART_ROM_BASE, CART_ROM_END, 0, 0, read8_delegate(FUNC(ql_state::cart_rom_r), this)); - program.install_read_handler(TRUMP_ROM_BASE, TRUMP_ROM_END, 0, 0, read8_delegate(FUNC(ql_state::trump_card_rom_r), this)); + program.install_read_handler(TRUMP_ROM_MBASE, TRUMP_ROM_END, 0, 0, read8_delegate(FUNC(ql_state::trump_card_rom_r), this)); program.install_read_handler(TRUMP_IO_BASE, TRUMP_IO_END, 0, 0, read8_delegate(FUNC(ql_state::disk_io_r), this)); program.install_write_handler(TRUMP_IO_BASE, TRUMP_IO_END, 0, 0, write8_delegate(FUNC(ql_state::disk_io_w), this)); m_disk_io_base=TRUMP_IO_BASE; break; } + + + // QIMI QL Internal Mouse Interface + if (m_config->read() & QIMI_MOUSE) + { + logerror("QIMI enabled\n"); + program.install_read_handler(QIMI_IO_BASE, QIMI_IO_END, 0, 0, read8_delegate(FUNC(ql_state::qimi_io_r), this)); + program.install_write_handler(QIMI_IO_BASE, QIMI_IO_END, 0, 0, write8_delegate(FUNC(ql_state::qimi_io_w), this)); + } } //************************************************************************** @@ -1062,7 +1226,7 @@ MACHINE_CONFIG_END //------------------------------------------------- ROM_START( ql ) - ROM_REGION( 0x20000, M68008_TAG, 0 ) + ROM_REGION( 0x28000, M68008_TAG, 0 ) ROM_DEFAULT_BIOS("js") ROM_SYSTEM_BIOS( 0, "fb", "v1.00 (FB)" ) ROMX_LOAD( "fb.ic33", 0x0000, 0x8000, NO_DUMP, ROM_BIOS(1) ) @@ -1090,7 +1254,8 @@ ROM_START( ql ) ROM_CART_LOAD("cart", 0xc000, 0x8000, ROM_MIRROR | ROM_OPTIONAL) ROM_LOAD( "trumpcard-125.rom", TRUMP_ROM_BASE, 0x08000, CRC(938eaa46) SHA1(9b3458cf3a279ed86ba395dc45c8f26939d6c44d)) - ROM_LOAD( "sandysuperdisk.rom", SANDY_ROM_BASE, 0x04000, CRC(b52077da) SHA1(bf531758145ffd083e01c1cf9c45d0e9264a3b53)) + ROM_LOAD( "sandysuperdisk.rom", SANDY_ROM_BASE_SD, 0x04000, CRC(b52077da) SHA1(bf531758145ffd083e01c1cf9c45d0e9264a3b53)) + ROM_LOAD( "sandy_disk_controller_v1.18y_1984.rom", SANDY_ROM_BASE_SQB, 0x08000, CRC(d02425be) SHA1(e730576e3e0c6a1acad042c09e15fc62a32d8fbd)) ROM_REGION( 0x800, I8749_TAG, 0 ) ROM_LOAD( "ipc8049.ic24", 0x000, 0x800, CRC(6a0d1f20) SHA1(fcb1c97ee7c66e5b6d8fbb57c06fd2f6509f2e1b) ) diff --git a/src/mess/includes/ql.h b/src/mess/includes/ql.h index 4cf92bd8214..e3248037467 100644 --- a/src/mess/includes/ql.h +++ b/src/mess/includes/ql.h @@ -8,6 +8,8 @@ #include "bus/rs232/rs232.h" #include "machine/ram.h" #include "machine/wd17xx.h" +#include "bus/centronics/ctronics.h" + #define SCREEN_TAG "screen" @@ -30,32 +32,40 @@ #define X3 XTAL_4_436MHz #define X4 XTAL_11MHz -#define QL_CONFIG_PORT "QLCONFIG" -#define DISK_TYPE_MASK 0x03 -#define DISK_TYPE_NONE 0x00 -#define DISK_TYPE_TRUMP 0x01 -#define DISK_TYPE_SANDY 0x02 +#define QL_CONFIG_PORT "config" +#define QIMI_PORT_MASK 0x01 +#define QIMI_NONE 0x00 +#define QIMI_MOUSE 0x01 +#define DISK_TYPE_MASK 0x06 +#define DISK_TYPE_NONE 0x00 +#define DISK_TYPE_TRUMP 0x02 +#define DISK_TYPE_SANDY_SD 0x04 +#define DISK_TYPE_SANDY_SQB 0x06 +#define IS_SANDY_DISK(__dtype__) ((__dtype__ == DISK_TYPE_SANDY_SD) || (__dtype__ == DISK_TYPE_SANDY_SQB)) -#define TRUMP_DRIVE1_MASK 0x01 -#define TRUMP_DRIVE0_MASK 0x02 -#define TRUMP_MOTOR_MASK 0x04 -#define TRUMP_SIDE_SHIFT 3 -#define TRUMP_SIDE_MASK (1 << TRUMP_SIDE_SHIFT) +#define TRUMP_DRIVE1_MASK 0x01 +#define TRUMP_DRIVE0_MASK 0x02 +#define TRUMP_MOTOR_MASK 0x04 +#define TRUMP_SIDE_SHIFT 3 +#define TRUMP_SIDE_MASK (1 << TRUMP_SIDE_SHIFT) -#define CART_ROM_BASE 0x0c000 -#define CART_ROM_END 0x0ffff -#define TRUMP_ROM_BASE 0x14000 -#define TRUMP_ROM_LEN 0x08000 -#define TRUMP_ROM_END (TRUMP_ROM_BASE+(TRUMP_ROM_LEN-1)) +#define CART_ROM_BASE 0x0c000 +#define CART_ROM_END 0x0ffff -#define TRUMP_IO_BASE 0x1c000 -#define TRUMP_IO_LEN 0x04000 -#define TRUMP_IO_END (TRUMP_IO_BASE+(TRUMP_IO_LEN-1)) +#define TRUMP_ROM_MBASE 0x10000 +#define TRUMP_ROM_BASE 0x14000 +#define TRUMP_ROM_LEN 0x08000 +#define TRUMP_ROM_END (TRUMP_ROM_MBASE+(TRUMP_ROM_LEN-1)) -#define SANDY_ROM_BASE 0x1c000 -#define SANDY_IO_BASE 0xc3fc0 -#define SANDY_IO_LEN 0x00040 -#define SANDY_IO_END (SANDY_IO_BASE+(SANDY_IO_LEN-1)) +#define TRUMP_IO_BASE 0x1c000 +#define TRUMP_IO_LEN 0x04000 +#define TRUMP_IO_END (TRUMP_IO_BASE+(TRUMP_IO_LEN-1)) + +#define SANDY_ROM_BASE_SD 0x1c000 +#define SANDY_ROM_BASE_SQB 0x20000 +#define SANDY_IO_BASE 0xc3fc0 +#define SANDY_IO_LEN 0x00040 +#define SANDY_IO_END (SANDY_IO_BASE+(SANDY_IO_LEN-1)) #define SANDY_DRIVE0_MASK 0x02 #define SANDY_DRIVE1_MASK 0x04 @@ -66,11 +76,43 @@ #define SANDY_DDEN_MASK (1 << SANDY_DDEN_SHIFT) #define SANDY_PRINTER_STROBE 0x20 #define SANDY_PRINTER_INTMASK 0x40 +#define SANDY_MOUSE_INTMASK 0x80 + +#define MOUSEX_TAG "MOUSEX" +#define MOUSEY_TAG "MOUSEY" +#define MOUSEB_TAG "MOUSEB" + +// Mouse bits in Sandy port order +#define MOUSE_MIDDLE 0x02 +#define MOUSE_RIGHT 0x04 +#define MOUSE_LEFT 0x08 +#define MOUSE_DIRY 0x10 +#define MOUSE_DIRX 0x20 +#define MOUSE_INTY 0x40 +#define MOUSE_INTX 0x80 +#define MOUSE_INT_MASK (MOUSE_INTX | MOUSE_INTY) + +#define QIMI_IO_BASE 0x1bf9c +#define QIMI_IO_LEN 0x22 +#define QIMI_IO_END (QIMI_IO_BASE + QIMI_IO_LEN ) + +#define QIMI_INTX 0x04 +#define QIMI_INTY 0x20 +#define QIMI_DIRX 0x10 +#define QIMI_DIRY 0x01 +#define QIMI_LEFT 0x20 +#define QIMI_RIGHT 0x10 +#define QIMI_INT_MASK (QIMI_INTX | QIMI_INTY) class ql_state : public driver_device { public: + enum + { + TIMER_MOUSE_TICK, + }; + ql_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, M68008_TAG), @@ -94,7 +136,11 @@ public: m_y6(*this, "Y6"), m_y7(*this, "Y7"), m_joy0(*this, "JOY0"), - m_joy1(*this, "JOY1") + m_joy1(*this, "JOY1"), + m_config(*this, QL_CONFIG_PORT), + m_mousex(*this, MOUSEX_TAG), + m_mousey(*this, MOUSEY_TAG), + m_mouseb(*this, MOUSEB_TAG) { } required_device m_maincpu; @@ -119,6 +165,10 @@ public: required_ioport m_y7; required_ioport m_joy0; required_ioport m_joy1; + optional_ioport m_config; + optional_ioport m_mousex; + optional_ioport m_mousey; + optional_ioport m_mouseb; virtual void machine_start(); virtual void machine_reset(); @@ -155,14 +205,34 @@ public: void trump_card_set_control(UINT8 data); void sandy_set_control(UINT8 data); - - int m_disk_type; + void sandy_print_char(UINT8 data); + + UINT8 m_disk_type; int m_disk_io_base; UINT8 m_disk_io_byte; UINT8 m_printer_char; DECLARE_READ_LINE_MEMBER(disk_io_dden_r); DECLARE_WRITE_LINE_MEMBER(disk_io_intrq_w); DECLARE_WRITE_LINE_MEMBER(disk_io_drq_w); + + DECLARE_WRITE_LINE_MEMBER( sandy_printer_busy ); + + // QIMI or Sandy mouse + void mouse_tick(); + + DECLARE_READ8_MEMBER( qimi_io_r ); + DECLARE_WRITE8_MEMBER( qimi_io_w ); + + UINT8 m_mouse_int; + + emu_timer *m_mouse_timer; + + UINT8 m_ql_mouse_x; + UINT8 m_ql_mouse_y; + +protected: + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + }; #endif