/****************************************************************************** drivers/sorc.c Sord m5 system driver Thankyou to Roman Stec and Jan P. Naidr for the documentation and much help. http://falabella.lf2.cuni.cz/~naidr/sord/ PI-5 is the parallel interface using a 8255. FD-5 is the disc operating system and disc interface. FD-5 is connected to M5 via PI-5. Kevin Thacker [MESS driver] ******************************************************************************/ #include "driver.h" #include "video/tms9928a.h" #include "sound/sn76496.h" #include "cpu/z80/z80.h" #include "cpu/z80/z80daisy.h" #include "includes/centroni.h" #include "devices/printer.h" #include "machine/z80ctc.h" #include "machine/z80pio.h" #include "machine/z80sio.h" #include "machine/8255ppi.h" #include "devices/cartslot.h" #include "devices/cassette.h" #include "devices/mflopimg.h" #include "formats/sord_cas.h" #include "formats/basicdsk.h" #define SORD_DEBUG /*********************************************************************************************/ /* FD5 disk interface */ /* - Z80 CPU */ /* - 27128 ROM (16K) */ /* - 2x6116 RAM */ /* - Intel8272/NEC765 */ /* - IRQ of NEC765 is connected to INT of Z80 */ /* PI-5 interface is required. mode 2 of the 8255 is used to communicate with the FD-5 */ #include "machine/nec765.h" #include "devices/cassette.h" #include "image.h" static MACHINE_RESET( sord_m5 ); static unsigned char fd5_databus; ADDRESS_MAP_START( sord_fd5_mem , ADDRESS_SPACE_PROGRAM, 8) AM_RANGE(0x0000, 0x03fff) AM_ROM /* internal rom */ AM_RANGE(0x4000, 0x0ffff) AM_RAM ADDRESS_MAP_END static int obfa,ibfa, intra; static int fd5_port_0x020_data; /* stb and ack automatically set on read/write? */ static WRITE8_HANDLER(fd5_communication_w) { cpu_yield(); fd5_port_0x020_data = data; #ifdef SORD_DEBUG logerror("fd5 0x020: %02x %04x\n",data,activecpu_get_pc()); #endif } static READ8_HANDLER(fd5_communication_r) { int data; cpu_yield(); data = (obfa<<3)|(ibfa<<2)|2; #ifdef SORD_DEBUG logerror("fd5 0x030: %02x %04x\n",data, activecpu_get_pc()); #endif return data; } static READ8_HANDLER(fd5_data_r) { cpu_yield(); #ifdef SORD_DEBUG logerror("fd5 0x010 r: %02x %04x\n",fd5_databus,activecpu_get_pc()); #endif ppi8255_set_portC(0, 0x50); ppi8255_set_portC(0, 0x10); ppi8255_set_portC(0, 0x50); return fd5_databus; } static WRITE8_HANDLER(fd5_data_w) { #ifdef SORD_DEBUG logerror("fd5 0x010 w: %02x %04x\n",data,activecpu_get_pc()); #endif fd5_databus = data; /* set stb on data write */ ppi8255_set_portC(0, 0x50); ppi8255_set_portC(0, 0x40); ppi8255_set_portC(0, 0x50); cpu_yield(); } static WRITE8_HANDLER(fd5_drive_control_w) { int state; if (data==0) state = 0; else state = 1; #ifdef SORD_DEBUG logerror("fd5 drive state w: %02x\n",state); #endif floppy_drive_set_motor_state(image_from_devtype_and_index(IO_FLOPPY, 0), state); floppy_drive_set_motor_state(image_from_devtype_and_index(IO_FLOPPY, 0), state); floppy_drive_set_ready_state(image_from_devtype_and_index(IO_FLOPPY, 1), 1,1); floppy_drive_set_ready_state(image_from_devtype_and_index(IO_FLOPPY, 1), 1,1); } static WRITE8_HANDLER(fd5_tc_w) { nec765_set_tc_state(1); nec765_set_tc_state(0); } /* 0x020 fd5 writes to this port to communicate with m5 */ /* 0x010 data bus to read/write from m5 */ /* 0x030 fd5 reads from this port to communicate with m5 */ /* 0x040 */ /* 0x050 */ ADDRESS_MAP_START( readport_sord_fd5 , ADDRESS_SPACE_IO, 8) AM_RANGE( 0x000, 0x000) AM_READ( nec765_status_r) AM_RANGE( 0x001, 0x001) AM_READ( nec765_data_r) AM_RANGE( 0x010, 0x010) AM_READ( fd5_data_r) AM_RANGE( 0x030, 0x030) AM_READ( fd5_communication_r) ADDRESS_MAP_END ADDRESS_MAP_START( writeport_sord_fd5 , ADDRESS_SPACE_IO, 8) AM_RANGE( 0x001, 0x001) AM_WRITE( nec765_data_w) AM_RANGE( 0x010, 0x010) AM_WRITE( fd5_data_w) AM_RANGE( 0x020, 0x020) AM_WRITE( fd5_communication_w) AM_RANGE( 0x040, 0x040) AM_WRITE( fd5_drive_control_w) AM_RANGE( 0x050, 0x050) AM_WRITE( fd5_tc_w) ADDRESS_MAP_END /* nec765 data request is connected to interrupt of z80 inside fd5 interface */ static void sord_fd5_fdc_interrupt(int state) { if (state) { cpunum_set_input_line(1,0, HOLD_LINE); } else { cpunum_set_input_line(1,0,CLEAR_LINE); } } static struct nec765_interface sord_fd5_nec765_interface= { sord_fd5_fdc_interrupt, NULL }; static void sord_fd5_init(void) { nec765_init(&sord_fd5_nec765_interface,NEC765A); } static MACHINE_RESET( sord_m5_fd5 ) { floppy_drive_set_geometry(image_from_devtype_and_index(IO_FLOPPY, 0), FLOPPY_DRIVE_SS_40); floppy_drive_set_geometry(image_from_devtype_and_index(IO_FLOPPY, 1), FLOPPY_DRIVE_SS_40); sord_fd5_init(); machine_reset_sord_m5(machine); ppi8255_set_portC(0, 0x50); } static mess_image *cassette_device_image(void) { return image_from_devtype_and_index(IO_CASSETTE, 0); } /*********************************************************************************************/ /* PI-5 */ static READ8_HANDLER(sord_ppi_porta_r) { cpu_yield(); return fd5_databus; } static READ8_HANDLER(sord_ppi_portb_r) { cpu_yield(); #ifdef SORD_DEBUG logerror("m5 read from pi5 port b %04x\n",activecpu_get_pc()); #endif return 0x0ff; } static READ8_HANDLER(sord_ppi_portc_r) { cpu_yield(); #ifdef SORD_DEBUG logerror("m5 read from pi5 port c %04x\n",activecpu_get_pc()); #endif /* from fd5 */ /* 00 = 0000 = write */ /* 02 = 0010 = write */ /* 06 = 0110 = read */ /* 04 = 0100 = read */ /* m5 expects */ /*00 = READ */ /*01 = POTENTIAL TO READ BUT ALSO RESET */ /*10 = WRITE */ /*11 = FORCE RESET AND WRITE */ /* FD5 bit 0 -> M5 bit 2 */ /* FD5 bit 2 -> M5 bit 1 */ /* FD5 bit 1 -> M5 bit 0 */ return ( /* FD5 bit 0-> M5 bit 2 */ ((fd5_port_0x020_data & 0x01)<<2) | /* FD5 bit 2-> M5 bit 1 */ ((fd5_port_0x020_data & 0x04)>>1) | /* FD5 bit 1-> M5 bit 0 */ ((fd5_port_0x020_data & 0x02)>>1) ); } static WRITE8_HANDLER(sord_ppi_porta_w) { cpu_yield(); fd5_databus = data; } static WRITE8_HANDLER(sord_ppi_portb_w) { cpu_yield(); /* f0, 40 */ /* 1111 */ /* 0100 */ if (data==0x0f0) { cpunum_set_input_line(1, INPUT_LINE_RESET, ASSERT_LINE); cpunum_set_input_line(1, INPUT_LINE_RESET, CLEAR_LINE); } #ifdef SORD_DEBUG logerror("m5 write to pi5 port b: %02x %04x\n",data,activecpu_get_pc()); #endif } /* A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, */ /* 41, 42, 43, 44, 45, 46, 47, 48, 49, 4a, 4b, 4c, 4d, 4e, 4f, 50, 51, 52*/ /* C,H,N */ static WRITE8_HANDLER(sord_ppi_portc_w) { obfa = (data & 0x80) ? 1 : 0; intra = (data & 0x08) ? 1 : 0; ibfa = (data & 0x20) ? 1 : 0; cpu_yield(); #ifdef SORD_DEBUG logerror("m5 write to pi5 port c: %02x %04x\n",data,activecpu_get_pc()); #endif } static ppi8255_interface sord_ppi8255_interface = { 1, {sord_ppi_porta_r}, {sord_ppi_portb_r}, {sord_ppi_portc_r}, {sord_ppi_porta_w}, {sord_ppi_portb_w}, {sord_ppi_portc_w} }; /*********************************************************************************************/ static void sord_m5_ctc_interrupt(int state) { //logerror("interrupting ctc %02x\r\n ",state); cpunum_set_input_line(0, 0, state); } static z80ctc_interface sord_m5_ctc_intf = { 3800000, 0, sord_m5_ctc_interrupt, 0, 0, 0 }; static READ8_HANDLER ( sord_keyboard_r ) { return readinputport(offset); } ADDRESS_MAP_START( sord_m5_mem , ADDRESS_SPACE_PROGRAM, 8) AM_RANGE(0x0000, 0x01fff) AM_ROM /* internal rom */ AM_RANGE(0x2000, 0x06fff) AM_ROMBANK(1) AM_RANGE(0x7000, 0x0ffff) AM_RAM ADDRESS_MAP_END static READ8_HANDLER(sord_ctc_r) { unsigned char data; data = z80ctc_0_r(offset & 0x03); logerror("sord ctc r: %04x %02x\n",(offset & 0x03), data); return data; } static WRITE8_HANDLER(sord_ctc_w) { logerror("sord ctc w: %04x %02x\n",(offset & 0x03), data); z80ctc_0_w(offset & 0x03, data); } static READ8_HANDLER(sord_sys_r) { unsigned char data; int printer_handshake; data = 0; /* cassette read */ if (cassette_input(cassette_device_image()) >=0) data |=(1<<0); printer_handshake = centronics_read_handshake(0); /* if printer is not online, it is busy */ if ((printer_handshake & CENTRONICS_ONLINE)!=0) { data|=(1<<1); } /* bit 7 must be 0 for saving and loading to work */ logerror("sys read: %02x\n",data); return data; } /* write */ /* bit 0 is strobe to printer or cassette write data */ /* bit 1 is cassette remote */ /* read */ /* bit 0 is cassette read data */ /* bit 1 is printer busy */ static WRITE8_HANDLER(sord_sys_w) { int handshake; handshake = 0; if (data & (1<<0)) { handshake = CENTRONICS_STROBE; } /* cassette remote */ cassette_change_state( cassette_device_image(), (data & 0x02) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); /* cassette data */ cassette_output(cassette_device_image(), (data & (1<<0)) ? -1.0 : 1.0); /* assumption: select is tied low */ centronics_write_handshake(0, CENTRONICS_SELECT | CENTRONICS_NO_RESET, CENTRONICS_SELECT| CENTRONICS_NO_RESET); centronics_write_handshake(0, handshake, CENTRONICS_STROBE); logerror("sys write: %02x\n",data); } static WRITE8_HANDLER(sord_printer_w) { // logerror("centronics w: %02x\n",data); centronics_write_data(0,data); } ADDRESS_MAP_START( sord_m5_io , ADDRESS_SPACE_IO, 8) ADDRESS_MAP_FLAGS( AMEF_ABITS(8) ) AM_RANGE(0x00, 0x0f) AM_READWRITE(sord_ctc_r, sord_ctc_w) AM_RANGE(0x10, 0x10) AM_MIRROR(0x0e) AM_READWRITE(TMS9928A_vram_r, TMS9928A_vram_w) AM_RANGE(0x11, 0x11) AM_MIRROR(0x0e) AM_READWRITE(TMS9928A_register_r, TMS9928A_register_w) AM_RANGE(0x20, 0x2f) AM_WRITE( SN76496_0_w) AM_RANGE(0x30, 0x3f) AM_READ(sord_keyboard_r) AM_RANGE(0x40, 0x40) AM_WRITE( sord_printer_w) AM_RANGE(0x50, 0x50) AM_READWRITE(sord_sys_r, sord_sys_w) ADDRESS_MAP_END ADDRESS_MAP_START( srdm5fd5_io , ADDRESS_SPACE_IO, 8) ADDRESS_MAP_FLAGS( AMEF_ABITS(8) ) AM_RANGE(0x00, 0x0f) AM_READWRITE(sord_ctc_r, sord_ctc_w) AM_RANGE(0x10, 0x10) AM_MIRROR(0x0e) AM_READWRITE(TMS9928A_vram_r, TMS9928A_vram_w) AM_RANGE(0x11, 0x11) AM_MIRROR(0x0e) AM_READWRITE(TMS9928A_register_r, TMS9928A_register_w) AM_RANGE(0x20, 0x2f) AM_WRITE( SN76496_0_w) AM_RANGE(0x30, 0x3f) AM_READ(sord_keyboard_r) AM_RANGE(0x40, 0x40) AM_WRITE( sord_printer_w) AM_RANGE(0x50, 0x50) AM_READWRITE(sord_sys_r, sord_sys_w) AM_RANGE(0x70, 0x73) AM_READWRITE(ppi8255_0_r, ppi8255_0_w) ADDRESS_MAP_END static CENTRONICS_CONFIG sordm5_cent_config[1] = { { PRINTER_CENTRONICS, NULL }, }; static void sordm5_video_interrupt_callback(int state) { if (state) { z80ctc_0_trg3_w(0,1); z80ctc_0_trg3_w(0,0); } } static const TMS9928a_interface tms9928a_interface = { TMS9929A, 0x4000, 0, 0, sordm5_video_interrupt_callback }; static MACHINE_START( sord_m5 ) { TMS9928A_configure(&tms9928a_interface); } static MACHINE_RESET( sord_m5 ) { z80ctc_init(0, &sord_m5_ctc_intf); /* PI-5 interface connected to Sord M5 */ ppi8255_init(&sord_ppi8255_interface); // cassette_timer = timer_pulse(TIME_IN_HZ(11025), 0, cassette_timer_callback); TMS9928A_reset (); z80ctc_reset(0); /* should be done in a special callback to work properly! */ memory_set_bankptr(1, memory_region(REGION_USER1)); centronics_config(0, sordm5_cent_config); /* assumption: select is tied low */ centronics_write_handshake(0, CENTRONICS_SELECT | CENTRONICS_NO_RESET, CENTRONICS_SELECT| CENTRONICS_NO_RESET); } INPUT_PORTS_START(sord_m5) /* line 0 */ PORT_START PORT_BIT (0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_BIT (0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("FUNC") PORT_CODE(KEYCODE_LALT) PORT_BIT (0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("LSHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_BIT (0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RSHIFT") PORT_CODE(KEYCODE_RSHIFT) PORT_BIT (0x10, 0x00, IPT_UNUSED) PORT_BIT (0x20, 0x00, IPT_UNUSED) PORT_BIT (0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_BIT (0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER) /* line 1 */ PORT_START PORT_BIT (0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_BIT (0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_BIT (0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_BIT (0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_BIT (0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_BIT (0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_BIT (0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_BIT (0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) /* line 2 */ PORT_START PORT_BIT (0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_BIT (0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_BIT (0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_BIT (0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_BIT (0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_BIT (0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_BIT (0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_BIT (0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) /* line 3 */ PORT_START PORT_BIT (0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_BIT (0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_BIT (0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_BIT (0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_BIT (0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_BIT (0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_BIT (0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_BIT (0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) /* line 4 */ PORT_START PORT_BIT (0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_BIT (0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_BIT (0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_BIT (0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_BIT (0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_BIT (0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_BIT (0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_BIT (0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) /* line 5 */ PORT_START PORT_BIT (0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_BIT (0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_BIT (0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_BIT (0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("^") PORT_CODE(KEYCODE_EQUALS) PORT_BIT (0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) PORT_BIT (0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) PORT_BIT (0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("_") PORT_CODE(KEYCODE_MINUS_PAD) PORT_BIT (0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("\\") PORT_CODE(KEYCODE_BACKSLASH) /* line 6 */ PORT_START PORT_BIT (0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_BIT (0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_BIT (0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("@") PORT_CODE(KEYCODE_QUOTE) PORT_BIT (0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) PORT_BIT (0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_BIT (0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(";") PORT_CODE(KEYCODE_PLUS_PAD) PORT_BIT (0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(":") PORT_CODE(KEYCODE_COLON) PORT_BIT (0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("]") PORT_CODE(KEYCODE_CLOSEBRACE) /* line 7 */ PORT_START PORT_BIT (0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("JOY 1 RIGHT") PORT_CODE(JOYCODE_X_RIGHT_SWITCH) PORT_BIT (0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("JOY 1 UP") PORT_CODE(JOYCODE_Y_UP_SWITCH) PORT_BIT (0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("JOY 1 LEFT") PORT_CODE(JOYCODE_X_LEFT_SWITCH) PORT_BIT (0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("JOY 1 DOWN") PORT_CODE(JOYCODE_Y_DOWN_SWITCH) PORT_BIT (0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("JOY 2 RIGHT") PORT_CODE(JOYCODE_X_RIGHT_SWITCH) PORT_BIT (0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("JOY 2 UP") PORT_CODE(JOYCODE_Y_UP_SWITCH) PORT_BIT (0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("JOY 2 LEFT") PORT_CODE(JOYCODE_X_LEFT_SWITCH) PORT_BIT (0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("JOY 2 DOWN") PORT_CODE(JOYCODE_Y_DOWN_SWITCH) /* line 8 */ PORT_START PORT_BIT (0x0ff, 0x000, IPT_UNUSED) /* line 9 */ PORT_START PORT_BIT (0x0ff, 0x000, IPT_UNUSED) /* line 10 */ PORT_START PORT_BIT (0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RSHIFT") PORT_CODE(KEYCODE_2_PAD) PORT_BIT (0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RSHIFT") PORT_CODE(KEYCODE_3_PAD) PORT_BIT (0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RSHIFT") PORT_CODE(KEYCODE_4_PAD) PORT_BIT (0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RSHIFT") PORT_CODE(KEYCODE_5_PAD) PORT_BIT (0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RSHIFT") PORT_CODE(KEYCODE_6_PAD) PORT_BIT (0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RSHIFT") PORT_CODE(KEYCODE_7_PAD) PORT_BIT (0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RSHIFT") PORT_CODE(KEYCODE_8_PAD) PORT_BIT (0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RSHIFT") PORT_CODE(KEYCODE_9_PAD) /* PORT_BIT (0x0ff, 0x000, IPT_UNUSED) */ /* line 11 */ PORT_START PORT_BIT (0x0ff, 0x000, IPT_UNUSED) /* line 12 */ PORT_START PORT_BIT (0x0ff, 0x000, IPT_UNUSED) /* line 13 */ PORT_START PORT_BIT (0x0ff, 0x000, IPT_UNUSED) /* line 14 */ PORT_START PORT_BIT (0x0ff, 0x000, IPT_UNUSED) /* line 15 */ PORT_START PORT_BIT (0x0ff, 0x000, IPT_UNUSED) PORT_START PORT_BIT (0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RESET") PORT_CODE(KEYCODE_ESC) INPUT_PORTS_END static struct z80_irq_daisy_chain sord_m5_daisy_chain[] = { {z80ctc_reset, z80ctc_irq_state, z80ctc_irq_ack, z80ctc_irq_reti, 0}, {0,0,0,0,-1} }; static INTERRUPT_GEN( sord_interrupt ) { if (TMS9928A_interrupt()) cpunum_set_input_line(0, 0, HOLD_LINE); } static MACHINE_DRIVER_START( sord_m5 ) /* basic machine hardware */ MDRV_CPU_ADD_TAG("main", Z80, 3800000) MDRV_CPU_PROGRAM_MAP(sord_m5_mem, 0) MDRV_CPU_IO_MAP(sord_m5_io, 0) MDRV_CPU_VBLANK_INT(sord_interrupt, 1) MDRV_CPU_CONFIG( sord_m5_daisy_chain ) MDRV_SCREEN_REFRESH_RATE(50) MDRV_SCREEN_VBLANK_TIME(DEFAULT_REAL_60HZ_VBLANK_DURATION) MDRV_INTERLEAVE(1) MDRV_MACHINE_START( sord_m5 ) MDRV_MACHINE_RESET( sord_m5 ) /* video hardware */ MDRV_IMPORT_FROM(tms9928a) /* sound hardware */ MDRV_SPEAKER_STANDARD_MONO("mono") MDRV_SOUND_ADD(SN76489A, 3579545) /* 3.579545 MHz */ MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) MACHINE_DRIVER_END static MACHINE_DRIVER_START( sord_m5_fd5 ) MDRV_IMPORT_FROM( sord_m5 ) MDRV_CPU_REPLACE("main", Z80, 3800000) MDRV_CPU_IO_MAP(srdm5fd5_io, 0) MDRV_CPU_ADD(Z80, 3800000) MDRV_CPU_PROGRAM_MAP(sord_fd5_mem, 0) MDRV_CPU_IO_MAP(readport_sord_fd5,writeport_sord_fd5) MDRV_INTERLEAVE(20) MDRV_MACHINE_RESET( sord_m5_fd5 ) MACHINE_DRIVER_END /*************************************************************************** Game driver(s) ***************************************************************************/ ROM_START(sordm5) ROM_REGION(0x010000, REGION_CPU1, 0) ROM_LOAD("sordint.rom",0x0000, 0x02000, CRC(78848d39) SHA1(ac042c4ae8272ad6abe09ae83492ef9a0026d0b2)) ROM_REGION(0x5000, REGION_USER1, 0) ROM_CART_LOAD(0, "rom", 0x0000, 0x5000, ROM_NOMIRROR) ROM_END ROM_START(srdm5fd5) ROM_REGION(0x10000, REGION_CPU1, 0) ROM_LOAD("sordint.rom",0x0000, 0x02000, CRC(78848d39) SHA1(ac042c4ae8272ad6abe09ae83492ef9a0026d0b2)) ROM_REGION(0x10000, REGION_CPU2, 0) ROM_LOAD("sordfd5.rom",0x0000, 0x04000, NO_DUMP) ROM_REGION(0x5000, REGION_USER1, 0) ROM_END static FLOPPY_OPTIONS_START( sordm5 ) FLOPPY_OPTION( sordm5, "dsk", "Sord M5 disk image", basicdsk_identify_default, basicdsk_construct_default, HEADS([1]) TRACKS([40]) SECTORS([18]) SECTOR_LENGTH([256]) FIRST_SECTOR_ID([1])) FLOPPY_OPTIONS_END static void sordm5_printer_getinfo(const device_class *devclass, UINT32 state, union devinfo *info) { /* printer */ switch(state) { /* --- the following bits of info are returned as 64-bit signed integers --- */ case DEVINFO_INT_COUNT: info->i = 1; break; default: printer_device_getinfo(devclass, state, info); break; } } static void sordm5_cassette_getinfo(const device_class *devclass, UINT32 state, union devinfo *info) { /* cassette */ switch(state) { /* --- the following bits of info are returned as 64-bit signed integers --- */ case DEVINFO_INT_COUNT: info->i = 1; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case DEVINFO_PTR_CASSETTE_FORMATS: info->p = (void *) sordm5_cassette_formats; break; default: cassette_device_getinfo(devclass, state, info); break; } } SYSTEM_CONFIG_START(sordm5) CONFIG_RAM_DEFAULT(64 * 1024) CONFIG_DEVICE(sordm5_printer_getinfo) CONFIG_DEVICE(sordm5_cassette_getinfo) CONFIG_DEVICE(cartslot_device_getinfo) SYSTEM_CONFIG_END static void srdm5fd5_floppy_getinfo(const device_class *devclass, UINT32 state, union devinfo *info) { /* floppy */ switch(state) { /* --- the following bits of info are returned as 64-bit signed integers --- */ case DEVINFO_INT_COUNT: info->i = 4; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case DEVINFO_PTR_FLOPPY_OPTIONS: info->p = (void *) floppyoptions_sordm5; break; default: floppy_device_getinfo(devclass, state, info); break; } } SYSTEM_CONFIG_START(srdm5fd5) CONFIG_IMPORT_FROM(sordm5) CONFIG_DEVICE(srdm5fd5_floppy_getinfo) SYSTEM_CONFIG_END /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT CONFIG COMPANY FULLNAME */ COMP( 1983, sordm5, 0, 0, sord_m5, sord_m5, 0, sordm5, "Sord", "Sord M5", 0) COMP(1983, srdm5fd5, 0, 0, sord_m5_fd5, sord_m5, 0, srdm5fd5, "Sord", "Sord M5 + PI5 + FD5", GAME_NOT_WORKING)