/*************************************************************************** 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 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 machine().device("floppy0")->floppy_drive_set_ready_state(1,0); break; case 0x0d: m_fdc->set_drive(1); machine().device("floppy1")->floppy_drive_set_ready_state(1,0); break; case 0x0b: m_fdc->set_drive(2); machine().device("floppy2")->floppy_drive_set_ready_state(1,0); break; case 0x07: m_fdc->set_drive(3); machine().device("floppy3")->floppy_drive_set_ready_state(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 (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; } } /******* 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 machine().device("floppy0")->floppy_drive_set_ready_state(1,0); break; case 0x02: m_fdc->set_drive(1); machine().device("floppy1")->floppy_drive_set_ready_state(1,0); break; case 0x04: m_fdc->set_drive(2); machine().device("floppy2")->floppy_drive_set_ready_state(1,0); break; case 0x08: m_fdc->set_drive(3); machine().device("floppy3")->floppy_drive_set_ready_state(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 machine().device("floppy0")->floppy_drive_set_ready_state(1,0); break; case 0x01: m_fdc->set_drive(1); machine().device("floppy1")->floppy_drive_set_ready_state(1,0); break; case 0x02: m_fdc->set_drive(2); machine().device("floppy2")->floppy_drive_set_ready_state(1,0); break; case 0x03: m_fdc->set_drive(3); machine().device("floppy3")->floppy_drive_set_ready_state(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_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_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_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_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.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_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_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; }