swtpc, swtpc09: save state, port change, cleanups

This commit is contained in:
68bit 2019-11-08 11:08:20 +11:00 committed by Vas Crabb
parent d039a575ca
commit ffe5c0772c
4 changed files with 124 additions and 83 deletions

View File

@ -109,14 +109,16 @@ public:
, m_maincpu(*this, "maincpu")
, m_ram(*this, "ram")
, m_brg(*this, "brg")
, m_maincpu_clock(*this, "maincpu_clock")
, m_swtbug_ready_wait(*this, "swtbug_ready_wait")
, m_swtbug_load_at_a100(*this, "swtbug_load_at_a100")
, m_maincpu_clock(*this, "MAINCPU_CLOCK")
, m_swtbug_ready_wait(*this, "SWTBUG_READY_WAIT")
, m_swtbug_load_at_a100(*this, "SWTBUG_LOAD_AT_A100")
{ }
void swtpcm(machine_config &config);
void swtpc(machine_config &config);
DECLARE_INPUT_CHANGED_MEMBER(maincpu_clock_change);
private:
virtual void machine_reset() override;
virtual void machine_start() override;
@ -158,8 +160,8 @@ static INPUT_PORTS_START( swtpc )
// the CPU clock and the frequency was variable. The 6800 was
// available at speeds up to 2MHz so that might not have been
// impossible. An overclock option of 4MHz is also implemented.
PORT_START("maincpu_clock")
PORT_CONFNAME(0xffffff, 1000000, "CPU clock")
PORT_START("MAINCPU_CLOCK")
PORT_CONFNAME(0xffffff, 1000000, "CPU clock") PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc_state, maincpu_clock_change, 0)
PORT_CONFSETTING( 898550, "0.89855 MHz") // MIKBUG
PORT_CONFSETTING( 921600, "0.92160 MHz") // SWTPC
PORT_CONFSETTING(1000000, "1.0 MHz")
@ -172,7 +174,7 @@ static INPUT_PORTS_START( swtpc )
// the motor when accessing the control register, the drive does not
// have time to become ready before commands are issued and the boot
// fails. This workaround is necessary in practice.
PORT_START("swtbug_ready_wait")
PORT_START("SWTBUG_READY_WAIT")
PORT_CONFNAME(0x1, 1, "SWTBUG ready wait patch")
PORT_CONFSETTING(0, "No")
PORT_CONFSETTING(1, "Yes - apply patch")
@ -184,7 +186,7 @@ static INPUT_PORTS_START( swtpc )
// 0xa100 or perhaps better implement support for the high PROM to
// allow custom code to be used which is needed anyway as even NEWBUG
// appears to have issues and is not optimized for the DC5 FDC.
PORT_START("swtbug_load_at_a100")
PORT_START("SWTBUG_LOAD_AT_A100")
PORT_CONFNAME(0x1, 1, "SWTBUG disk boot patch, to load at 0xa100")
PORT_CONFSETTING(0, "No")
PORT_CONFSETTING(1, "Yes - apply patch")
@ -195,6 +197,11 @@ static DEVICE_INPUT_DEFAULTS_START( dc5 )
DEVICE_INPUT_DEFAULTS("address_mode", 0xf, 0)
DEVICE_INPUT_DEFAULTS_END
INPUT_CHANGED_MEMBER(swtpc_state::maincpu_clock_change)
{
m_maincpu->set_clock(newval);
}
void swtpc_state::machine_reset()
{
uint32_t maincpu_clock = m_maincpu_clock->read();

View File

@ -206,8 +206,8 @@ static INPUT_PORTS_START( swtpc09 )
// Run the 6809 at 2MHz (an 8MHz XTAL) so that manual polling of FDC can
// keep up with higher rate operation. The MPU09 did have the option of
// 1MHz or 2MHz operation.
PORT_START("maincpu_clock")
PORT_CONFNAME(0xffffff, 2000000, "CPU clock")
PORT_START("MAINCPU_CLOCK")
PORT_CONFNAME(0xffffff, 2000000, "CPU clock") PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc09_state, maincpu_clock_change, 0)
PORT_CONFSETTING(1000000, "1.0 MHz")
PORT_CONFSETTING(2000000, "2.0 MHz")
PORT_CONFSETTING(4000000, "4.0 MHz")
@ -219,20 +219,20 @@ static INPUT_PORTS_START( swtpc09 )
// 'standard' 3.5" - 1.2MHz
// 3.5" hd - 2.0MHz
// 8" 360rpm - 2.4MHz
PORT_START("fdc_clock")
PORT_DIPNAME(0xffffff, 2000000, "DMAF2/3 FDC clock")
PORT_DIPSETTING(1000000, "1.0 MHz")
PORT_DIPSETTING(1200000, "1.2 MHz")
PORT_DIPSETTING(2000000, "2.0 MHz")
PORT_DIPSETTING(2400000, "2.4 MHz")
PORT_START("FDC_CLOCK")
PORT_CONFNAME(0xffffff, 2000000, "DMAF2/3 FDC clock") PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc09_state, fdc_clock_change, 0)
PORT_CONFSETTING(1000000, "1.0 MHz")
PORT_CONFSETTING(1200000, "1.2 MHz")
PORT_CONFSETTING(2000000, "2.0 MHz")
PORT_CONFSETTING(2400000, "2.4 MHz")
// The MP-ID board has jumpers to vary the baud rates generated. The
// most useful is the Low/High rate jumper that provide a four times
// rate increase.
PORT_START("baud_rate_high")
PORT_DIPNAME(0x1, 0, "High baud rate")
PORT_DIPSETTING(0, "Low (x1)")
PORT_DIPSETTING(1, "High (x4)")
PORT_START("BAUD_RATE_HIGH")
PORT_CONFNAME(0x1, 0, "High baud rate") PORT_CHANGED_MEMBER(DEVICE_SELF, swtpc09_state, baud_rate_high_change, 0)
PORT_CONFSETTING(0, "Low (x1)")
PORT_CONFSETTING(1, "High (x4)")
// Debug aid to hard code the density. The FLEX format uses single
// density for track zero. Many virtual disks 'fix' the format to be
@ -240,7 +240,7 @@ static INPUT_PORTS_START( swtpc09 )
// driver support for that. This setting is an aid to report
// unexpected usage, and it attempts to correct that. It is possible
// to patch the software to work with these pure double density disks.
PORT_START("floppy_expected_density")
PORT_START("FLOPPY_EXPECTED_DENSITY")
PORT_CONFNAME(0xff, 0, "DMAF2/3 expected density")
PORT_CONFSETTING(0, "-")
PORT_CONFSETTING(1, "single density")
@ -259,7 +259,7 @@ static INPUT_PORTS_START( swtpc09 )
// the head based track zero being single density. This aid is not
// intended to be a substitute for fixing the drivers but it does help
// work through the issues while patching the disks.
PORT_START("floppy_expected_sectors")
PORT_START("FLOPPY_EXPECTED_SECTORS")
PORT_CONFNAME(0xff, 0, "DMAF2/3 expected sectors per side")
PORT_CONFSETTING(0, "-")
PORT_CONFSETTING(10, "10") // 5 1/4" single density 256B
@ -271,7 +271,7 @@ static INPUT_PORTS_START( swtpc09 )
// 6800 disks did format track zero in single density and if the
// driver sticks to that and if using a double density disk then set a
// single density size here.
PORT_START("floppy_track_zero_expected_sectors")
PORT_START("FLOPPY_TRACK_ZERO_EXPECTED_SECTORS")
PORT_CONFNAME(0xff, 0, "DMAF2/3 track zero expected sectors per side")
PORT_CONFSETTING(0, "-")
PORT_CONFSETTING(10, "10") // 5 1/4" single density 256B
@ -280,7 +280,7 @@ static INPUT_PORTS_START( swtpc09 )
PORT_CONFSETTING(26, "26") // 8" double density 256B
PORT_CONFSETTING(36, "36") // 3.5" 1.4M QD 256B
PORT_START("sbug_double_density")
PORT_START("SBUG_DOUBLE_DENSITY")
PORT_CONFNAME(0x1, 0, "SBUG patch for double density (SSO) disk boot")
PORT_CONFSETTING(0, "No - single density")
PORT_CONFSETTING(1, "Yes - double density")
@ -289,7 +289,7 @@ static INPUT_PORTS_START( swtpc09 )
// after the disk boot code has loaded FLEX, and then it jumps to
// 0xc850 to cold start FLEX. Have seen 0xcd00 being the cold start
// address, so add an option to patch the PROM for that.
PORT_START("piaide_flex_boot_cd00")
PORT_START("PIAIDE_FLEX_BOOT_CD00")
PORT_CONFNAME(0x1, 0, "PIA IDE PROM patch FLEX entry to 0xcd00")
PORT_CONFSETTING(0, "No - FLEX entry 0xc850")
PORT_CONFSETTING(1, "Yes - FLEX entry 0xcd00")

View File

@ -44,14 +44,14 @@ public:
, m_via_cb2(*this, "via_cb2")
, m_dat(*this, "dat")
, m_bankdev(*this, "bankdev")
, m_maincpu_clock(*this, "maincpu_clock")
, m_fdc_clock(*this, "fdc_clock")
, m_baud_rate_high(*this, "baud_rate_high")
, m_floppy_expected_density(*this, "floppy_expected_density")
, m_floppy_expected_sectors(*this, "floppy_expected_sectors")
, m_floppy_track_zero_expected_sectors(*this, "floppy_track_zero_expected_sectors")
, m_sbug_double_density(*this, "sbug_double_density")
, m_piaide_flex_boot_cd00(*this, "piaide_flex_boot_cd00")
, m_maincpu_clock(*this, "MAINCPU_CLOCK")
, m_fdc_clock(*this, "FDC_CLOCK")
, m_baud_rate_high(*this, "BAUD_RATE_HIGH")
, m_floppy_expected_density(*this, "FLOPPY_EXPECTED_DENSITY")
, m_floppy_expected_sectors(*this, "FLOPPY_EXPECTED_SECTORS")
, m_floppy_track_zero_expected_sectors(*this, "FLOPPY_TRACK_ZERO_EXPECTED_SECTORS")
, m_sbug_double_density(*this, "SBUG_DOUBLE_DENSITY")
, m_piaide_flex_boot_cd00(*this, "PIAIDE_FLEX_BOOT_CD00")
{ }
void swtpc09_base(machine_config &config);
@ -65,6 +65,10 @@ public:
void init_swtpc09u();
void init_swtpc09d3();
DECLARE_INPUT_CHANGED_MEMBER(maincpu_clock_change);
DECLARE_INPUT_CHANGED_MEMBER(fdc_clock_change);
DECLARE_INPUT_CHANGED_MEMBER(baud_rate_high_change);
private:
DECLARE_FLOPPY_FORMATS(floppy_flex_formats);
DECLARE_FLOPPY_FORMATS(floppy_uniflex_formats);

View File

@ -45,7 +45,7 @@ WRITE_LINE_MEMBER(swtpc09_state::io_irq_w)
/******* MC6840 PTM on MPID Board *******/
/* 6840 PTM handlers */
// 6840 PTM handlers
WRITE_LINE_MEMBER( swtpc09_state::ptm_o1_callback )
{
m_pia_counter++;
@ -55,7 +55,7 @@ WRITE_LINE_MEMBER( swtpc09_state::ptm_o1_callback )
WRITE_LINE_MEMBER( swtpc09_state::ptm_o3_callback )
{
/* the output from timer3 is the input clock for timer2 */
// the output from timer3 is the input clock for timer2
//m_ptm->set_c2(state);
}
@ -604,25 +604,17 @@ offs_t swtpc09_state::dat_translate(offs_t offset) const
READ8_MEMBER(swtpc09_state::main_r)
{
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)
{
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 */
@ -735,10 +727,10 @@ READ8_MEMBER( swtpc09_state::m6844_r )
{
uint8_t result = 0;
/* switch off the offset we were given */
// switch off the offset we were given
switch (offset)
{
/* upper byte of address */
// upper byte of address
case 0x00:
case 0x04:
case 0x08:
@ -746,7 +738,7 @@ READ8_MEMBER( swtpc09_state::m6844_r )
result = m_m6844_channel[offset / 4].address >> 8;
break;
/* lower byte of address */
// lower byte of address
case 0x01:
case 0x05:
case 0x09:
@ -754,7 +746,7 @@ READ8_MEMBER( swtpc09_state::m6844_r )
result = m_m6844_channel[offset / 4].address & 0xff;
break;
/* upper byte of counter */
// upper byte of counter
case 0x02:
case 0x06:
case 0x0a:
@ -762,7 +754,7 @@ READ8_MEMBER( swtpc09_state::m6844_r )
result = m_m6844_channel[offset / 4].counter >> 8;
break;
/* lower byte of counter */
// lower byte of counter
case 0x03:
case 0x07:
case 0x0b:
@ -770,7 +762,7 @@ READ8_MEMBER( swtpc09_state::m6844_r )
result = m_m6844_channel[offset / 4].counter & 0xff;
break;
/* channel control */
// channel control
case 0x10:
case 0x11:
case 0x12:
@ -787,33 +779,30 @@ READ8_MEMBER( swtpc09_state::m6844_r )
}
break;
/* priority control */
// priority control
case 0x14:
result = m_m6844_priority;
break;
/* interrupt control */
// interrupt control
case 0x15:
result = m_m6844_interrupt;
break;
/* chaining control */
// chaining control
case 0x16:
result = m_m6844_chain;
break;
/* 0x17-0x1f not used */
// 0x17-0x1f not used
default: break;
}
if (m_system_type == UNIFLEX_DMAF2 || m_system_type == FLEX_DMAF2) // if DMAF2 controller data bus is inverted to 6844
{
// if DMAF2 controller data bus is inverted to 6844
if (m_system_type == UNIFLEX_DMAF2 || m_system_type == FLEX_DMAF2)
return ~result & 0xff;
}
else
{
return result & 0xff;
}
}
@ -821,13 +810,14 @@ WRITE8_MEMBER( swtpc09_state::m6844_w )
{
int i;
if (m_system_type == UNIFLEX_DMAF2 || m_system_type == FLEX_DMAF2) // if DMAF2 controller data bus is inverted to 6844
// if DMAF2 controller data bus is inverted to 6844
if (m_system_type == UNIFLEX_DMAF2 || m_system_type == FLEX_DMAF2)
data = ~data & 0xff;
/* switch off the offset we were given */
// switch off the offset we were given
switch (offset)
{
/* upper byte of address */
// upper byte of address
case 0x00:
case 0x04:
case 0x08:
@ -835,7 +825,7 @@ WRITE8_MEMBER( swtpc09_state::m6844_w )
m_m6844_channel[offset / 4].address = (m_m6844_channel[offset / 4].address & 0xff) | (data << 8);
break;
/* lower byte of address */
// lower byte of address
case 0x01:
case 0x05:
case 0x09:
@ -843,7 +833,7 @@ WRITE8_MEMBER( swtpc09_state::m6844_w )
m_m6844_channel[offset / 4].address = (m_m6844_channel[offset / 4].address & 0xff00) | (data & 0xff);
break;
/* upper byte of counter */
// upper byte of counter
case 0x02:
case 0x06:
case 0x0a:
@ -851,7 +841,7 @@ WRITE8_MEMBER( swtpc09_state::m6844_w )
m_m6844_channel[offset / 4].counter = (m_m6844_channel[offset / 4].counter & 0xff) | (data << 8);
break;
/* lower byte of counter */
// lower byte of counter
case 0x03:
case 0x07:
case 0x0b:
@ -859,7 +849,7 @@ WRITE8_MEMBER( swtpc09_state::m6844_w )
m_m6844_channel[offset / 4].counter = (m_m6844_channel[offset / 4].counter & 0xff00) | (data & 0xff);
break;
/* channel control */
// channel control
case 0x10:
case 0x11:
case 0x12:
@ -867,57 +857,73 @@ WRITE8_MEMBER( swtpc09_state::m6844_w )
m_m6844_channel[offset - 0x10].control = (m_m6844_channel[offset - 0x10].control & 0xc0) | (data & 0x3f);
break;
/* priority control */
// priority control
case 0x14:
m_m6844_priority = data;
/* update each channel */
// update each channel
for (i = 0; i < 4; i++)
{
/* if we're going active... */
// if we're going active...
if (!m_m6844_channel[i].active && (data & (1 << i)))
{
/* mark us active */
// mark us active
m_m6844_channel[i].active = 1;
/* set the DMA busy bit and clear the DMA end bit */
// 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 */
// 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... */
// if we're going inactive...
else if (m_m6844_channel[i].active && !(data & (1 << i)))
{
/* mark us inactive */
//mark us inactive
m_m6844_channel[i].active = 0;
}
}
break;
/* interrupt control */
// interrupt control
case 0x15:
m_m6844_interrupt = (m_m6844_interrupt & 0x80) | (data & 0x7f);
m6844_update_interrupt();
break;
/* chaining control */
// chaining control
case 0x16:
m_m6844_chain = data;
break;
/* 0x17-0x1f not used */
// 0x17-0x1f not used
default: break;
}
}
INPUT_CHANGED_MEMBER(swtpc09_state::maincpu_clock_change)
{
m_maincpu->set_clock(newval * 4);
}
INPUT_CHANGED_MEMBER(swtpc09_state::fdc_clock_change)
{
if (m_system_type == FLEX_DMAF2 ||
m_system_type == UNIFLEX_DMAF2 ||
m_system_type == UNIFLEX_DMAF3)
{
m_fdc->set_unscaled_clock(newval);
}
}
INPUT_CHANGED_MEMBER(swtpc09_state::baud_rate_high_change)
{
m_brg->rsa_w(newval);
}
void swtpc09_state::machine_reset()
{
uint32_t maincpu_clock = m_maincpu_clock->read();
@ -933,8 +939,8 @@ void swtpc09_state::machine_reset()
// 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.
// gives a rate four times as high. Note the schematic appears to have
// mislabeled this setting.
uint8_t baud_rate_high = m_baud_rate_high->read();
m_brg->rsa_w(baud_rate_high);
m_brg->rsb_w(1);
@ -947,7 +953,7 @@ void swtpc09_state::machine_reset()
// 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_system_type == FLEX_DC5_PIAIDE) &&
m_sbug_double_density->read())
{
// Patch the boot ROM to load the boot sector in double density.
@ -971,7 +977,7 @@ void swtpc09_state::machine_reset()
void swtpc09_state::machine_start()
{
m_pia_counter = 0; // init ptm/pia counter to 0
m_pia_counter = 0; // init ptm/pia counter to 0
m_fdc_status = 0; // for floppy controller
m_interrupt = 0;
m_active_interrupt = false;
@ -1000,6 +1006,30 @@ void swtpc09_state::machine_start()
m_m6844_chain = 0x00;
m_banked_space = &subdevice<address_map_bank_device>("bankdev")->space(AS_PROGRAM);
save_item(NAME(m_pia_counter));
save_item(NAME(m_dmaf_high_address));
save_item(NAME(m_dmaf2_interrupt_enable));
save_item(NAME(m_system_type));
save_item(NAME(m_fdc_status));
save_item(NAME(m_floppy_motor_on));
save_item(NAME(m_fdc_side));
save_item(NAME(m_dmaf3_via_porta));
save_item(NAME(m_dmaf3_via_portb));
save_item(NAME(m_active_interrupt));
save_item(NAME(m_interrupt));
for (int i = 0; i < 4; i++)
{
save_item(NAME(m_m6844_channel[i].active), i);
save_item(NAME(m_m6844_channel[i].address), i);
save_item(NAME(m_m6844_channel[i].counter), i);
save_item(NAME(m_m6844_channel[i].control), i);
save_item(NAME(m_m6844_channel[i].start_address), i);
save_item(NAME(m_m6844_channel[i].start_counter), i);
}
save_item(NAME(m_m6844_priority));
save_item(NAME(m_m6844_interrupt));
save_item(NAME(m_m6844_chain));
}
void swtpc09_state::init_swtpc09()