From 84ecd31bfa757cbe4473e823fad74479b76ef13d Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 25 Mar 2014 13:51:13 +0000 Subject: [PATCH] (MESS) New driver added : - SWTPC S/09 [Robert Justice] --- .gitattributes | 3 + src/emu/machine/6850acia.c | 5 +- src/mess/drivers/swtpc09.c | 292 +++++++++++ src/mess/includes/swtpc09.h | 131 +++++ src/mess/machine/swtpc09.c | 973 ++++++++++++++++++++++++++++++++++++ src/mess/mess.lst | 7 + src/mess/mess.mak | 5 + 7 files changed, 1413 insertions(+), 3 deletions(-) create mode 100644 src/mess/drivers/swtpc09.c create mode 100644 src/mess/includes/swtpc09.h create mode 100644 src/mess/machine/swtpc09.c diff --git a/.gitattributes b/.gitattributes index 65150f26ee4..e5f9aeb2ae5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7931,6 +7931,7 @@ src/mess/drivers/svi318.c svneol=native#text/plain src/mess/drivers/svision.c svneol=native#text/plain src/mess/drivers/svmu.c svneol=native#text/plain src/mess/drivers/swtpc.c svneol=native#text/plain +src/mess/drivers/swtpc09.c svneol=native#text/plain src/mess/drivers/sym1.c svneol=native#text/plain src/mess/drivers/sys2900.c svneol=native#text/plain src/mess/drivers/systec.c svneol=native#text/plain @@ -8210,6 +8211,7 @@ src/mess/includes/super80.h svneol=native#text/plain src/mess/includes/superslave.h svneol=native#text/plain src/mess/includes/svi318.h svneol=native#text/plain src/mess/includes/svision.h svneol=native#text/plain +src/mess/includes/swtpc09.h svneol=native#text/plain src/mess/includes/tandy1t.h svneol=native#text/plain src/mess/includes/tandy2k.h svneol=native#text/plain src/mess/includes/tdv2324.h svneol=native#text/plain @@ -8573,6 +8575,7 @@ src/mess/machine/super80.c svneol=native#text/plain src/mess/machine/svi318.c svneol=native#text/plain src/mess/machine/swim.c svneol=native#text/plain src/mess/machine/swim.h svneol=native#text/plain +src/mess/machine/swtpc09.c svneol=native#text/plain src/mess/machine/tandy1t.c svneol=native#text/plain src/mess/machine/tandy2kb.c svneol=native#text/plain src/mess/machine/tandy2kb.h svneol=native#text/plain diff --git a/src/emu/machine/6850acia.c b/src/emu/machine/6850acia.c index 02f0d12e605..2e52de30d57 100644 --- a/src/emu/machine/6850acia.c +++ b/src/emu/machine/6850acia.c @@ -220,9 +220,6 @@ WRITE8_MEMBER( acia6850_device::control_w ) m_status &= SR_CTS; - /// TODO: find out if this should be set as data sheet says status is cleared apart from cts & dcd - m_status |= SR_TDRE; - if (m_dcd) { m_status |= SR_DCD; @@ -538,6 +535,8 @@ WRITE_LINE_MEMBER( acia6850_device::write_txc ) case STATE_STOP: if (m_tx_counter == m_divide) { + m_tx_counter = 0; + m_tx_bits++; if (LOG) logerror("MC6850 '%s': TX STOP BIT %d\n", tag(), m_tx_bits); diff --git a/src/mess/drivers/swtpc09.c b/src/mess/drivers/swtpc09.c new file mode 100644 index 00000000000..b3c42aa5223 --- /dev/null +++ b/src/mess/drivers/swtpc09.c @@ -0,0 +1,292 @@ +/************************************************************************** + + SWTPC S/09 Mess driver + Robert Justice ,2009-2014 + + Emulates four different fixed combinations of hardware + 1. swtpc09 + MP-09 with SBUG rom, MP-ID, MP-S2, DMF2. + Will boot Flex operating system + 2. swtpc09i + MP-09 with SBUG rom + HDrom, MP-ID, MP-S2, DMF2, PIAIDE. + Will boot Flex operating system + TODO: finish ide part and get this one working. + 3. swtpc09u + MP-09 with UniBUG rom, MP-ID, MP-S2, DMF2. + Will boot UniFlex operating system + 4. swtpc09d3 + MP-09 with UniBUG U3 rom, MP-ID, MP-S2, DMF3. + Will boot UniFlex operating system + TODO: add Harddisk support, DMF3 has WD1000 interface + +***************************************************************************/ + +#define ADDRESS_MAP_MODERN + +#include "emu.h" +#include "includes/swtpc09.h" + + + +/************************************************************************** + Address maps + + 56K of RAM from 0x0000 to 0xdfff + 2K of ROM from 0xf800 to 0xffff + + E000 - E003 S2 MC6850 ACIA1 (used for UniFlex console) + E004 - E007 S2 MC6850 ACIA2 (used for Flex console) + E080 - E08F MPID MC6821 PIA + E090 - E09F MPID MC6840 PTM + + F000 - F01F DMF2 MC6844 DMAC + F020 - F023 DMF2 WD1791 FDC + F024 - F03F DMF2 Drive select register + F040 - F041 DMF2 DMA Address register + + F800 - FFFF ROM + FFF0 - FFFF DAT RAM (only for writes) + + + for DMF3 version + F000 - F01F DMF3 MC6844 DMAC + F020 - F023 DMF3 WD1791 FDC + F024 - F024 DMF3 Drive select register + F025 - F025 DMF3 DMA Address register + F040 - F04F DMF3 6522 VIA + +***************************************************************************/ + +/* Address map is dynamically setup when DAT memory is written to */ +/* only ROM from FF00-FFFF and DAT memory at FFF0-FFFF (write only) is guaranteed always*/ + +static ADDRESS_MAP_START(swtpc09_mem, AS_PROGRAM, 8, swtpc09_state) + AM_RANGE(0xff00, 0xffef) AM_ROM + AM_RANGE(0xfff0, 0xffff) AM_ROM AM_WRITE(dat_w) +ADDRESS_MAP_END + + +/* Input ports */ +static INPUT_PORTS_START( swtpc09 ) +INPUT_PORTS_END + +static LEGACY_FLOPPY_OPTIONS_START(swtpc09) + LEGACY_FLOPPY_OPTION(dsdd40, "dsk", "flex 40 trks ds dd 5.25", basicdsk_identify_default, basicdsk_construct_default, NULL, + HEADS([1]) + TRACKS([40]) + SECTORS([36]) + SECTOR_LENGTH([256]) + FIRST_SECTOR_ID([1])) + LEGACY_FLOPPY_OPTION(ssdd40, "dsk", "flex 40 trks ss dd 5.25 ", basicdsk_identify_default, basicdsk_construct_default, NULL, + HEADS([1]) + TRACKS([40]) + SECTORS([25]) + SECTOR_LENGTH([256]) + FIRST_SECTOR_ID([1])) + LEGACY_FLOPPY_OPTION(sssd40, "dsk", "flex 40 trks ss sd 5.25", basicdsk_identify_default, basicdsk_construct_default, NULL, + HEADS([1]) + TRACKS([40]) + SECTORS([10]) + SECTOR_LENGTH([256]) + FIRST_SECTOR_ID([1])) + LEGACY_FLOPPY_OPTION(sssd35, "dsk", "flex 35 trks ss sd 5.25", basicdsk_identify_default, basicdsk_construct_default, NULL, + HEADS([1]) + TRACKS([35]) + SECTORS([10]) + SECTOR_LENGTH([256]) + FIRST_SECTOR_ID([1])) + LEGACY_FLOPPY_OPTION(flex144M, "dsk", "flex 1.44mb disk from swtpc emu", basicdsk_identify_default, basicdsk_construct_default, NULL, + HEADS([1]) + TRACKS([80]) + SECTORS([72]) + SECTOR_LENGTH([256]) + FIRST_SECTOR_ID([1])) + LEGACY_FLOPPY_OPTION(flexdssd8inch, "dsk", "Flex 8 inch ds sd floppy image", basicdsk_identify_default, basicdsk_construct_default, NULL, + HEADS([1]) + TRACKS([77]) + SECTORS([30]) + SECTOR_LENGTH([256]) + FIRST_SECTOR_ID([1])) + LEGACY_FLOPPY_OPTION(uniflexdssd8inch, "dsk", "UNIFlex 8 inch ds sd floppy image", basicdsk_identify_default, basicdsk_construct_default, NULL, + HEADS([1]) + TRACKS([77]) + SECTORS([16]) + SECTOR_LENGTH([512]) + FIRST_SECTOR_ID([1])) + LEGACY_FLOPPY_OPTION(uniflexdsdd8inch, "dsk", "UNIFlex 8 inch ds dd floppy image", basicdsk_identify_default, basicdsk_construct_default, NULL, + HEADS([1]) + TRACKS([77]) + SECTORS([32]) + SECTOR_LENGTH([512]) + FIRST_SECTOR_ID([1])) +LEGACY_FLOPPY_OPTIONS_END + + +static const floppy_interface swtpc09_floppy_interface = +{ + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + DEVCB_NULL, + FLOPPY_STANDARD_5_25_DSHD, + LEGACY_FLOPPY_OPTIONS_NAME(swtpc09), + NULL, + NULL +}; + +WRITE_LINE_MEMBER(swtpc09_state::write_acia_clock) +{ + m_acia->write_txc(state); + m_acia->write_rxc(state); +} + +/*************************************************************************** + Machine definitions +****************************************************************************/ + +/* Machine driver */ +/* MPU09, MPID, MPS2 DMF2 */ +static MACHINE_CONFIG_START( swtpc09, swtpc09_state ) + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", M6809, 1000000) + MCFG_CPU_PROGRAM_MAP(swtpc09_mem) + + /* video hardware */ + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "serial_terminal") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("acia", acia6850_device, write_rxd)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("acia", acia6850_device, write_cts)) + + MCFG_PTM6840_ADD("ptm", swtpc09_6840_intf) + + MCFG_DEVICE_ADD("pia", PIA6821, 0) + MCFG_PIA_READPA_HANDLER(READ8(swtpc09_state, pia0_a_r)) + MCFG_PIA_READPA_HANDLER(READ8(swtpc09_state, pia0_ca1_r)) + MCFG_PIA_IRQA_HANDLER(WRITELINE(swtpc09_state, pia0_irq_a)) + + MCFG_DEVICE_ADD("acia", ACIA6850, 0) + MCFG_ACIA6850_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_ACIA6850_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(swtpc09_state, acia_interrupt)) + + MCFG_DEVICE_ADD("acia_clock", CLOCK, 153600) + MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(swtpc09_state, write_acia_clock)) + + MCFG_FD1793_ADD("fdc", swtpc09_wd17xx_interface ) + MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(swtpc09_floppy_interface) + + +MACHINE_CONFIG_END + +/* MPU09, MPID, MPS2 DC4 PIAIDE*/ +static MACHINE_CONFIG_START( swtpc09i, swtpc09_state ) + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", M6809, 1000000) + MCFG_CPU_PROGRAM_MAP(swtpc09_mem) + + /* video hardware */ + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "serial_terminal") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("acia", acia6850_device, write_rxd)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("acia", acia6850_device, write_cts)) + + MCFG_PTM6840_ADD("ptm", swtpc09_6840_intf) + + MCFG_DEVICE_ADD("pia", PIA6821, 0) + MCFG_PIA_READPA_HANDLER(READ8(swtpc09_state, pia0_a_r)) + MCFG_PIA_READPA_HANDLER(READ8(swtpc09_state, pia0_ca1_r)) + MCFG_PIA_IRQA_HANDLER(WRITELINE(swtpc09_state, pia0_irq_a)) + + MCFG_DEVICE_ADD("acia", ACIA6850, 0) + MCFG_ACIA6850_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_ACIA6850_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(swtpc09_state, acia_interrupt)) + + MCFG_DEVICE_ADD("acia_clock", CLOCK, 153600) + MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(swtpc09_state, write_acia_clock)) + + MCFG_FD1793_ADD("fdc", swtpc09_wd17xx_interface ) + MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(swtpc09_floppy_interface) + + MCFG_DEVICE_ADD("piaide", PIA6821, 0) + +/* old start to adding ide support, needs major updating */ +/* this is to support an add on card driving IDE from a PIA */ +// MCFG_HARDDISK_ADD("harddisk") +// MCFG_IDE_CONTROLLER_ADD("ide", NULL) +// MCFG_IDE_CONTROLLER_REGIONS("harddisk", NULL) +// MCFG_IDE_CONTROLLER_ADD( "ide", ide_intf, "hdd", NULL, false ) /* FIXME */ bebox + + +MACHINE_CONFIG_END + + +/* MPU09, MPID, MPS2 DMF3 */ +static MACHINE_CONFIG_START( swtpc09d3, swtpc09_state ) + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", M6809, 2000000) + MCFG_CPU_PROGRAM_MAP(swtpc09_mem) + + /* video hardware */ + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "serial_terminal") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("acia", acia6850_device, write_rxd)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("acia", acia6850_device, write_cts)) + + MCFG_PTM6840_ADD("ptm", swtpc09_6840_intf) + + MCFG_DEVICE_ADD("pia", PIA6821, 0) + MCFG_PIA_READPA_HANDLER(READ8(swtpc09_state, pia0_a_r)) + MCFG_PIA_READPA_HANDLER(READ8(swtpc09_state, pia0_ca1_r)) + MCFG_PIA_IRQA_HANDLER(WRITELINE(swtpc09_state, pia0_irq_a)) + + MCFG_DEVICE_ADD("acia", ACIA6850, 0) + MCFG_ACIA6850_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_ACIA6850_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(swtpc09_state, acia_interrupt)) + MCFG_ACIA6850_IRQ_HANDLER(DEVWRITELINE("maincpu", m6809_device, irq_line)) + + MCFG_DEVICE_ADD("acia_clock", CLOCK, 153600) + MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(swtpc09_state, write_acia_clock)) + + MCFG_FD1793_ADD("fdc", swtpc09_wd17xx_interface ) + MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(swtpc09_floppy_interface) + + MCFG_DEVICE_ADD("via", VIA6522, XTAL_4MHz / 4) + MCFG_VIA6522_READPA_HANDLER(READ8(swtpc09_state, dmf3_via_read_porta)) + MCFG_VIA6522_READPB_HANDLER(READ8(swtpc09_state, dmf3_via_read_portb)) + MCFG_VIA6522_WRITEPA_HANDLER(WRITE8(swtpc09_state, dmf3_via_write_porta)) + //MCFG_VIA6522_CA1_HANDLER(WRITELINE(swtpc09_state, dmf3_via_write_ca1)) + MCFG_VIA6522_IRQ_HANDLER(WRITELINE(swtpc09_state, dmf3_via_irq)) + + +MACHINE_CONFIG_END + + +/* ROM definition */ +ROM_START( swtpc09 ) + ROM_REGION( 0x100000, "maincpu", 0 ) + ROM_LOAD ( "sbugh1-8.bin", 0xf800, 0x0800, CRC(10a045a7) SHA1(de547b77653951c7424a069520d52c5b0432e98d) ) +ROM_END + +ROM_START( swtpc09i ) + ROM_REGION( 0x100000, "maincpu", 0 ) + ROM_LOAD ( "hd-rom.bin", 0xe800, 0x0800, CRC(b898b4d7) SHA1(2806633eda7da4e9a243fc534f15526ee928b6bc) ) + ROM_LOAD ( "sbugh1-8.bin", 0xf800, 0x0800, CRC(10a045a7) SHA1(de547b77653951c7424a069520d52c5b0432e98d) ) +ROM_END + +ROM_START( swtpc09u ) + ROM_REGION( 0x100000, "maincpu", 0 ) + ROM_LOAD ( "unibug.bin", 0xf800, 0x0800, CRC(92e1cbf2) SHA1(db00f17ee9accdbfa1775fe0162d3556159b8e70) ) +ROM_END + +ROM_START( swtpc09d3 ) + ROM_REGION( 0x100000, "maincpu", 0 ) + ROM_LOAD ( "uos3.bin", 0xf800, 0x0800, CRC(e95eb3e0) SHA1(3e971d3b7e143bc87e4b506e18a8c928c089c25a) ) +ROM_END + +/* Driver */ + +/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ +COMP( 1980, swtpc09, 0, 0, swtpc09, swtpc09, swtpc09_state, swtpc09, "SWTPC", "swtpc S/09 Sbug", GAME_NO_SOUND_HW) +COMP( 1980, swtpc09i, swtpc09, 0, swtpc09i, swtpc09, swtpc09_state, swtpc09i, "SWTPC", "swtpc S/09 Sbug + piaide", GAME_NOT_WORKING | GAME_NO_SOUND_HW) +COMP( 1980, swtpc09u, swtpc09, 0, swtpc09, swtpc09, swtpc09_state, swtpc09u, "SWTPC", "swtpc S/09 UNIBug + DMF2", GAME_NO_SOUND_HW) +COMP( 1980, swtpc09d3, swtpc09, 0, swtpc09d3, swtpc09, swtpc09_state, swtpc09d3, "SWTPC", "swtpc S/09 UNIBug + DMF3", GAME_NO_SOUND_HW) diff --git a/src/mess/includes/swtpc09.h b/src/mess/includes/swtpc09.h new file mode 100644 index 00000000000..3221de06bda --- /dev/null +++ b/src/mess/includes/swtpc09.h @@ -0,0 +1,131 @@ +/*************************************************************************** + swtpc09 include file + Robert Justice ,2009-2014 + +****************************************************************************/ + +#ifndef swtpc09_H_ +#define swtpc09_H_ + +#include "emu.h" +#include "cpu/m6809/m6809.h" +#include "video/generic.h" +#include "machine/wd17xx.h" +#include "formats/basicdsk.h" +#include "imagedev/flopdrv.h" +#include "machine/wd17xx.h" +#include "machine/6840ptm.h" +#include "machine/6821pia.h" +#include "machine/6850acia.h" +#include "machine/6522via.h" +#include "machine/terminal.h" +#include "imagedev/harddriv.h" +#include "machine/idectrl.h" +#include "machine/clock.h" +#include "bus/rs232/rs232.h" + + + +class swtpc09_state : public driver_device +{ +public: + swtpc09_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_pia(*this, "pia"), + m_ptm(*this, "ptm"), + m_acia(*this, "acia"), + m_fdc(*this, "fdc"), + m_via(*this, "via"), + m_piaide(*this, "piaide"), + m_harddisk(*this, "harddisk"), + m_ide(*this, "ide") + { } + + required_device m_maincpu; + required_device m_pia; + required_device m_ptm; + required_device m_acia; + required_device m_fdc; + optional_device m_via; + optional_device m_piaide; + optional_device m_harddisk; + optional_device m_ide; + + DECLARE_READ8_MEMBER(pia0_a_r); + DECLARE_READ8_MEMBER(pia0_ca1_r); + DECLARE_WRITE_LINE_MEMBER( pia0_irq_a ); + + DECLARE_WRITE8_MEMBER( ptm_o1_callback ); + DECLARE_WRITE8_MEMBER( ptm_o3_callback ); + DECLARE_WRITE_LINE_MEMBER( ptm_irq ); + + DECLARE_WRITE_LINE_MEMBER( acia_interrupt ); + DECLARE_WRITE_LINE_MEMBER( write_acia_clock ); + + DECLARE_WRITE_LINE_MEMBER( fdc_intrq_w ); + DECLARE_WRITE_LINE_MEMBER( fdc_drq_w ); + + DECLARE_READ8_MEMBER( dmf3_via_read_porta ); + DECLARE_READ8_MEMBER( dmf3_via_read_portb ); + DECLARE_WRITE8_MEMBER( dmf3_via_write_porta ); + DECLARE_WRITE_LINE_MEMBER( dmf3_via_write_ca1 ); + DECLARE_WRITE_LINE_MEMBER( dmf3_via_irq ); + + DECLARE_READ8_MEMBER(piaide_a_r); + DECLARE_READ8_MEMBER(piaide_b_r); + DECLARE_WRITE8_MEMBER(piaide_a_w); + DECLARE_WRITE8_MEMBER(piaide_b_w); + + DECLARE_WRITE8_MEMBER(swtpc09_kbd_put); + + DECLARE_READ8_MEMBER ( dmf2_dma_address_reg_r ); + DECLARE_WRITE8_MEMBER ( dmf2_dma_address_reg_w ); + DECLARE_READ8_MEMBER ( dmf2_control_reg_r ); + DECLARE_WRITE8_MEMBER ( dmf2_control_reg_w ); + + DECLARE_READ8_MEMBER ( dmf3_dma_address_reg_r ); + DECLARE_WRITE8_MEMBER ( dmf3_dma_address_reg_w ); + DECLARE_READ8_MEMBER ( dmf3_control_reg_r ); + DECLARE_WRITE8_MEMBER ( dmf3_control_reg_w ); + + DECLARE_WRITE8_MEMBER ( dc4_control_reg_w ); + + DECLARE_WRITE8_MEMBER(dat_w); + + DECLARE_DRIVER_INIT( swtpc09 ); + DECLARE_DRIVER_INIT( swtpc09i ); + DECLARE_DRIVER_INIT( swtpc09u ); + DECLARE_DRIVER_INIT( swtpc09d3 ); + + void swtpc09_fdc_dma_transfer(); + void swtpc09_irq_handler(UINT8 peripheral, UINT8 state); + + UINT8 m_term_data; // terminal keyboard value + UINT8 m_pia_counter; // this is the counter on pia porta + UINT8 m_fdc_dma_address_reg; // dmf2 or dmf3 dma extended address reg + UINT8 m_system_type; // flag to indicate hw and rom combination + UINT8 m_fdc_status; // for floppy controller + UINT8 m_via_ca1_input; // dmf3 fdc interupt is connected here + UINT8 m_dmf3_via_porta; + UINT8 m_piaide_porta; + UINT8 m_piaide_portb; + UINT8 m_active_interrupt; + UINT8 m_interrupt; + +}; + +/*----------- defined in machine/swtpc09.c -----------*/ + +extern const wd17xx_interface swtpc09_wd17xx_interface; +extern const ptm6840_interface swtpc09_6840_intf; + + +READ8_HANDLER ( m6844_r ); +WRITE8_HANDLER ( m6844_w ); + + +#endif /* swtpc09_H_ */ + + + diff --git a/src/mess/machine/swtpc09.c b/src/mess/machine/swtpc09.c new file mode 100644 index 00000000000..05e1cba7895 --- /dev/null +++ b/src/mess/machine/swtpc09.c @@ -0,0 +1,973 @@ +/*************************************************************************** + swtpc09 machine file + Robert Justice ,2009-2014 + +****************************************************************************/ + +#include "emu.h" +#include "includes/swtpc09.h" + +#define DMAC_IRQ 0x01 // interrupt handler IDs +#define ACIA_IRQ 0x02 +#define PTM_IRQ 0x04 +#define PIA_IRQ 0x08 +#define FDC_IRQ 0x10 +#define VIA_IRQ 0x20 + +#define FLEX_DMF2 1 // system type flags +#define UNIFLEX_DMF2 2 +#define UNIFLEX_DMF3 3 +#define FLEX_DC4_PIAIDE 4 + +#define VERBOSE 0 + +#define LOG(x) do { if (VERBOSE) logerror x; } while (0) + + +/* channel_data structure holds info about each 6844 DMA channel */ +typedef struct m6844_channel_data +{ + int active; + int address; + int counter; + UINT8 control; + int start_address; + int start_counter; +} m6844_channel_data; + +/* 6844 description */ +static m6844_channel_data m6844_channel[4]; +static UINT8 m6844_priority; +static UINT8 m6844_interrupt; +static UINT8 m6844_chain; + +/******* MC6840 PTM on MPID Board *******/ +/* 6840 PTM interface */ +const ptm6840_interface swtpc09_6840_intf = +{ + 2000000, + { 50, 0, 50 }, + { DEVCB_DRIVER_MEMBER(swtpc09_state, ptm_o1_callback), DEVCB_NULL, DEVCB_DRIVER_MEMBER(swtpc09_state, ptm_o3_callback) }, + DEVCB_DRIVER_LINE_MEMBER(swtpc09_state, ptm_irq) +}; + +/* 6840 PTM handlers */ +WRITE8_MEMBER( swtpc09_state::ptm_o1_callback ) +{ + pia6821_device *pia = machine().device("pia"); + + m_pia_counter++; + //pia_counter = pia_counter && 0xff; + if (m_pia_counter && 0x80) pia->ca1_w(1); +} + +WRITE8_MEMBER( swtpc09_state::ptm_o3_callback ) +{ + //ptm6840_device *ptm = machine().device("ptm"); + /* the output from timer3 is the input clock for timer2 */ + //m_ptm->set_c2(data); +} + +WRITE_LINE_MEMBER( swtpc09_state::ptm_irq ) +{ + if (state) + swtpc09_irq_handler(PTM_IRQ, ASSERT_LINE); + else + swtpc09_irq_handler(PTM_IRQ, CLEAR_LINE); +} + +/******* MC6821 PIA on MPID Board *******/ +/* Read/Write handlers for pia */ + +READ8_MEMBER( swtpc09_state::pia0_a_r ) +{ + return m_pia_counter; +} + +READ8_MEMBER( swtpc09_state::pia0_ca1_r ) +{ + return 0; +} + +WRITE_LINE_MEMBER( swtpc09_state::pia0_irq_a ) +{ + pia6821_device *pia = machine().device("pia"); + + if ( pia->irq_a_state()) + swtpc09_irq_handler(PIA_IRQ, ASSERT_LINE); + else + swtpc09_irq_handler(PIA_IRQ, CLEAR_LINE); + +} + + +/******* MC6850 ACIA on MPS2 *******/ + +WRITE_LINE_MEMBER( swtpc09_state::acia_interrupt ) +{ + if (state) + { + swtpc09_irq_handler(ACIA_IRQ, ASSERT_LINE); + LOG(("swtpc09_acia_irq_assert\n")); + } + else + { + swtpc09_irq_handler(ACIA_IRQ, CLEAR_LINE); + LOG(("swtpc09_acia_irq_clear\n")); + } +} + +/*********************************************************************/ +/* DMF2 Floppy Controller Board */ +/*********************************************************************/ + +/* DMF2 dma extended address register */ +READ8_MEMBER ( swtpc09_state::dmf2_dma_address_reg_r ) +{ + return m_fdc_dma_address_reg; +} + +WRITE8_MEMBER ( swtpc09_state::dmf2_dma_address_reg_w ) +{ + m_fdc_dma_address_reg = data; + + // bit 4 controls a gate enable/disable for DMF2 fdc irq line + if ((m_fdc_dma_address_reg & 0x10) && (m_system_type == UNIFLEX_DMF2 || m_system_type == FLEX_DMF2)) + swtpc09_irq_handler(FDC_IRQ, CLEAR_LINE); //then clear the irq to cpu + + LOG(("swtpc09_dmf2_dma_address_reg_w %02X\n", data)); +} + +/* DMF2 fdc control register */ +READ8_MEMBER ( swtpc09_state::dmf2_control_reg_r ) +{ + //LOG(("swtpc09_dmf2_control_reg_r $%02X\n", m_fdc_status)); + return m_fdc_status; +} + +WRITE8_MEMBER ( swtpc09_state::dmf2_control_reg_w ) +{ + LOG(("swtpc09_dmf2_control_reg_w $%02X\n", data)); + + switch (data & 0x0F) + { + case 0x0e: + m_fdc->set_drive(0); + // need to set drive ready as sw checks before doing anything + floppy_drive_set_ready_state(machine().device("floppy0"), 1,0); + break; + case 0x0d: + m_fdc->set_drive(1); + floppy_drive_set_ready_state(machine().device("floppy1"), 1,0); + break; + + case 0x0b: + m_fdc->set_drive(2); + floppy_drive_set_ready_state(machine().device("floppy2"), 1,0); + break; + + case 0x07: + m_fdc->set_drive(3); + floppy_drive_set_ready_state(machine().device("floppy3"), 1,0); + break; + + default: + break; + } + + // ignore side select in emulation due to sector numbering + ////side select + //if (!(data & 0x10)) { + // wd17xx_set_side(fdc, 1); + //} + //if (data & 0x10) { + // wd17xx_set_side(fdc, 0); + //} + + + /* bit 5 dden select */ + + if (!(data & 0x20)) { + m_fdc->dden_w(0); + LOG(("Density single\n")); + } + if (data & 0x20) { + m_fdc->dden_w(1); + LOG(("Density double\n")); + } +} + +/* FDC controller dma transfer */ +void swtpc09_state::swtpc09_fdc_dma_transfer() +{ + UINT8 *RAM = memregion("maincpu")->base(); + UINT32 offset; + address_space &space = m_maincpu->space(AS_PROGRAM); + + offset = (m_fdc_dma_address_reg & 0x0f)<<16; + + if (m6844_channel[0].active == 1) //active dma transfer + { + if (!(m6844_channel[0].control & 0x01)) // dma write to memory + { + UINT8 data = m_fdc->data_r(space, 0); + + LOG(("swtpc09_dma_write_mem %05X %02X\n", m6844_channel[0].address + offset, data)); + RAM[m6844_channel[0].address + offset] = data; + } + else + { + UINT8 data = RAM[m6844_channel[0].address + offset]; + + m_fdc->data_w(space, 0, data); + //LOG(("swtpc09_dma_read_mem %04X %02X\n", m6844_channel[0].address, data)); + } + + m6844_channel[0].address++; + m6844_channel[0].counter--; + + if (m6844_channel[0].counter == 0) // dma transfer has finished + { + m6844_channel[0].control |= 0x80; // set dend flag + if (m6844_interrupt & 0x01) // interrupt for channel 0 is enabled? + { + m6844_interrupt |= 0x80; // set bit 7 to indicate active interrupt + swtpc09_irq_handler(DMAC_IRQ, ASSERT_LINE); + } + } + } + +} + +/* common interrupt handler */ +void swtpc09_state::swtpc09_irq_handler(UINT8 peripheral, UINT8 state) +{ + LOG(("swtpc09_irq_handler peripheral:%02X state:%02X\n", peripheral, state)); + + switch (state) + { + case ASSERT_LINE: + m_interrupt |= peripheral; + break; + + case CLEAR_LINE: + m_interrupt &= (~peripheral & 0x3f); + break; + } + + if (!m_active_interrupt && m_interrupt) //no active interrupt and it needs to be asserted + { + m_maincpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); + m_active_interrupt=TRUE; + LOG(("swtpc09_irq_assert %02X\n", peripheral)); + } + else if (m_active_interrupt && !m_interrupt) //active interrupt and it needs to be cleared + { + m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); + LOG(("swtpc09_irq_clear %02X\n", peripheral)); + m_active_interrupt=FALSE; + } +} + +/******* WD1791 FDC *******/ +/* wd1791 fdc interface */ +const wd17xx_interface swtpc09_wd17xx_interface = +{ + DEVCB_NULL, + DEVCB_DRIVER_LINE_MEMBER(swtpc09_state, fdc_intrq_w), + DEVCB_DRIVER_LINE_MEMBER(swtpc09_state, fdc_drq_w), + {FLOPPY_0, FLOPPY_1, FLOPPY_2, FLOPPY_3 } +}; + +/* handlers for fdc */ +WRITE_LINE_MEMBER( swtpc09_state::fdc_intrq_w ) +{ + LOG(("swtpc09_fdc_intrq_w %02X\n", state)); + if ( m_system_type == UNIFLEX_DMF3 ) //IRQ from 1791 is connect into VIA ca2 + { + if (state) + { + m_fdc_status |= 0x40; + m_via->write_cb2(0); //fdc interrupt is connected to CA1 + m_dmf3_via_porta &= 0xfb; //clear pa3 + //m_via->write_porta(m_dmf3_via_porta); //and connected to PA3 + //swtpc09_irq_handler(FDC_IRQ, ASSERT_LINE); + } + else + { + m_fdc_status &= ~0x40; + m_via->write_cb2(1); + m_dmf3_via_porta |= 0x04; //and connected to PA3 + //m_via->write_porta(m_dmf3_via_porta); //and connected to PA3 + //swtpc09_irq_handler(FDC_IRQ, CLEAR_LINE); + } + } + else if ( m_system_type == FLEX_DC4_PIAIDE ) //for dc4 emulate irq jumper out + { + if (state) + { + m_fdc_status |= 0x40; + } + else + { + m_fdc_status &= ~0x40; + } + } + else //for dmf2 it is connected directly to cpu via a gate + { + if (state) + { + m_fdc_status |= 0x40; + if (!(m_fdc_dma_address_reg & 0x10)) // is dmf2 fdc irq enabled + { + LOG(("swtpc09_fdc_int ** assert\n")); + swtpc09_irq_handler(FDC_IRQ, ASSERT_LINE); + } + } + else + { + m_fdc_status &= ~0x40; + if (!(m_fdc_dma_address_reg & 0x10)) // is dmf2 fdc irq enabled + { + LOG(("swtpc09_fdc_int ** clear\n")); + swtpc09_irq_handler(FDC_IRQ, CLEAR_LINE); + } + } + } +} + +WRITE_LINE_MEMBER( swtpc09_state::fdc_drq_w ) +{ + if (m_system_type == FLEX_DC4_PIAIDE) //for dc4 no dma + { + if (state) + { + m_fdc_status |= 0x80; + } + else + m_fdc_status &= 0x7f; + } + else + { + if (state) + { + m_fdc_status |= 0x80; + swtpc09_fdc_dma_transfer(); + } + else + m_fdc_status &= 0x7f; + } +} + +/*********************************************************************/ +/* DMF3 Board */ +/*********************************************************************/ + +/* via on dmf3 board */ +READ8_MEMBER( swtpc09_state::dmf3_via_read_porta ) +{ + return m_dmf3_via_porta; +} + +READ8_MEMBER( swtpc09_state::dmf3_via_read_portb ) +{ + return 0xff; +} + +WRITE8_MEMBER( swtpc09_state::dmf3_via_write_porta ) +{ + m_dmf3_via_porta &= data; +} + +//WRITE_LINE_MEMBER( swtpc09_state::dmf3_via_write_ca1 ) +//{ +// return m_via_ca1_input; +// LOG(("swtpc09_dmf3_via_write_ca1 %02X\n", state)); + +//} + +WRITE_LINE_MEMBER( swtpc09_state::dmf3_via_irq ) +{ + if (state) + swtpc09_irq_handler(VIA_IRQ, ASSERT_LINE); + else + swtpc09_irq_handler(VIA_IRQ, CLEAR_LINE); +} + +/* DMF3 dma extended address register */ +READ8_MEMBER ( swtpc09_state::dmf3_dma_address_reg_r ) +{ + return m_fdc_dma_address_reg; +} + +WRITE8_MEMBER ( swtpc09_state::dmf3_dma_address_reg_w ) +{ + m_fdc_dma_address_reg = data; + LOG(("swtpc09_dmf3_dma_address_reg_w %02X\n", data)); +} + +/* DMF3 fdc control register */ +READ8_MEMBER ( swtpc09_state::dmf3_control_reg_r ) +{ + //LOG(("swtpc09_dmf3_control_reg_r $%02X\n", m_fdc_status)); + return m_fdc_status; +} + +WRITE8_MEMBER ( swtpc09_state::dmf3_control_reg_w ) +{ + LOG(("swtpc09_dmf3_control_reg_w $%02X\n", data)); + + switch (data & 0x0F) + { + case 0x01: + m_fdc->set_drive(0); + // need to set drive ready as sw checks before doing anything + floppy_drive_set_ready_state(machine().device("floppy0"), 1,0); + break; + case 0x02: + m_fdc->set_drive(1); + floppy_drive_set_ready_state(machine().device("floppy1"), 1,0); + break; + + case 0x04: + m_fdc->set_drive(2); + floppy_drive_set_ready_state(machine().device("floppy2"), 1,0); + break; + + case 0x08: + m_fdc->set_drive(3); + floppy_drive_set_ready_state(machine().device("floppy3"), 1,0); + break; + + default: + break; + } + + // ignore side select in emulation due to sector numbering + ////side select + //if (!(data & 0x10)) { + // wd17xx_set_side(fdc, 1); + //} + //if (data & 0x10) { + // wd17xx_set_side(fdc, 0); + //} + + + /* bit 5 dden select */ + + if (data & 0x20) { + m_fdc->dden_w(0); + LOG(("Density single\n")); + } + if (!(data & 0x20)) { + m_fdc->dden_w(1); + LOG(("Density double\n")); + } +} + +// DC4 drive select + +WRITE8_MEMBER ( swtpc09_state::dc4_control_reg_w ) +{ + LOG(("swtpc09_dc4_control_reg_w $%02X\n", data)); + + switch (data & 0x03) + { + case 0x00: + m_fdc->set_drive(0); + // need to set drive ready as sw checks before doing anything + floppy_drive_set_ready_state(machine().device("floppy0"), 1,0); + break; + case 0x01: + m_fdc->set_drive(1); + floppy_drive_set_ready_state(machine().device("floppy1"), 1,0); + break; + + case 0x02: + m_fdc->set_drive(2); + floppy_drive_set_ready_state(machine().device("floppy2"), 1,0); + break; + + case 0x03: + m_fdc->set_drive(3); + floppy_drive_set_ready_state(machine().device("floppy3"), 1,0); + break; + + default: + break; + } + + // ignore side select in emulation due to sector numbering +} + + +/******* MC6821 PIA on IDE Board *******/ +/* Read/Write handlers for pia ide */ +/* TODO: update and finish this off */ + +READ8_MEMBER( swtpc09_state::piaide_a_r ) +{ + return m_piaide_porta; +} + +READ8_MEMBER( swtpc09_state::piaide_b_r ) +{ + return m_piaide_portb; +} + +WRITE8_MEMBER( swtpc09_state::piaide_a_w ) +{ + m_piaide_porta = data; +} + +WRITE8_MEMBER( swtpc09_state::piaide_b_w ) +{ + int tempidedata; + + m_piaide_portb = data; + + if ((data & 0x40)&&(!(data&0x20))) //cs0=0 cs1=1 bit 5&6 + { + if (!(data & 0x02)) //rd line bit 1 + { + tempidedata = m_ide->read_cs0(space, (data&0x1c)>>2, 0xffff); + LOG(("swtpc09_ide_bus_r: offset $%02X data %04X\n", (data&0x1c)>>2, tempidedata)); + m_piaide_porta = tempidedata & 0x00ff; + } + else if (!(data & 0x01)) //wr line bit 0 + { + m_ide->write_cs0(space, (data&0x1c)>>2, m_piaide_porta, 0xffff); + LOG(("swtpc09_ide_bus_w: offset $%02X data %04X\n", (data&0x1c)>>2, m_piaide_porta)); + } + } + else if ((data & 0x20)&&(!(data&0x40))) //cs0=1 cs1=0 bit 5&6 + { + if (!(data & 0x02)) //rd line bit 1 + { + tempidedata = m_ide->read_cs1(space, (data&0x1c)>>2, 0xffff); + LOG(("swtpc09_ide_bus_r: offset $%02X data %04X\n", (data&0x1c)>>2, tempidedata)); + m_piaide_porta = tempidedata & 0x00ff; + } + else if (!(data & 0x01)) //wr line bit 0 + { + m_ide->write_cs1(space, (data&0x1c)>>2, m_piaide_porta, 0xffff); + LOG(("swtpc09_ide_bus_w: offset $%02X data %04X\n", (data&0x1c)>>2, m_piaide_porta)); + } + } +} + + +/* DAT ram write handler (Dynamic Address Translator) */ +/* This creates the address map when a page is mapped in */ +/* memory map is created based on system_type flag */ +/* this is accomodate the different cards installed */ + +WRITE8_MEMBER(swtpc09_state::dat_w) +{ + UINT8 a16_to_a19, a12_to_a15; + UINT8 *RAM = memregion("maincpu")->base(); + UINT32 physical_address, logical_address; + + address_space &mem = m_maincpu->space(AS_PROGRAM); + + fd1793_device *fdc = machine().device("fdc"); + pia6821_device *pia = machine().device("pia"); + ptm6840_device *ptm = machine().device("ptm"); + acia6850_device *acia = machine().device("acia"); + via6522_device *via = machine().device("via"); + pia6821_device *piaide = machine().device("piaide"); + + a16_to_a19 = data & 0xf0; + a12_to_a15 = ~data & 0x0f; //lower 4 bits are inverted + physical_address = ((a16_to_a19 + a12_to_a15) << 12); + logical_address = offset << 12; + LOG(("swtpc09_dat_bank_unmap Logical address:%04X\n", offset << 12 )); + LOG(("swtpc09_dat_bank_set dat:%02X Logical address:%04X Physical address:%05X\n", data, offset << 12, physical_address )); + + + // unmap page to be changed + mem.unmap_readwrite(offset << 12, (offset << 12)+0x0fff); + + // map in new page + if (a12_to_a15 == 0x0e) // 0xE000 address range to be mapped in at this page + { + if (m_system_type == FLEX_DMF2) // if flex/sbug, map in acia at 0xE004 + { + mem.nop_readwrite(logical_address+0x000, logical_address+0x003); + mem.install_readwrite_handler(logical_address+0x004, logical_address+0x004, read8_delegate(FUNC(acia6850_device::status_r), acia), write8_delegate(FUNC(acia6850_device::control_w),acia)); + mem.install_readwrite_handler(logical_address+0x005, logical_address+0x005, read8_delegate(FUNC(acia6850_device::data_r), acia), write8_delegate(FUNC(acia6850_device::data_w),acia)); + mem.nop_readwrite(logical_address+0x006, logical_address+0x07f); + mem.install_readwrite_handler(logical_address+0x080, logical_address+0x08f, read8_delegate(FUNC(pia6821_device::read), pia), write8_delegate(FUNC(pia6821_device::write), pia)); + mem.install_readwrite_handler(logical_address+0x090, logical_address+0x09f, read8_delegate(FUNC(ptm6840_device::read), ptm), write8_delegate(FUNC(ptm6840_device::write), ptm)); + mem.nop_readwrite(logical_address+0x0a0, logical_address+0xfff); + } + else if (m_system_type == FLEX_DC4_PIAIDE) // if flex/sbug and dc4 and piaide + { + mem.nop_readwrite(logical_address+0x000, logical_address+0x003); + mem.install_readwrite_handler(logical_address+0x004, logical_address+0x004, read8_delegate(FUNC(acia6850_device::status_r), acia), write8_delegate(FUNC(acia6850_device::control_w),acia)); + mem.install_readwrite_handler(logical_address+0x005, logical_address+0x005, read8_delegate(FUNC(acia6850_device::data_r), acia), write8_delegate(FUNC(acia6850_device::data_w),acia)); + mem.install_write_handler(logical_address+0x014, logical_address+0x014, write8_delegate(FUNC(swtpc09_state::dc4_control_reg_w),this)); + mem.install_readwrite_handler(logical_address+0x018, logical_address+0x01b, read8_delegate(FUNC(fd1793_device::read), fdc), write8_delegate(FUNC(fd1793_device::write),fdc)); + //mem.nop_readwrite(logical_address+0x01c, logical_address+0x05f); + mem.install_readwrite_handler(logical_address+0x060, logical_address+0x06f, read8_delegate(FUNC(pia6821_device::read), piaide), write8_delegate(FUNC(pia6821_device::write), piaide)); + //mem.nop_readwrite(logical_address+0x070, logical_address+0x07f); + mem.install_readwrite_handler(logical_address+0x080, logical_address+0x08f, read8_delegate(FUNC(pia6821_device::read), pia), write8_delegate(FUNC(pia6821_device::write), pia)); + mem.install_readwrite_handler(logical_address+0x090, logical_address+0x09f, read8_delegate(FUNC(ptm6840_device::read), ptm), write8_delegate(FUNC(ptm6840_device::write), ptm)); + //mem.nop_readwrite(logical_address+0x0a0, logical_address+0x7ff); + mem.install_rom(logical_address+0x800, logical_address+0xfff, &RAM[0xe800]); //piaide rom + } + else // assume unibug, map in acia at 0xE000 + { + mem.install_readwrite_handler(logical_address+0x000, logical_address+0x000, read8_delegate(FUNC(acia6850_device::status_r), acia), write8_delegate(FUNC(acia6850_device::control_w), acia)); + mem.install_readwrite_handler(logical_address+0x001, logical_address+0x001, read8_delegate(FUNC(acia6850_device::data_r), acia), write8_delegate(FUNC(acia6850_device::data_w), acia)); + mem.nop_readwrite(logical_address+0x002, logical_address+0x07f); + mem.install_readwrite_handler(logical_address+0x080, logical_address+0x08f, read8_delegate(FUNC(pia6821_device::read), pia), write8_delegate(FUNC(pia6821_device::write), pia)); + mem.install_readwrite_handler(logical_address+0x090, logical_address+0x09f, read8_delegate(FUNC(ptm6840_device::read), ptm), write8_delegate(FUNC(ptm6840_device::write), ptm)); + mem.nop_readwrite(logical_address+0x0a0, logical_address+0xfff); + } + } + else if (a12_to_a15 == 0x0f) // 0xF000 address range to be mapped in at this page + { + if (m_system_type == UNIFLEX_DMF2 || m_system_type == FLEX_DMF2) // if DMF2 conroller this is the map + { + mem.install_legacy_readwrite_handler(logical_address+0x000, logical_address+0x01f, FUNC(m6844_r), FUNC(m6844_w)); + mem.install_readwrite_handler(logical_address+0x020, logical_address+0x023, read8_delegate(FUNC(fd1793_device::read), fdc), write8_delegate(FUNC(fd1793_device::write),fdc)); + mem.install_readwrite_handler(logical_address+0x024, logical_address+0x03f, read8_delegate(FUNC(swtpc09_state::dmf2_control_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_control_reg_w),this)); + mem.install_readwrite_handler(logical_address+0x040, logical_address+0x041, read8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_w),this)); + //mem.nop_readwrite(logical_address+0x042, logical_address+0x7ff); + mem.install_rom(logical_address+0x800, logical_address+0xfff, &RAM[0xf800]); + mem.install_write_handler(logical_address+0xff0, logical_address+0xfff, write8_delegate(FUNC(swtpc09_state::dat_w),this)); + } + else if (m_system_type == FLEX_DC4_PIAIDE) // 2k ram for piaide on s09 board + { + //mem.install_legacy_readwrite_handler(logical_address+0x000, logical_address+0x01f, FUNC(m6844_r), FUNC(m6844_w)); + //mem.install_legacy_readwrite_handler(*fdc, logical_address+0x020, logical_address+0x023, 0, 0, FUNC(wd17xx_r), FUNC(wd17xx_w)); + //mem.install_readwrite_handler(logical_address+0x024, logical_address+0x03f, read8_delegate(FUNC(swtpc09_state::dmf2_control_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_control_reg_w),this)); + //mem.install_readwrite_handler(logical_address+0x040, logical_address+0x041, read8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_w),this)); + mem.install_ram(logical_address+0x000, logical_address+0x7ff, &RAM[0xf000]); + mem.install_rom(logical_address+0x800, logical_address+0xfff, &RAM[0xf800]); + mem.install_write_handler(logical_address+0xff0, logical_address+0xfff, write8_delegate(FUNC(swtpc09_state::dat_w),this)); + } + else // assume DMF3 controller + { + mem.install_legacy_readwrite_handler(logical_address+0x000, logical_address+0x01f, FUNC(m6844_r), FUNC(m6844_w)); + mem.install_readwrite_handler(logical_address+0x020, logical_address+0x023, read8_delegate(FUNC(fd1793_device::read), fdc), write8_delegate(FUNC(fd1793_device::write),fdc)); + mem.install_readwrite_handler(logical_address+0x024, logical_address+0x024, read8_delegate(FUNC(swtpc09_state::dmf3_control_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf3_control_reg_w),this)); + mem.install_readwrite_handler(logical_address+0x025, logical_address+0x025, read8_delegate(FUNC(swtpc09_state::dmf3_dma_address_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf3_dma_address_reg_w),this)); + //mem.nop_readwrite(logical_address+0x030, logical_address+0x03f); + mem.install_readwrite_handler(logical_address+0x040, logical_address+0x04f, read8_delegate(FUNC(via6522_device::read), via), write8_delegate(FUNC(via6522_device::write), via)); + //mem.nop_readwrite(logical_address+0x050, logical_address+0x7ff); + mem.install_rom(logical_address+0x800, logical_address+0xfff, &RAM[0xf800]); + mem.install_write_handler(logical_address+0xff0, logical_address+0xfff, write8_delegate(FUNC(swtpc09_state::dat_w),this)); + } + } + else if (offset==0x0f) // then we need to leave in top part of ram and dat write + { + mem.install_ram(logical_address, logical_address+0x0eff, 0, 0, &RAM[physical_address]); + mem.install_rom(logical_address+0xf00, logical_address+0xfff, 0, 0, &RAM[0xff00]); + mem.install_write_handler(logical_address+0xff0, logical_address+0xfff, write8_delegate(FUNC(swtpc09_state::dat_w),this)); + + } + else // all the rest is treated as ram, 1MB ram emulated + { + mem.install_ram(logical_address, logical_address+0x0fff, &RAM[physical_address]); + } + +// unused code to limit to 256k ram +// else if (!(a12_to_a15 & 0x0c) ) // limit ram to 256k || a12_to_a15 == 0x02 +// { +// memory_install_ram(space, logical_address, logical_address+0x0fff, 0, 0, &RAM[physical_address]); +// } +// +// else // all the rest is treated as unallocated +// { +// memory_nop_readwrite(space, logical_address, logical_address+0x0fff, 0, 0); +// } + +} + +/* MC6844 DMA controller I/O */ + +READ8_HANDLER( m6844_r ) +{ + UINT8 result = 0; + swtpc09_state *state = space.machine().driver_data(); + + + /* switch off the offset we were given */ + switch (offset) + { + /* upper byte of address */ + case 0x00: + case 0x04: + case 0x08: + case 0x0c: + result = m6844_channel[offset / 4].address >> 8; + break; + + /* lower byte of address */ + case 0x01: + case 0x05: + case 0x09: + case 0x0d: + result = m6844_channel[offset / 4].address & 0xff; + break; + + /* upper byte of counter */ + case 0x02: + case 0x06: + case 0x0a: + case 0x0e: + result = m6844_channel[offset / 4].counter >> 8; + break; + + /* lower byte of counter */ + case 0x03: + case 0x07: + case 0x0b: + case 0x0f: + result = m6844_channel[offset / 4].counter & 0xff; + break; + + /* channel control */ + case 0x10: + case 0x11: + case 0x12: + case 0x13: + result = m6844_channel[offset - 0x10].control; + + /* a read here clears the DMA end flag */ + m6844_channel[offset - 0x10].control &= ~0x80; + if (m6844_interrupt && 0x80) // if interrupt is active, then clear + { + state->swtpc09_irq_handler(0x01, CLEAR_LINE); + m6844_interrupt &= 0x7f; // clear interrupt indication bit 7 + LOG(("swtpc09_6844_r interrupt cleared \n")); + } + break; + + /* priority control */ + case 0x14: + result = m6844_priority; + break; + + /* interrupt control */ + case 0x15: + result = m6844_interrupt; + break; + + /* chaining control */ + case 0x16: + result = m6844_chain; + break; + + /* 0x17-0x1f not used */ + default: break; + } + //LOG(("swtpc09_6844_r %02X %02X\n", offset, result & 0xff)); + + if (state->m_system_type == UNIFLEX_DMF2 || state->m_system_type == FLEX_DMF2) // if DMF2 controller data bus is inverted to 6844 + { + return ~result & 0xff; + } + else + { + return result & 0xff; + } +} + + +WRITE8_HANDLER( m6844_w ) +{ + int i; + swtpc09_state *state = space.machine().driver_data(); + + if (state->m_system_type == UNIFLEX_DMF2 || state->m_system_type == FLEX_DMF2) // if DMF2 controller data bus is inverted to 6844 + data = ~data & 0xff; + + LOG(("swtpc09_6844_w %02X %02X\n", offset, data)); + /* switch off the offset we were given */ + switch (offset) + { + /* upper byte of address */ + case 0x00: + case 0x04: + case 0x08: + case 0x0c: + m6844_channel[offset / 4].address = (m6844_channel[offset / 4].address & 0xff) | (data << 8); + break; + + /* lower byte of address */ + case 0x01: + case 0x05: + case 0x09: + case 0x0d: + m6844_channel[offset / 4].address = (m6844_channel[offset / 4].address & 0xff00) | (data & 0xff); + break; + + /* upper byte of counter */ + case 0x02: + case 0x06: + case 0x0a: + case 0x0e: + m6844_channel[offset / 4].counter = (m6844_channel[offset / 4].counter & 0xff) | (data << 8); + break; + + /* lower byte of counter */ + case 0x03: + case 0x07: + case 0x0b: + case 0x0f: + m6844_channel[offset / 4].counter = (m6844_channel[offset / 4].counter & 0xff00) | (data & 0xff); + break; + + /* channel control */ + case 0x10: + case 0x11: + case 0x12: + case 0x13: + m6844_channel[offset - 0x10].control = (m6844_channel[offset - 0x10].control & 0xc0) | (data & 0x3f); + break; + + /* priority control */ + case 0x14: + m6844_priority = data; + + /* update each channel */ + for (i = 0; i < 4; i++) + { + /* if we're going active... */ + if (!m6844_channel[i].active && (data & (1 << i))) + { + /* mark us active */ + m6844_channel[i].active = 1; + LOG(("swtpc09_dma_channel active %02X\n", i)); + + /* set the DMA busy bit and clear the DMA end bit */ + m6844_channel[i].control |= 0x40; + m6844_channel[i].control &= ~0x80; + + /* set the starting address, counter, and time */ + m6844_channel[i].start_address = m6844_channel[i].address; + m6844_channel[i].start_counter = m6844_channel[i].counter; + + + /* generate and play the sample */ + //play_cvsd(space->machine, i); + } + + /* if we're going inactive... */ + else if (m6844_channel[i].active && !(data & (1 << i))) + { + /* mark us inactive */ + m6844_channel[i].active = 0; + } + } + break; + + /* interrupt control */ + case 0x15: + m6844_interrupt = (m6844_interrupt & 0x80) | (data & 0x7f); + LOG(("swtpc09_m6844_interrupt_w %02X\n", m6844_interrupt)); + break; + + /* chaining control */ + case 0x16: + m6844_chain = data; + break; + + /* 0x17-0x1f not used */ + default: break; + } +} + + +DRIVER_INIT_MEMBER( swtpc09_state, swtpc09 ) +{ + int i; + m_pia_counter = 0; // init ptm/pia counter to 0 + m_term_data = 0; // terminal keyboard input + m_fdc_status = 0; // for floppy controller + m_system_type = FLEX_DMF2; + m_interrupt = 0; + m_active_interrupt = FALSE; + + /* reset the 6844 */ + for (i = 0; i < 4; i++) + { + m6844_channel[i].active = 0; + m6844_channel[i].control = 0x00; + } + m6844_priority = 0x00; + m6844_interrupt = 0x00; + m6844_chain = 0x00; + +} + +DRIVER_INIT_MEMBER( swtpc09_state, swtpc09i ) +{ + int i; + m_pia_counter = 0; // init ptm/pia counter to 0 + m_term_data = 0; // terminal keyboard input + m_fdc_status = 0; // for floppy controller + m_system_type = FLEX_DC4_PIAIDE; + m_interrupt = 0; + m_active_interrupt = FALSE; + + /* reset the 6844 */ + for (i = 0; i < 4; i++) + { + m6844_channel[i].active = 0; + m6844_channel[i].control = 0x00; + } + m6844_priority = 0x00; + m6844_interrupt = 0x00; + m6844_chain = 0x00; + +} + +DRIVER_INIT_MEMBER( swtpc09_state, swtpc09u ) +{ + int i; + m_pia_counter = 0; //init ptm/pia counter to 0 + m_term_data = 0; //terminal keyboard input + m_fdc_status = 0; // for floppy controller + m_system_type = UNIFLEX_DMF2; + m_interrupt = 0; + m_active_interrupt = FALSE; + + /* reset the 6844 */ + for (i = 0; i < 4; i++) + { + m6844_channel[i].active = 0; + m6844_channel[i].control = 0x00; + } + m6844_priority = 0x00; + m6844_interrupt = 0x00; + m6844_chain = 0x00; + +} + +DRIVER_INIT_MEMBER( swtpc09_state, swtpc09d3 ) +{ + int i; + m_pia_counter = 0; //init ptm/pia counter to 0 + m_term_data = 0; //terminal keyboard input + m_fdc_status = 0; // for floppy controller + m_via_ca1_input = 0; + m_system_type = UNIFLEX_DMF3; + m_interrupt = 0; + m_active_interrupt = FALSE; + + + /* reset the 6844 */ + for (i = 0; i < 4; i++) + { + m6844_channel[i].active = 0; + m6844_channel[i].control = 0x00; + } + m6844_priority = 0x00; + m6844_interrupt = 0x00; + m6844_chain = 0x00; + +} diff --git a/src/mess/mess.lst b/src/mess/mess.lst index 712e3940f3a..4d04ab39c68 100644 --- a/src/mess/mess.lst +++ b/src/mess/mess.lst @@ -1876,6 +1876,13 @@ prof80 prof180x prof181x +// SWTPC S/09 +swtpc09 // S09, DMF2 Floppy SBUG rom - FLEX +swtpc09i // S09, DC4 Floppy + PIA IDE SBUG rom - FLEX +swtpc09u // S09, DMF2 Floppy UNIBUG rom - UniFLEX +swtpc09d3 // S09, DMF3 Floppy UNIBUG U3 rom - UniFLEX U3 + + //***************Games****************************************************** // Computer Electronic ccmk1 // Chess Champion MK I diff --git a/src/mess/mess.mak b/src/mess/mess.mak index 2a2a6ba074e..cb4a2f5205d 100644 --- a/src/mess/mess.mak +++ b/src/mess/mess.mak @@ -728,6 +728,7 @@ DRVLIBS += \ $(MESSOBJ)/sun.a \ $(MESSOBJ)/svi.a \ $(MESSOBJ)/svision.a \ + $(MESSOBJ)/swtpc09.a \ $(MESSOBJ)/synertec.a \ $(MESSOBJ)/ta.a \ $(MESSOBJ)/tandberg.a \ @@ -1773,6 +1774,10 @@ $(MESSOBJ)/svision.a: \ $(MESS_DRIVERS)/svision.o \ $(MESS_AUDIO)/svision.o \ +$(MESSOBJ)/swtpc09.a: \ + $(MESS_DRIVERS)/swtpc09.o \ + $(MESS_MACHINE)/swtpc09.o \ + $(MESSOBJ)/synertec.a: \ $(MESS_DRIVERS)/sym1.o \