mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
(MESS) Refactored the Commodore 2040/3040/4040 disk drives to use the modern floppy system. [Curt Coder]
This commit is contained in:
parent
95b8ff6fb7
commit
a24e0640a3
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -693,6 +693,8 @@ src/emu/bus/ieee488/c2040.c svneol=native#text/plain
|
||||
src/emu/bus/ieee488/c2040.h svneol=native#text/plain
|
||||
src/emu/bus/ieee488/c2040fdc.c svneol=native#text/plain
|
||||
src/emu/bus/ieee488/c2040fdc.h svneol=native#text/plain
|
||||
src/emu/bus/ieee488/c8050.c svneol=native#text/plain
|
||||
src/emu/bus/ieee488/c8050.h svneol=native#text/plain
|
||||
src/emu/bus/ieee488/c8280.c svneol=native#text/plain
|
||||
src/emu/bus/ieee488/c8280.h svneol=native#text/plain
|
||||
src/emu/bus/ieee488/d9060.c svneol=native#text/plain
|
||||
|
@ -251,6 +251,7 @@ BUSOBJS += $(BUSOBJ)/ieee488/ieee488.o
|
||||
BUSOBJS += $(BUSOBJ)/ieee488/c2031.o
|
||||
BUSOBJS += $(BUSOBJ)/ieee488/c2040.o
|
||||
BUSOBJS += $(BUSOBJ)/ieee488/c2040fdc.o
|
||||
BUSOBJS += $(BUSOBJ)/ieee488/c8050.o
|
||||
BUSOBJS += $(BUSOBJ)/ieee488/c8280.o
|
||||
BUSOBJS += $(BUSOBJ)/ieee488/d9060.o
|
||||
BUSOBJS += $(BUSOBJ)/ieee488/d9060hd.o
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@
|
||||
// copyright-holders:Curt Coder
|
||||
/**********************************************************************
|
||||
|
||||
Commodore 2040/3040/4040/8050/8250/SFD-1001 Disk Drive emulation
|
||||
Commodore 2040/3040/4040 Disk Drive emulation
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
@ -16,11 +16,15 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "ieee488.h"
|
||||
#include "c2040fdc.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "cpu/m6502/m6504.h"
|
||||
#include "imagedev/flopdrv.h"
|
||||
#include "imagedev/floppy.h"
|
||||
#include "formats/d64_dsk.h"
|
||||
#include "formats/g64_dsk.h"
|
||||
#include "formats/d67_dsk.h"
|
||||
#include "formats/d80_dsk.h"
|
||||
#include "formats/d82_dsk.h"
|
||||
#include "machine/6522via.h"
|
||||
#include "machine/6532riot.h"
|
||||
#include "machine/mos6530.h"
|
||||
@ -34,7 +38,7 @@
|
||||
// ======================> c2040_device
|
||||
|
||||
class c2040_device : public device_t,
|
||||
public device_ieee488_interface
|
||||
public device_ieee488_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
@ -46,42 +50,39 @@ public:
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
virtual ioport_constructor device_input_ports() const;
|
||||
|
||||
// not really public
|
||||
static void on_disk0_change(device_image_interface &image);
|
||||
static void on_disk1_change(device_image_interface &image);
|
||||
|
||||
DECLARE_READ8_MEMBER( dio_r );
|
||||
DECLARE_WRITE8_MEMBER( dio_w );
|
||||
DECLARE_READ8_MEMBER( riot1_pa_r );
|
||||
DECLARE_WRITE8_MEMBER( riot1_pa_w );
|
||||
DECLARE_READ8_MEMBER( riot1_pb_r );
|
||||
DECLARE_WRITE8_MEMBER( riot1_pb_w );
|
||||
DECLARE_READ8_MEMBER( via_pa_r );
|
||||
DECLARE_WRITE8_MEMBER( via_pb_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( mode_sel_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( rw_sel_w );
|
||||
DECLARE_READ8_MEMBER( pi_r );
|
||||
DECLARE_WRITE8_MEMBER( pi_w );
|
||||
DECLARE_READ8_MEMBER( miot_pb_r );
|
||||
DECLARE_WRITE8_MEMBER( miot_pb_w );
|
||||
|
||||
DECLARE_FLOPPY_FORMATS( floppy_formats );
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||
|
||||
// device_ieee488_interface overrides
|
||||
virtual void ieee488_atn(int state);
|
||||
virtual void ieee488_ifc(int state);
|
||||
|
||||
virtual void byte_ready(int state) { }
|
||||
enum
|
||||
{
|
||||
LED_POWER = 0,
|
||||
LED_ACT0,
|
||||
LED_ACT1,
|
||||
LED_ERR
|
||||
};
|
||||
|
||||
inline void update_ieee_signals();
|
||||
inline void update_gcr_data();
|
||||
inline void read_current_track(int unit);
|
||||
inline void spindle_motor(int unit, int mtr);
|
||||
inline void micropolis_step_motor(int unit, int stp);
|
||||
inline void mpi_step_motor(int unit, int stp);
|
||||
|
||||
required_device<m6502_device> m_maincpu;
|
||||
required_device<m6504_device> m_fdccpu;
|
||||
@ -89,51 +90,20 @@ protected:
|
||||
required_device<riot6532_device> m_riot1;
|
||||
required_device<mos6530_device> m_miot;
|
||||
required_device<via6522_device> m_via;
|
||||
required_device<legacy_floppy_image_device> m_image0;
|
||||
optional_device<legacy_floppy_image_device> m_image1;
|
||||
required_device<floppy_image_device> m_floppy0;
|
||||
optional_device<floppy_image_device> m_floppy1;
|
||||
required_device<c2040_fdc_t> m_fdc;
|
||||
required_memory_region m_gcr;
|
||||
required_ioport m_address;
|
||||
|
||||
struct {
|
||||
// motors
|
||||
int m_stp; // stepper motor phase
|
||||
int m_mtr; // spindle motor on
|
||||
|
||||
// track
|
||||
UINT8 m_track_buffer[G64_BUFFER_SIZE]; // track data buffer
|
||||
int m_track_len; // track length
|
||||
int m_buffer_pos; // byte position within track buffer
|
||||
int m_bit_pos; // bit position within track buffer byte
|
||||
|
||||
// devices
|
||||
device_t *m_image;
|
||||
} m_unit[2];
|
||||
|
||||
int m_drive; // selected drive
|
||||
int m_side; // selected side
|
||||
|
||||
// IEEE-488 bus
|
||||
int m_rfdo; // not ready for data output
|
||||
int m_daco; // not data accepted output
|
||||
int m_atna; // attention acknowledge
|
||||
int m_ifc;
|
||||
|
||||
// track
|
||||
int m_ds; // density select
|
||||
int m_bit_count; // GCR bit counter
|
||||
UINT16 m_sr; // GCR data shift register
|
||||
UINT8 m_pi; // parallel data input
|
||||
UINT16 m_i; // GCR encoder/decoded ROM address
|
||||
UINT8 m_e; // GCR encoder/decoded ROM data
|
||||
|
||||
// signals
|
||||
int m_ready; // byte ready
|
||||
int m_mode; // mode select
|
||||
int m_rw; // read/write select
|
||||
int m_miot_irq; // MIOT interrupt
|
||||
|
||||
// timers
|
||||
emu_timer *m_bit_timer;
|
||||
};
|
||||
|
||||
|
||||
@ -158,72 +128,8 @@ public:
|
||||
// optional information overrides
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
};
|
||||
|
||||
|
||||
// ======================> c8050_device
|
||||
|
||||
class c8050_device : public c2040_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
c8050_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
c8050_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, bool double_sided, const char *shortname, const char *source);
|
||||
|
||||
// optional information overrides
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
DECLARE_READ8_MEMBER( via_pb_r );
|
||||
DECLARE_WRITE8_MEMBER( via_pb_w );
|
||||
DECLARE_READ8_MEMBER( miot_pb_r );
|
||||
DECLARE_WRITE8_MEMBER( miot_pb_w );
|
||||
|
||||
protected:
|
||||
virtual void byte_ready(int state);
|
||||
|
||||
bool m_double_sided;
|
||||
};
|
||||
|
||||
|
||||
// ======================> c8250_device
|
||||
|
||||
class c8250_device : public c8050_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
c8250_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// optional information overrides
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
};
|
||||
|
||||
|
||||
// ======================> c8250lp_device
|
||||
|
||||
class c8250lp_device : public c8050_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
c8250lp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// optional information overrides
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
};
|
||||
|
||||
|
||||
// ======================> sfd1001_device
|
||||
|
||||
class sfd1001_device : public c8050_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sfd1001_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// optional information overrides
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
DECLARE_FLOPPY_FORMATS( floppy_formats );
|
||||
};
|
||||
|
||||
|
||||
@ -231,10 +137,6 @@ public:
|
||||
extern const device_type C2040;
|
||||
extern const device_type C3040;
|
||||
extern const device_type C4040;
|
||||
extern const device_type C8050;
|
||||
extern const device_type C8250;
|
||||
extern const device_type C8250LP;
|
||||
extern const device_type SFD1001;
|
||||
|
||||
|
||||
|
||||
|
@ -13,7 +13,9 @@
|
||||
|
||||
TODO:
|
||||
|
||||
- writing (write sr shifted before write starts)
|
||||
- writing starts in the middle of a byte
|
||||
- READY output is actually low when (CNT=9 QB=0), but since we latch the read
|
||||
byte on syncpoints, READY is low when (prevCNT=9 CNT=0) as seen below
|
||||
- 8050 PLL
|
||||
|
||||
*/
|
||||
@ -69,7 +71,6 @@ const rom_entry *c2040_fdc_t::device_rom_region() const
|
||||
|
||||
c2040_fdc_t::c2040_fdc_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
|
||||
device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__),
|
||||
m_read_pi(*this),
|
||||
m_write_sync(*this),
|
||||
m_write_ready(*this),
|
||||
m_write_error(*this),
|
||||
@ -86,11 +87,13 @@ c2040_fdc_t::c2040_fdc_t(const machine_config &mconfig, device_type type, const
|
||||
m_rw_sel(0),
|
||||
m_period(attotime::from_hz(clock))
|
||||
{
|
||||
cur_live.tm = attotime::never;
|
||||
cur_live.state = IDLE;
|
||||
cur_live.next_state = -1;
|
||||
}
|
||||
|
||||
c2040_fdc_t::c2040_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, C2040_FDC, "C2040 FDC", tag, owner, clock, "c2040fdc", __FILE__),
|
||||
m_read_pi(*this),
|
||||
m_write_sync(*this),
|
||||
m_write_ready(*this),
|
||||
m_write_error(*this),
|
||||
@ -107,6 +110,9 @@ c2040_fdc_t::c2040_fdc_t(const machine_config &mconfig, const char *tag, device_
|
||||
m_rw_sel(0),
|
||||
m_period(attotime::from_hz(clock))
|
||||
{
|
||||
cur_live.tm = attotime::never;
|
||||
cur_live.state = IDLE;
|
||||
cur_live.next_state = -1;
|
||||
}
|
||||
|
||||
c8050_fdc_t::c8050_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
@ -121,7 +127,6 @@ c8050_fdc_t::c8050_fdc_t(const machine_config &mconfig, const char *tag, device_
|
||||
void c2040_fdc_t::device_start()
|
||||
{
|
||||
// resolve callbacks
|
||||
m_read_pi.resolve_safe(0);
|
||||
m_write_sync.resolve_safe();
|
||||
m_write_ready.resolve_safe();
|
||||
m_write_error.resolve_safe();
|
||||
@ -171,6 +176,7 @@ void c2040_fdc_t::live_start()
|
||||
cur_live.drv_sel = m_drv_sel;
|
||||
cur_live.mode_sel = m_mode_sel;
|
||||
cur_live.rw_sel = m_rw_sel;
|
||||
cur_live.pi = m_pi;
|
||||
|
||||
checkpoint_live = cur_live;
|
||||
|
||||
@ -179,12 +185,15 @@ void c2040_fdc_t::live_start()
|
||||
|
||||
void c2040_fdc_t::checkpoint()
|
||||
{
|
||||
get_next_edge(machine().time());
|
||||
checkpoint_live = cur_live;
|
||||
if (LOG) logerror("---- checkpoint rw=%u mode=%u\n", checkpoint_live.rw_sel, checkpoint_live.mode_sel);
|
||||
}
|
||||
|
||||
void c2040_fdc_t::rollback()
|
||||
{
|
||||
cur_live = checkpoint_live;
|
||||
if (LOG) logerror("---- rollback rw=%u mode=%u\n", cur_live.rw_sel, cur_live.mode_sel);
|
||||
get_next_edge(cur_live.tm);
|
||||
}
|
||||
|
||||
@ -214,6 +223,8 @@ bool c2040_fdc_t::write_next_bit(bool bit, attotime limit)
|
||||
if(bit && cur_live.write_position < ARRAY_LENGTH(cur_live.write_buffer))
|
||||
cur_live.write_buffer[cur_live.write_position++] = cur_live.tm;
|
||||
|
||||
if (LOG) logerror("%s write bit %u (%u)\n", cur_live.tm.as_string(), cur_live.bit_counter, bit);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -221,9 +232,12 @@ void c2040_fdc_t::commit(attotime tm)
|
||||
{
|
||||
if(cur_live.write_start_time.is_never() || tm == cur_live.write_start_time || !cur_live.write_position)
|
||||
return;
|
||||
|
||||
if (LOG) logerror("%s committing %u transitions since %s\n", tm.as_string(), cur_live.write_position, cur_live.write_start_time.as_string());
|
||||
|
||||
if(get_floppy())
|
||||
get_floppy()->write_flux(cur_live.write_start_time, tm, cur_live.write_position, cur_live.write_buffer);
|
||||
|
||||
cur_live.write_start_time = tm;
|
||||
cur_live.write_position = 0;
|
||||
}
|
||||
@ -290,6 +304,9 @@ void c2040_fdc_t::live_run(attotime limit)
|
||||
case RUNNING: {
|
||||
bool syncpoint = false;
|
||||
|
||||
if (cur_live.tm > limit)
|
||||
return;
|
||||
|
||||
int bit = get_next_bit(cur_live.tm, limit);
|
||||
if(bit < 0)
|
||||
return;
|
||||
@ -317,12 +334,13 @@ void c2040_fdc_t::live_run(attotime limit)
|
||||
cur_live.shift_reg <<= 1;
|
||||
cur_live.shift_reg |= !(BIT(cur_live.cell_counter, 3) || BIT(cur_live.cell_counter, 2));
|
||||
cur_live.shift_reg &= 0x3ff;
|
||||
|
||||
if (LOG) logerror("%s read bit %u (%u) >> %03x, rw=%u mode=%u\n", cur_live.tm.as_string(), cur_live.bit_counter,
|
||||
!(BIT(cur_live.cell_counter, 3) || BIT(cur_live.cell_counter, 2)), cur_live.shift_reg, cur_live.rw_sel, cur_live.mode_sel);
|
||||
|
||||
// write bit
|
||||
if (!cur_live.rw_sel) {
|
||||
write_next_bit(BIT(cur_live.shift_reg_write, 9), limit);
|
||||
cur_live.shift_reg_write <<= 1;
|
||||
cur_live.shift_reg_write &= 0x3ff;
|
||||
}
|
||||
|
||||
// update bit counter
|
||||
@ -337,6 +355,8 @@ void c2040_fdc_t::live_run(attotime limit)
|
||||
ready = 1;
|
||||
}
|
||||
}
|
||||
|
||||
syncpoint = true;
|
||||
}
|
||||
|
||||
// update GCR
|
||||
@ -347,14 +367,26 @@ void c2040_fdc_t::live_run(attotime limit)
|
||||
}
|
||||
|
||||
cur_live.e = m_gcr_rom->base()[cur_live.i];
|
||||
|
||||
if (BIT(cell_counter, 1) && !BIT(cur_live.cell_counter, 1) && cur_live.bit_counter == 9) {
|
||||
//ready = 0;
|
||||
}
|
||||
|
||||
// load write shift register
|
||||
if (!ready) {
|
||||
// load write shift register
|
||||
// E7 E6 I7 E5 E4 E3 E2 I2 E1 E0
|
||||
UINT8 e = cur_live.e;
|
||||
offs_t i = cur_live.i;
|
||||
|
||||
cur_live.shift_reg_write = BIT(e,7)<<9 | BIT(e,6)<<8 | BIT(i,7)<<7 | BIT(e,5)<<6 | BIT(e,4)<<5 | BIT(e,3)<<4 | BIT(e,2)<<3 | BIT(i,2)<<2 | (e & 0x03);
|
||||
|
||||
if(LOG) logerror("%s load write shift register %03x\n",cur_live.tm.as_string(),cur_live.shift_reg_write);
|
||||
} else if (BIT(cell_counter, 1) && !BIT(cur_live.cell_counter, 1)) {
|
||||
// clock write shift register
|
||||
cur_live.shift_reg_write <<= 1;
|
||||
cur_live.shift_reg_write &= 0x3ff;
|
||||
|
||||
if (LOG) logerror("%s write shift << %03x\n",cur_live.tm.as_string(),cur_live.shift_reg_write);
|
||||
}
|
||||
|
||||
// update signals
|
||||
@ -362,11 +394,13 @@ void c2040_fdc_t::live_run(attotime limit)
|
||||
int error = !(BIT(cur_live.e, 3) || ready);
|
||||
|
||||
if (ready != cur_live.ready) {
|
||||
if (LOG) logerror("%s READY %u\n", cur_live.tm.as_string(),ready);
|
||||
cur_live.ready = ready;
|
||||
syncpoint = true;
|
||||
}
|
||||
|
||||
if (sync != cur_live.sync) {
|
||||
if (LOG) logerror("%s SYNC %u\n", cur_live.tm.as_string(),sync);
|
||||
cur_live.sync = sync;
|
||||
syncpoint = true;
|
||||
}
|
||||
@ -378,14 +412,17 @@ void c2040_fdc_t::live_run(attotime limit)
|
||||
|
||||
if (syncpoint) {
|
||||
commit(cur_live.tm);
|
||||
|
||||
cur_live.tm += m_period;
|
||||
live_delay(RUNNING_SYNCPOINT);
|
||||
return;
|
||||
}
|
||||
|
||||
cur_live.tm += m_period;
|
||||
break;
|
||||
}
|
||||
|
||||
case RUNNING_SYNCPOINT: {
|
||||
cur_live.pi = m_read_pi(0);
|
||||
m_write_ready(cur_live.ready);
|
||||
m_write_sync(cur_live.sync);
|
||||
m_write_error(cur_live.error);
|
||||
@ -402,23 +439,17 @@ void c2040_fdc_t::get_next_edge(attotime when)
|
||||
{
|
||||
floppy_image_device *floppy = get_floppy();
|
||||
|
||||
m_edge = floppy ? floppy->get_next_transition(when) : attotime::never;
|
||||
cur_live.edge = floppy ? floppy->get_next_transition(when) : attotime::never;
|
||||
}
|
||||
|
||||
int c2040_fdc_t::get_next_bit(attotime &tm, attotime limit)
|
||||
{
|
||||
/* floppy_image_device *floppy = cur_live.drv_sel ? m_floppy1 : m_floppy0;
|
||||
|
||||
attotime edge = floppy ? floppy->get_next_transition(tm) : attotime::never;*/
|
||||
attotime edge = m_edge;
|
||||
attotime next = tm + m_period;
|
||||
|
||||
tm = next;
|
||||
|
||||
int bit = (edge.is_never() || edge >= next) ? 0 : 1;
|
||||
int bit = (cur_live.edge.is_never() || cur_live.edge >= next) ? 0 : 1;
|
||||
|
||||
if (bit) {
|
||||
get_next_edge(tm);
|
||||
get_next_edge(next);
|
||||
}
|
||||
|
||||
return bit && cur_live.rw_sel;
|
||||
@ -429,14 +460,23 @@ READ8_MEMBER( c2040_fdc_t::read )
|
||||
UINT8 e = checkpoint_live.e;
|
||||
offs_t i = checkpoint_live.i;
|
||||
|
||||
return (BIT(e, 6) << 7) | (BIT(i, 7) << 6) | (e & 0x33) | (BIT(e, 2) << 3) | (i & 0x04);
|
||||
UINT8 data = (BIT(e, 6) << 7) | (BIT(i, 7) << 6) | (e & 0x33) | (BIT(e, 2) << 3) | (i & 0x04);
|
||||
|
||||
if (LOG) logerror("%s VIA reads data %02x (%03x)\n", machine().time().as_string(), data, checkpoint_live.shift_reg);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( c2040_fdc_t::write )
|
||||
{
|
||||
live_sync();
|
||||
cur_live.pi = data;
|
||||
live_run();
|
||||
if (m_pi != data)
|
||||
{
|
||||
live_sync();
|
||||
m_pi = cur_live.pi = data;
|
||||
checkpoint();
|
||||
if (LOG) logerror("%s PI %02x\n", machine().time().as_string(), data);
|
||||
live_run();
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( c2040_fdc_t::drv_sel_w )
|
||||
@ -445,7 +485,8 @@ WRITE_LINE_MEMBER( c2040_fdc_t::drv_sel_w )
|
||||
{
|
||||
live_sync();
|
||||
m_drv_sel = cur_live.drv_sel = state;
|
||||
get_next_edge(machine().time());
|
||||
checkpoint();
|
||||
if (LOG) logerror("%s DRV SEL %u\n", machine().time().as_string(), state);
|
||||
live_run();
|
||||
}
|
||||
}
|
||||
@ -456,6 +497,8 @@ WRITE_LINE_MEMBER( c2040_fdc_t::mode_sel_w )
|
||||
{
|
||||
live_sync();
|
||||
m_mode_sel = cur_live.mode_sel = state;
|
||||
checkpoint();
|
||||
if (LOG) logerror("%s MODE SEL %u\n", machine().time().as_string(), state);
|
||||
live_run();
|
||||
}
|
||||
}
|
||||
@ -466,6 +509,8 @@ WRITE_LINE_MEMBER( c2040_fdc_t::rw_sel_w )
|
||||
{
|
||||
live_sync();
|
||||
m_rw_sel = cur_live.rw_sel = state;
|
||||
checkpoint();
|
||||
if (LOG) logerror("%s RW SEL %u\n", machine().time().as_string(), state);
|
||||
if (state)
|
||||
stop_writing(machine().time());
|
||||
live_run();
|
||||
@ -478,8 +523,9 @@ WRITE_LINE_MEMBER( c2040_fdc_t::mtr0_w )
|
||||
{
|
||||
live_sync();
|
||||
m_mtr0 = state;
|
||||
if (LOG) logerror("%s MTR0 %u\n", machine().time().as_string(), state);
|
||||
m_floppy0->mon_w(state);
|
||||
get_next_edge(machine().time());
|
||||
checkpoint();
|
||||
|
||||
if (!m_mtr0 || !m_mtr1) {
|
||||
if(cur_live.state == IDLE) {
|
||||
@ -499,8 +545,9 @@ WRITE_LINE_MEMBER( c2040_fdc_t::mtr1_w )
|
||||
{
|
||||
live_sync();
|
||||
m_mtr1 = state;
|
||||
if (LOG) logerror("%s MTR1 %u\n", machine().time().as_string(), state);
|
||||
if (m_floppy1) m_floppy1->mon_w(state);
|
||||
get_next_edge(machine().time());
|
||||
checkpoint();
|
||||
|
||||
if (!m_mtr0 || !m_mtr1) {
|
||||
if(cur_live.state == IDLE) {
|
||||
@ -520,13 +567,20 @@ WRITE_LINE_MEMBER( c2040_fdc_t::odd_hd_w )
|
||||
{
|
||||
live_sync();
|
||||
m_odd_hd = cur_live.odd_hd = state;
|
||||
if (LOG) logerror("%s ODD HD %u\n", machine().time().as_string(), state);
|
||||
m_floppy0->ss_w(!state);
|
||||
if (m_floppy1) m_floppy1->ss_w(!state);
|
||||
get_next_edge(machine().time());
|
||||
checkpoint();
|
||||
live_run();
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( c2040_fdc_t::pull_sync_w )
|
||||
{
|
||||
// TODO
|
||||
if (LOG) logerror("%s PULL SYNC %u\n", machine().time().as_string(), state);
|
||||
}
|
||||
|
||||
void c2040_fdc_t::stp_w(floppy_image_device *floppy, int mtr, int &old_stp, int stp)
|
||||
{
|
||||
if (mtr) return;
|
||||
@ -593,7 +647,7 @@ void c2040_fdc_t::stp0_w(int stp)
|
||||
{
|
||||
live_sync();
|
||||
this->stp_w(m_floppy0, m_mtr0, m_stp0, stp);
|
||||
get_next_edge(machine().time());
|
||||
checkpoint();
|
||||
live_run();
|
||||
}
|
||||
}
|
||||
@ -604,7 +658,7 @@ void c2040_fdc_t::stp1_w(int stp)
|
||||
{
|
||||
live_sync();
|
||||
if (m_floppy1) this->stp_w(m_floppy1, m_mtr1, m_stp1, stp);
|
||||
get_next_edge(machine().time());
|
||||
checkpoint();
|
||||
live_run();
|
||||
}
|
||||
}
|
||||
@ -615,6 +669,7 @@ void c2040_fdc_t::ds_w(int ds)
|
||||
{
|
||||
live_sync();
|
||||
m_ds = cur_live.ds = ds;
|
||||
checkpoint();
|
||||
live_run();
|
||||
}
|
||||
}
|
||||
|
@ -26,9 +26,6 @@
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MCFG_C2040_PI_CALLBACK(_read) \
|
||||
devcb = &c2040_fdc_t::set_pi_rd_callback(*device, DEVCB2_##_read);
|
||||
|
||||
#define MCFG_C2040_SYNC_CALLBACK(_write) \
|
||||
devcb = &c2040_fdc_t::set_sync_wr_callback(*device, DEVCB2_##_write);
|
||||
|
||||
@ -53,7 +50,6 @@ public:
|
||||
c2040_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
c2040_fdc_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
|
||||
|
||||
template<class _Object> static devcb2_base &set_pi_rd_callback(device_t &device, _Object object) { return downcast<c2040_fdc_t &>(device).m_read_pi.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &set_sync_wr_callback(device_t &device, _Object object) { return downcast<c2040_fdc_t &>(device).m_write_sync.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &set_ready_wr_callback(device_t &device, _Object object) { return downcast<c2040_fdc_t &>(device).m_write_ready.set_callback(object); }
|
||||
template<class _Object> static devcb2_base &set_error_wr_callback(device_t &device, _Object object) { return downcast<c2040_fdc_t &>(device).m_write_error.set_callback(object); }
|
||||
@ -67,6 +63,7 @@ public:
|
||||
DECLARE_WRITE_LINE_MEMBER( mtr0_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( mtr1_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( odd_hd_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( pull_sync_w );
|
||||
DECLARE_READ_LINE_MEMBER( wps_r ) { return checkpoint_live.drv_sel ? m_floppy1->wpt_r() : m_floppy0->wpt_r(); }
|
||||
DECLARE_READ_LINE_MEMBER( sync_r ) { return checkpoint_live.sync; }
|
||||
DECLARE_READ_LINE_MEMBER( ready_r ) { return checkpoint_live.ready; }
|
||||
@ -89,7 +86,6 @@ protected:
|
||||
|
||||
void stp_w(floppy_image_device *floppy, int mtr, int &old_stp, int stp);
|
||||
|
||||
private:
|
||||
enum {
|
||||
IDLE,
|
||||
RUNNING,
|
||||
@ -108,6 +104,7 @@ private:
|
||||
int rw_sel;
|
||||
int odd_hd;
|
||||
|
||||
attotime edge;
|
||||
UINT16 shift_reg;
|
||||
int cycle_counter;
|
||||
int cell_counter;
|
||||
@ -122,7 +119,6 @@ private:
|
||||
int write_position;
|
||||
};
|
||||
|
||||
devcb2_read8 m_read_pi;
|
||||
devcb2_write_line m_write_sync;
|
||||
devcb2_write_line m_write_ready;
|
||||
devcb2_write_line m_write_error;
|
||||
@ -141,8 +137,9 @@ private:
|
||||
int m_mode_sel;
|
||||
int m_rw_sel;
|
||||
int m_odd_hd;
|
||||
UINT8 m_pi;
|
||||
|
||||
attotime m_period, m_edge;
|
||||
attotime m_period;
|
||||
|
||||
live_info cur_live, checkpoint_live;
|
||||
emu_timer *t_gen;
|
||||
|
1380
src/emu/bus/ieee488/c8050.c
Normal file
1380
src/emu/bus/ieee488/c8050.c
Normal file
File diff suppressed because it is too large
Load Diff
191
src/emu/bus/ieee488/c8050.h
Normal file
191
src/emu/bus/ieee488/c8050.h
Normal file
@ -0,0 +1,191 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Curt Coder
|
||||
/**********************************************************************
|
||||
|
||||
Commodore 8050/8250/SFD-1001 Disk Drive emulation
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __C8050__
|
||||
#define __C8050__
|
||||
|
||||
#include "emu.h"
|
||||
#include "ieee488.h"
|
||||
#include "cpu/m6502/m6502.h"
|
||||
#include "cpu/m6502/m6504.h"
|
||||
#include "imagedev/flopdrv.h"
|
||||
#include "formats/d64_dsk.h"
|
||||
#include "formats/g64_dsk.h"
|
||||
#include "machine/6522via.h"
|
||||
#include "machine/6532riot.h"
|
||||
#include "machine/mos6530.h"
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> c8050_device
|
||||
|
||||
class c8050_device : public device_t,
|
||||
public device_ieee488_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
c8050_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, bool double_sided, const char *shortname, const char *source);
|
||||
c8050_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// optional information overrides
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
virtual ioport_constructor device_input_ports() const;
|
||||
|
||||
// not really public
|
||||
static void on_disk0_change(device_image_interface &image);
|
||||
static void on_disk1_change(device_image_interface &image);
|
||||
|
||||
DECLARE_READ8_MEMBER( dio_r );
|
||||
DECLARE_WRITE8_MEMBER( dio_w );
|
||||
DECLARE_READ8_MEMBER( riot1_pa_r );
|
||||
DECLARE_WRITE8_MEMBER( riot1_pa_w );
|
||||
DECLARE_READ8_MEMBER( riot1_pb_r );
|
||||
DECLARE_WRITE8_MEMBER( riot1_pb_w );
|
||||
DECLARE_READ8_MEMBER( via_pa_r );
|
||||
DECLARE_READ8_MEMBER( via_pb_r );
|
||||
DECLARE_WRITE8_MEMBER( via_pb_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( mode_sel_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( rw_sel_w );
|
||||
DECLARE_READ8_MEMBER( pi_r );
|
||||
DECLARE_WRITE8_MEMBER( pi_w );
|
||||
DECLARE_READ8_MEMBER( miot_pb_r );
|
||||
DECLARE_WRITE8_MEMBER( miot_pb_w );
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||
|
||||
// device_ieee488_interface overrides
|
||||
virtual void ieee488_atn(int state);
|
||||
virtual void ieee488_ifc(int state);
|
||||
|
||||
inline void byte_ready(int state);
|
||||
inline void update_ieee_signals();
|
||||
inline void update_gcr_data();
|
||||
inline void read_current_track(int unit);
|
||||
inline void spindle_motor(int unit, int mtr);
|
||||
inline void micropolis_step_motor(int unit, int stp);
|
||||
inline void mpi_step_motor(int unit, int stp);
|
||||
|
||||
required_device<m6502_device> m_maincpu;
|
||||
required_device<m6504_device> m_fdccpu;
|
||||
required_device<riot6532_device> m_riot0;
|
||||
required_device<riot6532_device> m_riot1;
|
||||
required_device<mos6530_device> m_miot;
|
||||
required_device<via6522_device> m_via;
|
||||
required_device<legacy_floppy_image_device> m_image0;
|
||||
optional_device<legacy_floppy_image_device> m_image1;
|
||||
required_memory_region m_gcr;
|
||||
required_ioport m_address;
|
||||
|
||||
struct {
|
||||
// motors
|
||||
int m_stp; // stepper motor phase
|
||||
int m_mtr; // spindle motor on
|
||||
|
||||
// track
|
||||
UINT8 m_track_buffer[G64_BUFFER_SIZE]; // track data buffer
|
||||
int m_track_len; // track length
|
||||
int m_buffer_pos; // byte position within track buffer
|
||||
int m_bit_pos; // bit position within track buffer byte
|
||||
|
||||
// devices
|
||||
device_t *m_image;
|
||||
} m_unit[2];
|
||||
|
||||
int m_drive; // selected drive
|
||||
int m_side; // selected side
|
||||
bool m_double_sided;
|
||||
|
||||
// IEEE-488 bus
|
||||
int m_rfdo; // not ready for data output
|
||||
int m_daco; // not data accepted output
|
||||
int m_atna; // attention acknowledge
|
||||
int m_ifc;
|
||||
|
||||
// track
|
||||
int m_ds; // density select
|
||||
int m_bit_count; // GCR bit counter
|
||||
UINT16 m_sr; // GCR data shift register
|
||||
UINT8 m_pi; // parallel data input
|
||||
UINT16 m_i; // GCR encoder/decoded ROM address
|
||||
UINT8 m_e; // GCR encoder/decoded ROM data
|
||||
|
||||
// signals
|
||||
int m_ready; // byte ready
|
||||
int m_mode; // mode select
|
||||
int m_rw; // read/write select
|
||||
int m_miot_irq; // MIOT interrupt
|
||||
|
||||
// timers
|
||||
emu_timer *m_bit_timer;
|
||||
};
|
||||
|
||||
|
||||
// ======================> c8250_device
|
||||
|
||||
class c8250_device : public c8050_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
c8250_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// optional information overrides
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
};
|
||||
|
||||
|
||||
// ======================> c8250lp_device
|
||||
|
||||
class c8250lp_device : public c8050_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
c8250lp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// optional information overrides
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
};
|
||||
|
||||
|
||||
// ======================> sfd1001_device
|
||||
|
||||
class sfd1001_device : public c8050_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sfd1001_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// optional information overrides
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type C8050;
|
||||
extern const device_type C8250;
|
||||
extern const device_type C8250LP;
|
||||
extern const device_type SFD1001;
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -373,6 +373,7 @@ UINT8 ieee488_device::get_data()
|
||||
// slot devices
|
||||
#include "c2031.h"
|
||||
#include "c2040.h"
|
||||
#include "c8050.h"
|
||||
#include "c8280.h"
|
||||
#include "d9060.h"
|
||||
#include "hardbox.h"
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define __PET__
|
||||
|
||||
#include "emu.h"
|
||||
#include "bus/ieee488/c8050.h"
|
||||
#include "bus/ieee488/ieee488.h"
|
||||
#include "bus/pet/cass.h"
|
||||
#include "bus/pet/exp.h"
|
||||
|
Loading…
Reference in New Issue
Block a user