summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/swtpc09.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/swtpc09.c')
-rw-r--r--src/mame/machine/swtpc09.c859
1 files changed, 859 insertions, 0 deletions
diff --git a/src/mame/machine/swtpc09.c b/src/mame/machine/swtpc09.c
new file mode 100644
index 00000000000..29bae501462
--- /dev/null
+++ b/src/mame/machine/swtpc09.c
@@ -0,0 +1,859 @@
+// license:BSD-3-Clause
+// copyright-holders:Robert Justice
+/***************************************************************************
+ 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)
+
+
+/******* MC6840 PTM on MPID Board *******/
+
+/* 6840 PTM handlers */
+WRITE8_MEMBER( swtpc09_state::ptm_o1_callback )
+{
+ pia6821_device *pia = machine().device<pia6821_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<ptm6840_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<pia6821_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));
+
+ floppy_image_device *floppy = NULL;
+
+ if (!BIT(data, 0)) floppy = m_floppy0->get_device();
+ if (!BIT(data, 1)) floppy = m_floppy1->get_device();
+ if (!BIT(data, 2)) floppy = m_floppy2->get_device();
+ if (!BIT(data, 3)) floppy = m_floppy3->get_device();
+
+ m_fdc->set_floppy(floppy);
+
+ if (floppy)
+ {
+ floppy->mon_w(0);
+ floppy->ss_w(!BIT(data, 4));
+ }
+
+ m_fdc->dden_w(!BIT(data, 5));
+}
+
+/* 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 (m_m6844_channel[0].active == 1) //active dma transfer
+ {
+ if (!(m_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", m_m6844_channel[0].address + offset, data));
+ RAM[m_m6844_channel[0].address + offset] = data;
+ }
+ else
+ {
+ UINT8 data = RAM[m_m6844_channel[0].address + offset];
+
+ m_fdc->data_w(space, 0, data);
+ //LOG(("swtpc09_dma_read_mem %04X %02X\n", m_m6844_channel[0].address, data));
+ }
+
+ m_m6844_channel[0].address++;
+ m_m6844_channel[0].counter--;
+
+ if (m_m6844_channel[0].counter == 0) // dma transfer has finished
+ {
+ m_m6844_channel[0].control |= 0x80; // set dend flag
+ if (m_m6844_interrupt & 0x01) // interrupt for channel 0 is enabled?
+ {
+ m_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;
+ }
+}
+
+/* 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));
+
+ floppy_image_device *floppy = NULL;
+
+ if (BIT(data, 0)) floppy = m_floppy0->get_device();
+ if (BIT(data, 1)) floppy = m_floppy1->get_device();
+ if (BIT(data, 2)) floppy = m_floppy2->get_device();
+ if (BIT(data, 3)) floppy = m_floppy3->get_device();
+
+ m_fdc->set_floppy(floppy);
+
+ if (floppy)
+ {
+ floppy->mon_w(0);
+ floppy->ss_w(BIT(data, 4));
+ }
+
+ m_fdc->dden_w(BIT(data, 5));
+}
+
+// DC4 drive select
+
+WRITE8_MEMBER ( swtpc09_state::dc4_control_reg_w )
+{
+ LOG(("swtpc09_dc4_control_reg_w $%02X\n", data));
+
+ floppy_image_device *floppy = NULL;
+
+ if (BIT(data, 0)) floppy = m_floppy0->get_device();
+ if (BIT(data, 1)) floppy = m_floppy1->get_device();
+ if (BIT(data, 2)) floppy = m_floppy2->get_device();
+ if (BIT(data, 3)) floppy = m_floppy3->get_device();
+
+ m_fdc->set_floppy(floppy);
+}
+
+
+/******* 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 accommodate 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_t *fdc = machine().device<fd1793_t>("fdc");
+ pia6821_device *pia = machine().device<pia6821_device>("pia");
+ ptm6840_device *ptm = machine().device<ptm6840_device>("ptm");
+ acia6850_device *acia = machine().device<acia6850_device>("acia");
+ via6522_device *via = machine().device<via6522_device>("via");
+ pia6821_device *piaide = machine().device<pia6821_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_t::read), fdc), write8_delegate(FUNC(fd1793_t::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_readwrite_handler(logical_address+0x000, logical_address+0x01f, read8_delegate(FUNC(swtpc09_state::m6844_r),this), write8_delegate(FUNC(swtpc09_state::m6844_w),this));
+ mem.install_readwrite_handler(logical_address+0x020, logical_address+0x023, read8_delegate(FUNC(fd1793_t::read), fdc), write8_delegate(FUNC(fd1793_t::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_readwrite_handler(logical_address+0x000, logical_address+0x01f, read8_delegate(FUNC(swtpc09_state::m6844_r),this), write8_delegate(FUNC(swtpc09_state::m6844_w),this));
+ //mem.install_readwrite_handler(logical_address+0x020, logical_address+0x023, read8_delegate(FUNC(fd1793_t::read), fdc), write8_delegate(FUNC(fd1793_t::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.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_readwrite_handler(logical_address+0x000, logical_address+0x01f, read8_delegate(FUNC(swtpc09_state::m6844_r),this), write8_delegate(FUNC(swtpc09_state::m6844_w),this));
+ mem.install_readwrite_handler(logical_address+0x020, logical_address+0x023, read8_delegate(FUNC(fd1793_t::read), fdc), write8_delegate(FUNC(fd1793_t::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_MEMBER( swtpc09_state::m6844_r )
+{
+ UINT8 result = 0;
+
+
+ /* switch off the offset we were given */
+ switch (offset)
+ {
+ /* upper byte of address */
+ case 0x00:
+ case 0x04:
+ case 0x08:
+ case 0x0c:
+ result = m_m6844_channel[offset / 4].address >> 8;
+ break;
+
+ /* lower byte of address */
+ case 0x01:
+ case 0x05:
+ case 0x09:
+ case 0x0d:
+ result = m_m6844_channel[offset / 4].address & 0xff;
+ break;
+
+ /* upper byte of counter */
+ case 0x02:
+ case 0x06:
+ case 0x0a:
+ case 0x0e:
+ result = m_m6844_channel[offset / 4].counter >> 8;
+ break;
+
+ /* lower byte of counter */
+ case 0x03:
+ case 0x07:
+ case 0x0b:
+ case 0x0f:
+ result = m_m6844_channel[offset / 4].counter & 0xff;
+ break;
+
+ /* channel control */
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ result = m_m6844_channel[offset - 0x10].control;
+
+ /* a read here clears the DMA end flag */
+ m_m6844_channel[offset - 0x10].control &= ~0x80;
+ if (m_m6844_interrupt & 0x80) // if interrupt is active, then clear
+ {
+ swtpc09_irq_handler(0x01, CLEAR_LINE);
+ m_m6844_interrupt &= 0x7f; // clear interrupt indication bit 7
+ LOG(("swtpc09_6844_r interrupt cleared \n"));
+ }
+ break;
+
+ /* priority control */
+ case 0x14:
+ result = m_m6844_priority;
+ break;
+
+ /* interrupt control */
+ case 0x15:
+ result = m_m6844_interrupt;
+ break;
+
+ /* chaining control */
+ case 0x16:
+ result = m_m6844_chain;
+ break;
+
+ /* 0x17-0x1f not used */
+ default: break;
+ }
+ //LOG(("swtpc09_6844_r %02X %02X\n", offset, result & 0xff));
+
+ if (m_system_type == UNIFLEX_DMF2 || m_system_type == FLEX_DMF2) // if DMF2 controller data bus is inverted to 6844
+ {
+ return ~result & 0xff;
+ }
+ else
+ {
+ return result & 0xff;
+ }
+}
+
+
+WRITE8_MEMBER( swtpc09_state::m6844_w )
+{
+ int i;
+
+ if (m_system_type == UNIFLEX_DMF2 || 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:
+ m_m6844_channel[offset / 4].address = (m_m6844_channel[offset / 4].address & 0xff) | (data << 8);
+ break;
+
+ /* lower byte of address */
+ case 0x01:
+ case 0x05:
+ case 0x09:
+ case 0x0d:
+ m_m6844_channel[offset / 4].address = (m_m6844_channel[offset / 4].address & 0xff00) | (data & 0xff);
+ break;
+
+ /* upper byte of counter */
+ case 0x02:
+ case 0x06:
+ case 0x0a:
+ case 0x0e:
+ m_m6844_channel[offset / 4].counter = (m_m6844_channel[offset / 4].counter & 0xff) | (data << 8);
+ break;
+
+ /* lower byte of counter */
+ case 0x03:
+ case 0x07:
+ case 0x0b:
+ case 0x0f:
+ m_m6844_channel[offset / 4].counter = (m_m6844_channel[offset / 4].counter & 0xff00) | (data & 0xff);
+ break;
+
+ /* channel control */
+ case 0x10:
+ case 0x11:
+ case 0x12:
+ case 0x13:
+ m_m6844_channel[offset - 0x10].control = (m_m6844_channel[offset - 0x10].control & 0xc0) | (data & 0x3f);
+ break;
+
+ /* priority control */
+ case 0x14:
+ m_m6844_priority = data;
+
+ /* update each channel */
+ for (i = 0; i < 4; i++)
+ {
+ /* if we're going active... */
+ if (!m_m6844_channel[i].active && (data & (1 << i)))
+ {
+ /* mark us active */
+ m_m6844_channel[i].active = 1;
+ LOG(("swtpc09_dma_channel active %02X\n", i));
+
+ /* set the DMA busy bit and clear the DMA end bit */
+ m_m6844_channel[i].control |= 0x40;
+ m_m6844_channel[i].control &= ~0x80;
+
+ /* set the starting address, counter, and time */
+ m_m6844_channel[i].start_address = m_m6844_channel[i].address;
+ m_m6844_channel[i].start_counter = m_m6844_channel[i].counter;
+
+
+ /* generate and play the sample */
+ //play_cvsd(space->machine, i);
+ }
+
+ /* if we're going inactive... */
+ else if (m_m6844_channel[i].active && !(data & (1 << i)))
+ {
+ /* mark us inactive */
+ m_m6844_channel[i].active = 0;
+ }
+ }
+ break;
+
+ /* interrupt control */
+ case 0x15:
+ m_m6844_interrupt = (m_m6844_interrupt & 0x80) | (data & 0x7f);
+ LOG(("swtpc09_m_m6844_interrupt_w %02X\n", m_m6844_interrupt));
+ break;
+
+ /* chaining control */
+ case 0x16:
+ m_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++)
+ {
+ m_m6844_channel[i].active = 0;
+ m_m6844_channel[i].control = 0x00;
+ }
+ m_m6844_priority = 0x00;
+ m_m6844_interrupt = 0x00;
+ m_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++)
+ {
+ m_m6844_channel[i].active = 0;
+ m_m6844_channel[i].control = 0x00;
+ }
+ m_m6844_priority = 0x00;
+ m_m6844_interrupt = 0x00;
+ m_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++)
+ {
+ m_m6844_channel[i].active = 0;
+ m_m6844_channel[i].control = 0x00;
+ }
+ m_m6844_priority = 0x00;
+ m_m6844_interrupt = 0x00;
+ m_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++)
+ {
+ m_m6844_channel[i].active = 0;
+ m_m6844_channel[i].control = 0x00;
+ }
+ m_m6844_priority = 0x00;
+ m_m6844_interrupt = 0x00;
+ m_m6844_chain = 0x00;
+
+}