diff options
Diffstat (limited to 'src/mame/machine/swtpc09.cpp')
-rw-r--r-- | src/mame/machine/swtpc09.cpp | 530 |
1 files changed, 341 insertions, 189 deletions
diff --git a/src/mame/machine/swtpc09.cpp b/src/mame/machine/swtpc09.cpp index 64ddd7703aa..2f6643e4878 100644 --- a/src/mame/machine/swtpc09.cpp +++ b/src/mame/machine/swtpc09.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Robert Justice +// copyright-holders:Robert Justice,68bit /*************************************************************************** swtpc09 machine file Robert Justice ,2009-2014 @@ -10,21 +10,38 @@ #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 IO_IRQ 0x40 -#define FLEX_DMF2 1 // system type flags -#define UNIFLEX_DMF2 2 -#define UNIFLEX_DMF3 3 -#define FLEX_DC4_PIAIDE 4 +#define FLEX_DMAF2 1 // system type flags +#define UNIFLEX_DMAF2 2 +#define UNIFLEX_DMAF3 3 +#define FLEX_DC5_PIAIDE 4 -#define VERBOSE 0 -#define LOG(x) do { if (VERBOSE) logerror x; } while (0) +READ8_MEMBER(swtpc09_state::unmapped_r) +{ + if (!machine().side_effects_disabled()) { + logerror("%s Unmapped read from addr %04x\n", machine().describe_context(), offset); + } + return 0; +} +WRITE8_MEMBER(swtpc09_state::unmapped_w) +{ + logerror("%s Unmapped write to addr %04x with data %02x\n", machine().describe_context(), offset, data); +} + +WRITE_LINE_MEMBER(swtpc09_state::io_irq_w) +{ + if (state) + swtpc09_irq_handler(IO_IRQ, ASSERT_LINE); + else + swtpc09_irq_handler(IO_IRQ, CLEAR_LINE); +} /******* MC6840 PTM on MPID Board *******/ @@ -72,70 +89,203 @@ WRITE_LINE_MEMBER( swtpc09_state::pia0_irq_a ) } -/******* MC6850 ACIA on MPS2 *******/ +/* Shared floppy support. */ -WRITE_LINE_MEMBER( swtpc09_state::acia_interrupt ) +void swtpc09_state::floppy_motor_trigger() { - if (state) + m_floppy0->get_device()->mon_w(CLEAR_LINE); + m_floppy1->get_device()->mon_w(CLEAR_LINE); + m_floppy2->get_device()->mon_w(CLEAR_LINE); + m_floppy3->get_device()->mon_w(CLEAR_LINE); + m_floppy_motor_timer->adjust(attotime::from_msec(30000)); + m_floppy_motor_on = 1; +} + +TIMER_CALLBACK_MEMBER(swtpc09_state::floppy_motor_callback) +{ + m_floppy0->get_device()->mon_w(ASSERT_LINE); + m_floppy1->get_device()->mon_w(ASSERT_LINE); + m_floppy2->get_device()->mon_w(ASSERT_LINE); + m_floppy3->get_device()->mon_w(ASSERT_LINE); + m_floppy_motor_on = 0; +} + +// Hack On a FDC command write, check that the floppy side is as expected +// given the track and sector. This check is performed for the type II and III +// commands. The floppy side is modified if necessary. +void swtpc09_state::validate_floppy_side(uint8_t cmd) +{ + if ((cmd & 0xe1) == 0x80 || (cmd & 0xe0) == 0xa0 || + (cmd & 0xf9) == 0xc0 || (cmd & 0xf9) == 0xe0 || + (cmd & 0xf9) == 0xf0) { - swtpc09_irq_handler(ACIA_IRQ, ASSERT_LINE); - logerror("swtpc09_acia_irq_assert\n"); + uint32_t expected_sectors = m_floppy_expected_sectors->read(); + uint32_t track_zero_expected_sectors = m_floppy_track_zero_expected_sectors->read(); + uint8_t sector = m_fdc->sector_r(); + uint8_t track = m_fdc->track_r(); + + if (track_zero_expected_sectors && track == 0) + { + uint8_t expected_side = sector > track_zero_expected_sectors ? 1 : 0; + + if (m_fdc_side != expected_side) + { + logerror("%s Unexpected size %d for track %d sector %d expected side %d\n", machine().describe_context(), m_fdc_side, track, sector, expected_side); + if (m_fdc_floppy) + { + m_fdc_floppy->ss_w(expected_side); + m_fdc_side = expected_side; + } + } + } + + if (expected_sectors) + { + uint8_t expected_side = sector > expected_sectors ? 1 : 0; + + if (m_fdc_side != expected_side) + { + logerror("%s Unexpected side %d for track %d sector %d expected side %d\n", machine().describe_context(), m_fdc_side, track, sector, expected_side); + if (m_fdc_floppy) + { + m_fdc_floppy->ss_w(expected_side); + m_fdc_side = expected_side; + } + } + } } - else +} + +// Note the dden line is low for double density. +uint8_t swtpc09_state::validate_fdc_dden(uint8_t dden) +{ + uint8_t expected_density = m_floppy_expected_density->read(); + switch (expected_density) { - swtpc09_irq_handler(ACIA_IRQ, CLEAR_LINE); - logerror("swtpc09_acia_irq_clear\n"); + case 1: + // Single density. + if (!dden) + logerror("%s Unexpected DDEN %d for single density\n", machine().describe_context(), dden); + return 1; + case 2: + { + // Double density with track zero single density. + uint8_t track = m_fdc->track_r(); + + if (track == 0) + { + if (!dden) + logerror("%s Unexpected DDEN %d for single density trak 0\n", machine().describe_context(), dden); + return 1; + } + if (dden) + logerror("%s Unexpected DDEN %d for double density\n", machine().describe_context(), dden); + return 0; + } + case 3: + // Pure double density. + if (dden) + logerror("%s Unexpected DDEN %d for double density\n", machine().describe_context(), dden); + return 0; + default: + return dden; } } +// The WD2797 supports an alternate interpretation of the sector size. Check +// that the flag is as expected and return the corrected command if necessary. +uint8_t swtpc09_state::validate_fdc_sector_size(uint8_t cmd) +{ + if ((cmd & 0xe1) == 0x80 || (cmd & 0xe0) == 0xa0) + { + // Check that the sector length flag is set as expected. + uint8_t sector_length_default = cmd & 0x08; + if (sector_length_default != 0x08) + { + logerror("%s Unexpected sector length default %02x\n", machine().describe_context(), sector_length_default); + // Patch the sector length flag. + cmd |= 0x08; + } + } + return cmd; +} + /*********************************************************************/ -/* DMF2 Floppy Controller Board */ +/* DMAF2 Floppy Controller Board */ /*********************************************************************/ -/* DMF2 dma extended address register */ -READ8_MEMBER ( swtpc09_state::dmf2_dma_address_reg_r ) +READ8_MEMBER( swtpc09_state::dmaf2_fdc_r ) +{ + // TODO Does access to the dmaf2 fdc also trigger the motor timer? + if (!machine().side_effects_disabled()) + floppy_motor_trigger(); + return m_fdc->fd1797_device::read(offset); +} + +WRITE8_MEMBER ( swtpc09_state::dmaf2_fdc_w ) +{ + // TODO Does access to the dmaf2 fdc also trigger the motor timer. + floppy_motor_trigger(); + + // TODO how does the DMAF2 use the FDC SSO output? + + if (offset == 0) { + validate_floppy_side(data); + data = validate_fdc_sector_size(data); + } + + m_fdc->fd1797_device::write(offset, data); +} + +/* DMAF2 dma extended address register */ +READ8_MEMBER ( swtpc09_state::dmaf2_dma_address_reg_r ) { return m_fdc_dma_address_reg; } -WRITE8_MEMBER ( swtpc09_state::dmf2_dma_address_reg_w ) +WRITE8_MEMBER ( swtpc09_state::dmaf2_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)) + // bit 4 controls a gate enable/disable for DMAF2 fdc irq line + if ((m_fdc_dma_address_reg & 0x10) && (m_system_type == UNIFLEX_DMAF2 || m_system_type == FLEX_DMAF2)) swtpc09_irq_handler(FDC_IRQ, CLEAR_LINE); //then clear the irq to cpu - - logerror("swtpc09_dmf2_dma_address_reg_w %02X\n", data); } -/* DMF2 fdc control register */ -READ8_MEMBER ( swtpc09_state::dmf2_control_reg_r ) +/* DMAF2 fdc control register */ +READ8_MEMBER ( swtpc09_state::dmaf2_control_reg_r ) { - //logerror("swtpc09_dmf2_control_reg_r $%02X\n", m_fdc_status); return m_fdc_status; } -WRITE8_MEMBER ( swtpc09_state::dmf2_control_reg_w ) +WRITE8_MEMBER ( swtpc09_state::dmaf2_control_reg_w ) { - logerror("swtpc09_dmf2_control_reg_w $%02X\n", data); - floppy_image_device *floppy = nullptr; + // TODO what to do if multiple drives are selected? + if (!BIT(data, 0) + !BIT(data, 1) + !BIT(data, 2) + !BIT(data, 3) > 1) + { + logerror("%s Unexpected DMAF2 has multiple drives selected: %d %d %d %d\n", machine().describe_context(), !BIT(data, 0), !BIT(data, 1), !BIT(data, 2), !BIT(data, 3)); + } + 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); + m_fdc_floppy = floppy; if (floppy) { - floppy->mon_w(0); - floppy->ss_w(!BIT(data, 4)); + uint8_t side = !BIT(data, 4); + floppy->ss_w(side); + m_fdc_side = side; } - m_fdc->dden_w(!BIT(data, 5)); + uint8_t dden = !BIT(data, 5); + dden = validate_fdc_dden(dden); + m_fdc->dden_w(dden); } /* FDC controller dma transfer */ @@ -152,7 +302,6 @@ void swtpc09_state::swtpc09_fdc_dma_transfer() { uint8_t data = m_fdc->data_r(); - logerror("swtpc09_dma_write_mem %05X %02X\n", m_m6844_channel[0].address + offset, data); space.write_byte(m_m6844_channel[0].address + offset, data); } else @@ -160,7 +309,6 @@ void swtpc09_state::swtpc09_fdc_dma_transfer() uint8_t data = space.read_byte(m_m6844_channel[0].address + offset); m_fdc->data_w(data); - //logerror("swtpc09_dma_read_mem %04X %02X\n", m_m6844_channel[0].address, data); } m_m6844_channel[0].address++; @@ -182,8 +330,6 @@ void swtpc09_state::swtpc09_fdc_dma_transfer() /* common interrupt handler */ void swtpc09_state::swtpc09_irq_handler(uint8_t peripheral, uint8_t state) { - logerror("swtpc09_irq_handler peripheral:%02X state:%02X\n", peripheral, state); - switch (state) { case ASSERT_LINE: @@ -191,20 +337,18 @@ void swtpc09_state::swtpc09_irq_handler(uint8_t peripheral, uint8_t state) break; case CLEAR_LINE: - m_interrupt &= (~peripheral & 0x3f); + m_interrupt &= (~peripheral & 0x7f); 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_maincpu->set_input_line(M6809_IRQ_LINE, ASSERT_LINE); m_active_interrupt=true; - logerror("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); - logerror("swtpc09_irq_clear %02X\n", peripheral); + m_maincpu->set_input_line(M6809_IRQ_LINE, CLEAR_LINE); m_active_interrupt=false; } } @@ -212,54 +356,40 @@ void swtpc09_state::swtpc09_irq_handler(uint8_t peripheral, uint8_t state) /* handlers for fdc */ WRITE_LINE_MEMBER( swtpc09_state::fdc_intrq_w ) { - logerror("swtpc09_fdc_intrq_w %02X\n", state); - if ( m_system_type == UNIFLEX_DMF3 ) //IRQ from 1791 is connect into VIA ca2 + if ( m_system_type == UNIFLEX_DMAF3 ) //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 + m_dmaf3_via_porta &= 0xfb; //clear pa3 + //m_via->write_porta(m_dmaf3_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 + m_dmaf3_via_porta |= 0x04; //and connected to PA3 + //m_via->write_porta(m_dmaf3_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 + else //for dmaf2 it is connected directly to cpu via a gate { 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 + if (!(m_fdc_dma_address_reg & 0x10)) // is dmaf2 fdc irq enabled { - logerror("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 + if (!(m_fdc_dma_address_reg & 0x10)) // is dmaf2 fdc irq enabled { - logerror("swtpc09_fdc_int ** clear\n"); swtpc09_irq_handler(FDC_IRQ, CLEAR_LINE); } } @@ -268,55 +398,69 @@ WRITE_LINE_MEMBER( swtpc09_state::fdc_intrq_w ) WRITE_LINE_MEMBER( swtpc09_state::fdc_drq_w ) { - if (m_system_type == FLEX_DC4_PIAIDE) //for dc4 no dma + if (state) { - if (state) - { - m_fdc_status |= 0x80; - } - else - m_fdc_status &= 0x7f; + m_fdc_status |= 0x80; + swtpc09_fdc_dma_transfer(); } else - { - if (state) - { - m_fdc_status |= 0x80; - swtpc09_fdc_dma_transfer(); - } - else - m_fdc_status &= 0x7f; - } + m_fdc_status &= 0x7f; +} + +WRITE_LINE_MEMBER( swtpc09_state::fdc_sso_w ) +{ + // Doese the DMAF2 or DMAF3 use the SSO output? } /*********************************************************************/ -/* DMF3 Board */ +/* DMAF3 Board */ /*********************************************************************/ -/* via on dmf3 board */ -READ8_MEMBER( swtpc09_state::dmf3_via_read_porta ) +READ8_MEMBER( swtpc09_state::dmaf3_fdc_r ) { - return m_dmf3_via_porta; + // TODO Does access to the fdc also trigger the motor timer. + if (!machine().side_effects_disabled()) + floppy_motor_trigger(); + return m_fdc->fd1797_device::read(offset); +} + +WRITE8_MEMBER ( swtpc09_state::dmaf3_fdc_w ) +{ + // TODO Does access to the fdc also trigger the motor timer. + floppy_motor_trigger(); + + if (offset == 0) { + validate_floppy_side(data); + data = validate_fdc_sector_size(data); + } + + m_fdc->fd1797_device::write(offset, data); } -READ8_MEMBER( swtpc09_state::dmf3_via_read_portb ) +/* via on dmaf3 board */ +READ8_MEMBER( swtpc09_state::dmaf3_via_read_porta ) +{ + return m_dmaf3_via_porta; +} + +READ8_MEMBER( swtpc09_state::dmaf3_via_read_portb ) { return 0xff; } -WRITE8_MEMBER( swtpc09_state::dmf3_via_write_porta ) +WRITE8_MEMBER( swtpc09_state::dmaf3_via_write_porta ) { - m_dmf3_via_porta &= data; + m_dmaf3_via_porta &= data; } -//WRITE_LINE_MEMBER( swtpc09_state::dmf3_via_write_ca1 ) +//WRITE_LINE_MEMBER( swtpc09_state::dmaf3_via_write_ca1 ) //{ // return m_via_ca1_input; -// logerror("swtpc09_dmf3_via_write_ca1 %02X\n", state); +// logerror("swtpc09_dmaf3_via_write_ca1 %02X\n", state); //} -WRITE_LINE_MEMBER( swtpc09_state::dmf3_via_irq ) +WRITE_LINE_MEMBER( swtpc09_state::dmaf3_via_irq ) { if (state) swtpc09_irq_handler(VIA_IRQ, ASSERT_LINE); @@ -324,117 +468,64 @@ WRITE_LINE_MEMBER( swtpc09_state::dmf3_via_irq ) swtpc09_irq_handler(VIA_IRQ, CLEAR_LINE); } -/* DMF3 dma extended address register */ -READ8_MEMBER ( swtpc09_state::dmf3_dma_address_reg_r ) +/* DMAF3 dma extended address register */ +READ8_MEMBER ( swtpc09_state::dmaf3_dma_address_reg_r ) { return m_fdc_dma_address_reg; } -WRITE8_MEMBER ( swtpc09_state::dmf3_dma_address_reg_w ) +WRITE8_MEMBER ( swtpc09_state::dmaf3_dma_address_reg_w ) { m_fdc_dma_address_reg = data; - logerror("swtpc09_dmf3_dma_address_reg_w %02X\n", data); } -/* DMF3 fdc control register */ -READ8_MEMBER ( swtpc09_state::dmf3_control_reg_r ) +/* DMAF3 fdc control register */ +READ8_MEMBER ( swtpc09_state::dmaf3_control_reg_r ) { - //logerror("swtpc09_dmf3_control_reg_r $%02X\n", m_fdc_status); return m_fdc_status; } -WRITE8_MEMBER ( swtpc09_state::dmf3_control_reg_w ) +WRITE8_MEMBER ( swtpc09_state::dmaf3_control_reg_w ) { - logerror("swtpc09_dmf3_control_reg_w $%02X\n", data); - floppy_image_device *floppy = nullptr; - 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) + // TODO multiple selected? + if (BIT(data, 0) + BIT(data, 1) + BIT(data, 2) + BIT(data, 3) > 1) { - floppy->mon_w(0); - floppy->ss_w(BIT(data, 4)); + logerror("%s Unexpected DMAF3 has multiple drives selected: %d %d %d %d\n", machine().describe_context(), !BIT(data, 0), !BIT(data, 1), !BIT(data, 2), !BIT(data, 3)); } - m_fdc->dden_w(BIT(data, 5)); -} - -// DC4 drive select - -WRITE8_MEMBER ( swtpc09_state::dc4_control_reg_w ) -{ - logerror("swtpc09_dc4_control_reg_w $%02X\n", data); - - floppy_image_device *floppy = nullptr; - 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); -} - + m_fdc_floppy = floppy; -/******* MC6821 PIA on IDE Board *******/ -/* Read/Write handlers for pia ide */ -/* TODO: update and finish this off */ + if (floppy) + { + uint8_t side = BIT(data, 4); + floppy->ss_w(side); + m_fdc_side = side; + } -READ8_MEMBER( swtpc09_state::piaide_a_r ) -{ - return m_piaide_porta; + uint8_t dden = BIT(data, 5); + dden = validate_fdc_dden(dden); + m_fdc->dden_w(dden); } -READ8_MEMBER( swtpc09_state::piaide_b_r ) -{ - return m_piaide_portb; -} +// DMAF3 WD1000 +// TODO. The following might help: +// http://www.bitsavers.org/pdf/westernDigital/WD100x/WD1000_OEM_Manual.pdf -WRITE8_MEMBER( swtpc09_state::piaide_a_w ) +READ8_MEMBER( swtpc09_state::dmaf3_wd_r ) { - m_piaide_porta = data; + return 0x00; } -WRITE8_MEMBER( swtpc09_state::piaide_b_w ) +WRITE8_MEMBER ( swtpc09_state::dmaf3_wd_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((data&0x1c)>>2); - logerror("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((data&0x1c)>>2, m_piaide_porta); - logerror("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((data&0x1c)>>2); - logerror("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((data&0x1c)>>2, m_piaide_porta); - logerror("swtpc09_ide_bus_w: offset $%02X data %04X\n", (data&0x1c)>>2, m_piaide_porta); - } - } } @@ -451,12 +542,26 @@ offs_t swtpc09_state::dat_translate(offs_t offset) const READ8_MEMBER(swtpc09_state::main_r) { - return m_banked_space->read_byte(dat_translate(offset)); + if (offset < 0xff00) + { + return m_banked_space->read_byte(dat_translate(offset)); + } + else + { + return m_banked_space->read_byte(offset | 0xfff00); + } } WRITE8_MEMBER(swtpc09_state::main_w) { - m_banked_space->write_byte(dat_translate(offset), data); + if (offset < 0xff00) + { + m_banked_space->write_byte(dat_translate(offset), data); + } + else + { + m_banked_space->write_byte(offset | 0xfff00, data); + } } /* MC6844 DMA controller I/O */ @@ -465,7 +570,6 @@ READ8_MEMBER( swtpc09_state::m6844_r ) { uint8_t result = 0; - /* switch off the offset we were given */ switch (offset) { @@ -509,12 +613,14 @@ READ8_MEMBER( swtpc09_state::m6844_r ) 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 + if (!machine().side_effects_disabled()) { - swtpc09_irq_handler(0x01, CLEAR_LINE); - m_m6844_interrupt &= 0x7f; // clear interrupt indication bit 7 - logerror("swtpc09_6844_r interrupt cleared \n"); + 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 + } } break; @@ -536,9 +642,8 @@ READ8_MEMBER( swtpc09_state::m6844_r ) /* 0x17-0x1f not used */ default: break; } - //logerror("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 + if (m_system_type == UNIFLEX_DMAF2 || m_system_type == FLEX_DMAF2) // if DMAF2 controller data bus is inverted to 6844 { return ~result & 0xff; } @@ -553,10 +658,9 @@ 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 + if (m_system_type == UNIFLEX_DMAF2 || m_system_type == FLEX_DMAF2) // if DMAF2 controller data bus is inverted to 6844 data = ~data & 0xff; - logerror("swtpc09_6844_w %02X %02X\n", offset, data); /* switch off the offset we were given */ switch (offset) { @@ -612,7 +716,6 @@ WRITE8_MEMBER( swtpc09_state::m6844_w ) { /* mark us active */ m_m6844_channel[i].active = 1; - logerror("swtpc09_dma_channel active %02X\n", i); /* set the DMA busy bit and clear the DMA end bit */ m_m6844_channel[i].control |= 0x40; @@ -639,7 +742,6 @@ WRITE8_MEMBER( swtpc09_state::m6844_w ) /* interrupt control */ case 0x15: m_m6844_interrupt = (m_m6844_interrupt & 0x80) | (data & 0x7f); - logerror("swtpc09_m_m6844_interrupt_w %02X\n", m_m6844_interrupt); break; /* chaining control */ @@ -652,6 +754,51 @@ WRITE8_MEMBER( swtpc09_state::m6844_w ) } } +void swtpc09_state::machine_reset() +{ + uint32_t maincpu_clock = m_maincpu_clock->read(); + m_maincpu->set_clock(maincpu_clock * 4); + + if (m_system_type == FLEX_DMAF2 || + m_system_type == UNIFLEX_DMAF2 || + m_system_type == UNIFLEX_DMAF3) + { + uint32_t fdc_clock = m_fdc_clock->read(); + m_fdc->set_unscaled_clock(fdc_clock); + } + + // Divider select X64 is the default Low baud rate setting. A High + // baud rate setting is also available that selects a X16 divider, so + // gives rate four times as high. Note the schematic appears to have + // mislabeled the this setting. + uint8_t baud_rate_high = m_baud_rate_high->read(); + m_brg->rsa_w(baud_rate_high); + m_brg->rsb_w(1); + + // Note UNIBUG has a smarter boot loader in ROM and will toggle the + // density on failure so this is not necessary for UniFLEX. + if ((m_system_type == FLEX_DMAF2 || + m_system_type == FLEX_DC5_PIAIDE) && + m_sbug_double_density->read()) + { + // Patch the boot ROM to load the boot sector in double density. + uint8_t* sbug = memregion("bankdev")->base(); + sbug[0xffaf8] = 0xfe; // 'D' DMAF2 boot path + sbug[0xffb78] = 0xfe; + sbug[0xffbe1] = 0x8e; // 'U' mini boot path + } + + if (m_system_type == FLEX_DC5_PIAIDE && + m_piaide_flex_boot_cd00->read()) + { + // Patch the PIA-IDE boot rom to use IO1 + uint8_t* rom = memregion("bankdev")->base(); + + // Patch the FLEX entry point. + rom[0xfe979] = 0xcd; + rom[0xfe97a] = 0x00; + } +} void swtpc09_state::machine_start() { @@ -660,6 +807,14 @@ void swtpc09_state::machine_start() m_interrupt = 0; m_active_interrupt = false; + m_fdc_side = 0; + + // Start with the IRQ disabled? + m_fdc_dma_address_reg = 0x10; + + m_floppy_motor_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(swtpc09_state::floppy_motor_callback),this)); + m_floppy_motor_on = 0; + // reset the 6844 for (int i = 0; i < 4; i++) { @@ -671,28 +826,25 @@ void swtpc09_state::machine_start() m_m6844_chain = 0x00; m_banked_space = &subdevice<address_map_bank_device>("bankdev")->space(AS_PROGRAM); - - m_brg->rsa_w(0); - m_brg->rsb_w(1); } void swtpc09_state::init_swtpc09() { - m_system_type = FLEX_DMF2; + m_system_type = FLEX_DMAF2; } void swtpc09_state::init_swtpc09i() { - m_system_type = FLEX_DC4_PIAIDE; + m_system_type = FLEX_DC5_PIAIDE; } void swtpc09_state::init_swtpc09u() { - m_system_type = UNIFLEX_DMF2; + m_system_type = UNIFLEX_DMAF2; } void swtpc09_state::init_swtpc09d3() { m_via_ca1_input = 0; - m_system_type = UNIFLEX_DMF3; + m_system_type = UNIFLEX_DMAF3; } |