summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/swtpc09.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/swtpc09.cpp')
-rw-r--r--src/mame/machine/swtpc09.cpp530
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;
}