mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
(MESS) pet: Refactored the Commodore 8050/8250/SFD-1001 to use the new floppy system. [Curt Coder]
This commit is contained in:
parent
3d71f6ab19
commit
a43d6473de
@ -9,6 +9,15 @@
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
|
||||
- write protect
|
||||
- separate read/write methods
|
||||
|
||||
*/
|
||||
|
||||
#include "c2040fdc.h"
|
||||
|
||||
|
||||
@ -310,7 +319,7 @@ void c2040_fdc_t::live_run(const attotime &limit)
|
||||
!(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) {
|
||||
if (!cur_live.rw_sel) { // TODO WPS
|
||||
write_next_bit(BIT(cur_live.shift_reg_write, 9), limit);
|
||||
}
|
||||
|
||||
|
@ -36,10 +36,10 @@
|
||||
#define M6502_TAG "un1"
|
||||
#define M6532_0_TAG "uc1"
|
||||
#define M6532_1_TAG "ue1"
|
||||
|
||||
#define M6504_TAG "uh3"
|
||||
#define M6522_TAG "um3"
|
||||
#define M6530_TAG "uk3"
|
||||
#define FDC_TAG "fdc"
|
||||
|
||||
|
||||
enum
|
||||
@ -51,13 +51,6 @@ enum
|
||||
};
|
||||
|
||||
|
||||
#define SYNC \
|
||||
(!(((m_sr & G64_SYNC_MARK) == G64_SYNC_MARK) & m_rw))
|
||||
|
||||
#define ERROR \
|
||||
(!(m_ready | BIT(m_e, 3)))
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEFINITIONS
|
||||
@ -104,7 +97,7 @@ ROM_START( c8050 ) // schematic 8050001
|
||||
ROMX_LOAD( "901887-01.ul1", 0x0000, 0x2000, CRC(0073b8b2) SHA1(b10603195f240118fe5fb6c6dfe5c5097463d890), ROM_BIOS(4) )
|
||||
ROMX_LOAD( "901888-01.uh1", 0x2000, 0x2000, CRC(de9b6132) SHA1(2e6c2d7ca934e5c550ad14bd5e9e7749686b7af4), ROM_BIOS(4) )
|
||||
|
||||
ROM_REGION( 0x400, M6504_TAG, 0 )
|
||||
ROM_REGION( 0x400, M6530_TAG, 0 )
|
||||
ROM_LOAD_OPTIONAL( "901483-02.uk3", 0x000, 0x400, CRC(d7277f95) SHA1(7607f9357f3a08f2a9f20931058d60d9e3c17d39) ) // 6530-036
|
||||
ROM_LOAD_OPTIONAL( "901483-03.uk3", 0x000, 0x400, CRC(9e83fa70) SHA1(e367ea8a5ddbd47f13570088427293138a10784b) ) // 6530-038 RIOT DOS 2.5 Micropolis
|
||||
ROM_LOAD_OPTIONAL( "901483-04.uk3", 0x000, 0x400, CRC(ae1c7866) SHA1(13bdf0bb387159167534c07a4554964734373f11) ) // 6530-039 RIOT DOS 2.5 Tandon
|
||||
@ -112,9 +105,6 @@ ROM_START( c8050 ) // schematic 8050001
|
||||
ROM_LOAD_OPTIONAL( "901885-01.uk3", 0x000, 0x400, NO_DUMP ) // 6530-044
|
||||
ROM_LOAD_OPTIONAL( "901885-04.uk3", 0x000, 0x400, CRC(bab998c9) SHA1(0dc9a3b60f1b866c63eebd882403532fc59fe57f) ) // 6530-47 RIOT DOS 2.7 Micropolis
|
||||
ROM_LOAD( "901869-01.uk3", 0x000, 0x400, CRC(2915327a) SHA1(3a9a80f72ce76e5f5c72513f8ef7553212912ae3) ) // 6530-48 RIOT DOS 2.7 MPI
|
||||
|
||||
ROM_REGION( 0x800, "gcr", 0)
|
||||
ROM_LOAD( "901467.uk6", 0x000, 0x800, CRC(a23337eb) SHA1(97df576397608455616331f8e837cb3404363fa2) )
|
||||
ROM_END
|
||||
|
||||
|
||||
@ -149,9 +139,6 @@ ROM_START( c8250lp )
|
||||
ROMX_LOAD( "251474-01b", 0x000, 0x400, CRC(9e9a9f90) SHA1(39498d7369a31ea7527b5044071acf35a84ea2ac), ROM_BIOS(1) ) // Matsushita
|
||||
ROMX_LOAD( "fdc-2.7b.bin", 0x000, 0x800, CRC(13a24482) SHA1(1cfa52d2ed245a95e6369b46a36c6c7aa3929931), ROM_BIOS(2) ) // CBM DOS 2.7B FDC ROM from the 8250LP inside 8296D
|
||||
ROMX_LOAD( "speeddos-fdc-f800.bin", 0x000, 0x800, CRC(253e760f) SHA1(3f7892a9bab84b633f45686bbbbe66bc2948c8e5), ROM_BIOS(3) )
|
||||
|
||||
ROM_REGION( 0x800, "gcr", 0)
|
||||
ROM_LOAD( "251167-01.uc1", 0x000, 0x800, BAD_DUMP CRC(a23337eb) SHA1(97df576397608455616331f8e837cb3404363fa2) )
|
||||
ROM_END
|
||||
|
||||
|
||||
@ -174,8 +161,10 @@ ROM_START( sfd1001 ) // schematic 251406
|
||||
ROM_LOAD( "901887-01.1j", 0x0000, 0x2000, CRC(0073b8b2) SHA1(b10603195f240118fe5fb6c6dfe5c5097463d890) )
|
||||
ROM_LOAD( "901888-01.3j", 0x2000, 0x2000, CRC(de9b6132) SHA1(2e6c2d7ca934e5c550ad14bd5e9e7749686b7af4) )
|
||||
|
||||
ROM_REGION( 0x800, M6504_TAG, 0 )
|
||||
ROM_REGION( 0x400, M6530_TAG, 0 )
|
||||
ROM_LOAD( "901885-04.u1", 0x000, 0x400, CRC(bab998c9) SHA1(0dc9a3b60f1b866c63eebd882403532fc59fe57f) )
|
||||
|
||||
ROM_REGION( 0x800, M6504_TAG, 0 )
|
||||
ROM_LOAD( "251257-02a.u2", 0x000, 0x800, CRC(b51150de) SHA1(3b954eb34f7ea088eed1d33ebc6d6e83a3e9be15) )
|
||||
|
||||
ROM_REGION( 0x800, "gcr", 0)
|
||||
@ -216,14 +205,14 @@ ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( c8050_fdc_mem, AS_PROGRAM, 8, c8050_device )
|
||||
ADDRESS_MAP_GLOBAL_MASK(0x1fff)
|
||||
AM_RANGE(0x0000, 0x003f) AM_MIRROR(0x0300) AM_RAM // 6530
|
||||
AM_RANGE(0x0040, 0x004f) AM_MIRROR(0x0330) AM_DEVREADWRITE(M6522_TAG, via6522_device, read, write)
|
||||
AM_RANGE(0x0080, 0x008f) AM_MIRROR(0x0330) AM_DEVREADWRITE(M6530_TAG, mos6530_device, read, write)
|
||||
AM_RANGE(0x0000, 0x003f) AM_MIRROR(0x0300) AM_DEVICE(M6530_TAG, mos6530_t, ram_map)
|
||||
AM_RANGE(0x0040, 0x004f) AM_MIRROR(0x0330) AM_DEVICE(M6522_TAG, via6522_device, map)
|
||||
AM_RANGE(0x0080, 0x008f) AM_MIRROR(0x0330) AM_DEVICE(M6530_TAG, mos6530_t, io_map)
|
||||
AM_RANGE(0x0400, 0x07ff) AM_RAM AM_SHARE("share1")
|
||||
AM_RANGE(0x0800, 0x0bff) AM_RAM AM_SHARE("share2")
|
||||
AM_RANGE(0x0c00, 0x0fff) AM_RAM AM_SHARE("share3")
|
||||
AM_RANGE(0x1000, 0x13ff) AM_RAM AM_SHARE("share4")
|
||||
AM_RANGE(0x1c00, 0x1fff) AM_ROM AM_REGION(M6504_TAG, 0)
|
||||
AM_RANGE(0x1c00, 0x1fff) AM_DEVICE(M6530_TAG, mos6530_t, rom_map)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
@ -233,9 +222,9 @@ ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( c8250lp_fdc_mem, AS_PROGRAM, 8, c8050_device )
|
||||
ADDRESS_MAP_GLOBAL_MASK(0x1fff)
|
||||
AM_RANGE(0x0000, 0x003f) AM_MIRROR(0x0300) AM_RAM // 6530
|
||||
AM_RANGE(0x0040, 0x004f) AM_MIRROR(0x0330) AM_DEVREADWRITE(M6522_TAG, via6522_device, read, write)
|
||||
AM_RANGE(0x0080, 0x008f) AM_MIRROR(0x0330) AM_DEVREADWRITE(M6530_TAG, mos6530_device, read, write)
|
||||
AM_RANGE(0x0000, 0x003f) AM_MIRROR(0x0300) AM_DEVICE(M6530_TAG, mos6530_t, ram_map)
|
||||
AM_RANGE(0x0040, 0x004f) AM_MIRROR(0x0330) AM_DEVICE(M6522_TAG, via6522_device, map)
|
||||
AM_RANGE(0x0080, 0x008f) AM_MIRROR(0x0330) AM_DEVICE(M6530_TAG, mos6530_t, io_map)
|
||||
AM_RANGE(0x0400, 0x07ff) AM_RAM AM_SHARE("share1")
|
||||
AM_RANGE(0x0800, 0x0bff) AM_RAM AM_SHARE("share2")
|
||||
AM_RANGE(0x0c00, 0x0fff) AM_RAM AM_SHARE("share3")
|
||||
@ -250,9 +239,9 @@ ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( sfd1001_fdc_mem, AS_PROGRAM, 8, c8050_device )
|
||||
ADDRESS_MAP_GLOBAL_MASK(0x1fff)
|
||||
AM_RANGE(0x0000, 0x003f) AM_MIRROR(0x0300) AM_RAM // 6530
|
||||
AM_RANGE(0x0040, 0x004f) AM_MIRROR(0x0330) AM_DEVREADWRITE(M6522_TAG, via6522_device, read, write)
|
||||
AM_RANGE(0x0080, 0x008f) AM_MIRROR(0x0330) AM_DEVREADWRITE(M6530_TAG, mos6530_device, read, write)
|
||||
AM_RANGE(0x0000, 0x003f) AM_MIRROR(0x0300) AM_DEVICE(M6530_TAG, mos6530_t, ram_map)
|
||||
AM_RANGE(0x0040, 0x004f) AM_MIRROR(0x0330) AM_DEVICE(M6522_TAG, via6522_device, map)
|
||||
AM_RANGE(0x0080, 0x008f) AM_MIRROR(0x0330) AM_DEVICE(M6530_TAG, mos6530_t, io_map)
|
||||
AM_RANGE(0x0400, 0x07ff) AM_RAM AM_SHARE("share1")
|
||||
AM_RANGE(0x0800, 0x0bff) AM_RAM AM_SHARE("share2")
|
||||
AM_RANGE(0x0c00, 0x0fff) AM_RAM AM_SHARE("share3")
|
||||
@ -433,71 +422,6 @@ WRITE8_MEMBER( c8050_device::riot1_pb_w )
|
||||
output_set_led_value(LED_ERR, BIT(data, 5));
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER( c8050_device::via_pa_r )
|
||||
{
|
||||
/*
|
||||
|
||||
bit description
|
||||
|
||||
PA0 E0
|
||||
PA1 E1
|
||||
PA2 I2
|
||||
PA3 E2
|
||||
PA4 E4
|
||||
PA5 E5
|
||||
PA6 I7
|
||||
PA7 E6
|
||||
|
||||
*/
|
||||
|
||||
return (BIT(m_e, 6) << 7) | (BIT(m_i, 7) << 6) | (m_e & 0x33) | (BIT(m_e, 2) << 3) | (m_i & 0x04);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( c8050_device::mode_sel_w )
|
||||
{
|
||||
// mode select
|
||||
m_mode = state;
|
||||
|
||||
update_gcr_data();
|
||||
m_via->write_cb1(ERROR);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( c8050_device::rw_sel_w )
|
||||
{
|
||||
// read/write select
|
||||
m_rw = state;
|
||||
|
||||
update_gcr_data();
|
||||
m_via->write_cb1(ERROR);
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER( c8050_device::via_pb_r )
|
||||
{
|
||||
/*
|
||||
|
||||
bit description
|
||||
|
||||
PB0 S1A
|
||||
PB1 S1B
|
||||
PB2 S0A
|
||||
PB3 S0B
|
||||
PB4 MTR1
|
||||
PB5 MTR0
|
||||
PB6 PULL SYNC
|
||||
PB7 SYNC
|
||||
|
||||
*/
|
||||
|
||||
UINT8 data = 0;
|
||||
|
||||
// SYNC detected
|
||||
data |= SYNC << 7;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( c8050_device::via_pb_w )
|
||||
{
|
||||
/*
|
||||
@ -511,195 +435,82 @@ WRITE8_MEMBER( c8050_device::via_pb_w )
|
||||
PB4 MTR1
|
||||
PB5 MTR0
|
||||
PB6 PULL SYNC
|
||||
PB7 SYNC
|
||||
PB7
|
||||
|
||||
*/
|
||||
|
||||
// spindle motor 1
|
||||
int mtr1 = BIT(data, 4);
|
||||
spindle_motor(1, mtr1);
|
||||
m_fdc->mtr1_w(BIT(data, 4));
|
||||
|
||||
// spindle motor 0
|
||||
int mtr0 = BIT(data, 5);
|
||||
spindle_motor(0, mtr0);
|
||||
m_fdc->mtr0_w(BIT(data, 5));
|
||||
|
||||
// stepper motor 1
|
||||
int s1 = data & 0x03;
|
||||
mpi_step_motor(1, s1);
|
||||
m_fdc->stp1_w(data & 0x03);
|
||||
|
||||
// stepper motor 0
|
||||
int s0 = (data >> 2) & 0x03;
|
||||
mpi_step_motor(0, s0);
|
||||
m_fdc->stp0_w((data >> 2) & 0x03);
|
||||
|
||||
m_bit_timer->enable(!mtr1 || !mtr0);
|
||||
// PLL sync
|
||||
m_fdc->pull_sync_w(!BIT(data, 6));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mos6530 uk3
|
||||
// SLOT_INTERFACE( c8050_floppies )
|
||||
//-------------------------------------------------
|
||||
|
||||
READ8_MEMBER( c8050_device::pi_r )
|
||||
{
|
||||
/*
|
||||
|
||||
bit description
|
||||
|
||||
PA0 PI0
|
||||
PA1 PI1
|
||||
PA2 PI2
|
||||
PA3 PI3
|
||||
PA4 PI4
|
||||
PA5 PI5
|
||||
PA6 PI6
|
||||
PA7 PI7
|
||||
|
||||
*/
|
||||
|
||||
return m_pi;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( c8050_device::pi_w )
|
||||
{
|
||||
/*
|
||||
|
||||
bit description
|
||||
|
||||
PA0 PI0
|
||||
PA1 PI1
|
||||
PA2 PI2
|
||||
PA3 PI3
|
||||
PA4 PI4
|
||||
PA5 PI5
|
||||
PA6 PI6
|
||||
PA7 PI7
|
||||
|
||||
*/
|
||||
|
||||
m_pi = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER( c8050_device::miot_pb_r )
|
||||
{
|
||||
/*
|
||||
|
||||
bit description
|
||||
|
||||
PB0 DRV SEL
|
||||
PB1 DS0
|
||||
PB2 DS1
|
||||
PB3 WPS
|
||||
PB4 DRIVE TYPE (0=2A, 1=2C)
|
||||
PB5
|
||||
PB6 (0=DS, 1=SS)
|
||||
PB7 M6504 IRQ
|
||||
|
||||
*/
|
||||
|
||||
UINT8 data = 0;
|
||||
|
||||
// write protect sense
|
||||
data |= m_unit[m_drive].m_image->floppy_wpt_r() << 3;
|
||||
|
||||
// drive type
|
||||
data |= 0x10;
|
||||
|
||||
// single/dual sided
|
||||
if (!m_double_sided)
|
||||
{
|
||||
data |= 0x40;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( c8050_device::miot_pb_w )
|
||||
{
|
||||
/*
|
||||
|
||||
bit description
|
||||
|
||||
PB0 DRV SEL
|
||||
PB1 DS0
|
||||
PB2 DS1
|
||||
PB3 WPS
|
||||
PB4 ODD HD (0=78-154, 1=1-77)
|
||||
PB5
|
||||
PB6 (0=DS, 1=SS)
|
||||
PB7 M6504 IRQ
|
||||
|
||||
*/
|
||||
|
||||
// drive select
|
||||
if (m_image1)
|
||||
{
|
||||
m_drive = BIT(data, 0);
|
||||
}
|
||||
|
||||
// density select
|
||||
int ds = (data >> 1) & 0x03;
|
||||
|
||||
if (m_ds != ds)
|
||||
{
|
||||
m_bit_timer->adjust(attotime::zero, 0, attotime::from_hz(C8050_BITRATE[ds]));
|
||||
m_ds = ds;
|
||||
}
|
||||
|
||||
// side select
|
||||
if (m_double_sided)
|
||||
{
|
||||
m_side = !BIT(data, 4);
|
||||
}
|
||||
|
||||
// interrupt
|
||||
if (m_miot_irq != BIT(data, 7))
|
||||
{
|
||||
m_fdccpu->set_input_line(M6502_IRQ_LINE, BIT(data, 7) ? CLEAR_LINE : ASSERT_LINE);
|
||||
m_miot_irq = BIT(data, 7);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// LEGACY_FLOPPY_OPTIONS( c8050 )
|
||||
//-------------------------------------------------
|
||||
|
||||
static LEGACY_FLOPPY_OPTIONS_START( c8050 )
|
||||
LEGACY_FLOPPY_OPTION( c8050, "d80", "Commodore 8050 Disk Image", d80_dsk_identify, d64_dsk_construct, NULL, NULL )
|
||||
LEGACY_FLOPPY_OPTIONS_END
|
||||
static SLOT_INTERFACE_START( c8050_floppies )
|
||||
SLOT_INTERFACE( "525ssqd", FLOPPY_525_SSQD )
|
||||
SLOT_INTERFACE_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// LEGACY_FLOPPY_OPTIONS( c8250 )
|
||||
// FLOPPY_FORMATS( floppy_formats )
|
||||
//-------------------------------------------------
|
||||
|
||||
static LEGACY_FLOPPY_OPTIONS_START( c8250 )
|
||||
LEGACY_FLOPPY_OPTION( c8250, "d80", "Commodore 8050 Disk Image", d80_dsk_identify, d64_dsk_construct, NULL, NULL )
|
||||
LEGACY_FLOPPY_OPTION( c8250, "d82", "Commodore 8250/SFD1001 Disk Image", d82_dsk_identify, d64_dsk_construct, NULL, NULL )
|
||||
LEGACY_FLOPPY_OPTIONS_END
|
||||
FLOPPY_FORMATS_MEMBER( c8050_device::floppy_formats )
|
||||
FLOPPY_D80_FORMAT
|
||||
FLOPPY_FORMATS_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// floppy_interface c8050_floppy_interface
|
||||
// SLOT_INTERFACE( c8250_floppies )
|
||||
//-------------------------------------------------
|
||||
|
||||
static const floppy_interface c8050_floppy_interface =
|
||||
{
|
||||
FLOPPY_STANDARD_5_25_SSDD,
|
||||
LEGACY_FLOPPY_OPTIONS_NAME(c8050),
|
||||
"floppy_5_25"
|
||||
};
|
||||
static SLOT_INTERFACE_START( c8250_floppies )
|
||||
SLOT_INTERFACE( "525qd", FLOPPY_525_QD )
|
||||
SLOT_INTERFACE_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// floppy_interface c8250_floppy_interface
|
||||
// FLOPPY_FORMATS( floppy_formats )
|
||||
//-------------------------------------------------
|
||||
|
||||
static const floppy_interface c8250_floppy_interface =
|
||||
{
|
||||
FLOPPY_STANDARD_5_25_DSQD,
|
||||
LEGACY_FLOPPY_OPTIONS_NAME(c8250),
|
||||
"floppy_5_25"
|
||||
};
|
||||
FLOPPY_FORMATS_MEMBER( c8250_device::floppy_formats )
|
||||
FLOPPY_D80_FORMAT,
|
||||
FLOPPY_D82_FORMAT
|
||||
FLOPPY_FORMATS_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// FLOPPY_FORMATS( floppy_formats )
|
||||
//-------------------------------------------------
|
||||
|
||||
FLOPPY_FORMATS_MEMBER( c8250lp_device::floppy_formats )
|
||||
FLOPPY_D80_FORMAT,
|
||||
FLOPPY_D82_FORMAT
|
||||
FLOPPY_FORMATS_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// FLOPPY_FORMATS( floppy_formats )
|
||||
//-------------------------------------------------
|
||||
|
||||
FLOPPY_FORMATS_MEMBER( sfd1001_device::floppy_formats )
|
||||
FLOPPY_D80_FORMAT,
|
||||
FLOPPY_D82_FORMAT
|
||||
FLOPPY_FORMATS_END
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -727,19 +538,27 @@ static MACHINE_CONFIG_FRAGMENT( c8050 )
|
||||
MCFG_CPU_PROGRAM_MAP(c8050_fdc_mem)
|
||||
|
||||
MCFG_DEVICE_ADD(M6522_TAG, VIA6522, XTAL_12MHz/12)
|
||||
MCFG_VIA6522_READPA_HANDLER(READ8(c8050_device, via_pa_r))
|
||||
MCFG_VIA6522_READPB_HANDLER(READ8(c8050_device, via_pb_r))
|
||||
MCFG_VIA6522_READPA_HANDLER(DEVREAD8(FDC_TAG, c8050_fdc_t, read))
|
||||
MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(c8050_device, via_pb_w))
|
||||
MCFG_VIA6522_CA2_HANDLER(WRITELINE(c8050_device, mode_sel_w))
|
||||
MCFG_VIA6522_CB2_HANDLER(WRITELINE(c8050_device, rw_sel_w))
|
||||
MCFG_VIA6522_CA2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, mode_sel_w))
|
||||
MCFG_VIA6522_CB2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, rw_sel_w))
|
||||
|
||||
MCFG_DEVICE_ADD(M6530_TAG, MOS6530, XTAL_12MHz/12)
|
||||
MCFG_MOS6530_IN_PA_CB(READ8(c8050_device, pi_r))
|
||||
MCFG_MOS6530_OUT_PA_CB(WRITE8(c8050_device, pi_w))
|
||||
MCFG_MOS6530_IN_PB_CB(READ8(c8050_device, miot_pb_r))
|
||||
MCFG_MOS6530_OUT_PB_CB(WRITE8(c8050_device, miot_pb_w))
|
||||
MCFG_DEVICE_ADD(M6530_TAG, MOS6530n, XTAL_12MHz/12)
|
||||
MCFG_MOS6530n_IRQ_CB(INPUTLINE(M6504_TAG, M6502_IRQ_LINE))
|
||||
MCFG_MOS6530n_OUT_PA_CB(DEVWRITE8(FDC_TAG, c8050_fdc_t, write))
|
||||
MCFG_MOS6530n_OUT_PB0_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, drv_sel_w))
|
||||
MCFG_MOS6530n_OUT_PB1_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds0_w))
|
||||
MCFG_MOS6530n_OUT_PB2_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds1_w))
|
||||
MCFG_MOS6530n_IN_PB6_CB(VCC) // SINGLE SIDED
|
||||
|
||||
MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(c8050_floppy_interface)
|
||||
MCFG_DEVICE_ADD(FDC_TAG, C8050_FDC, XTAL_12MHz/2)
|
||||
MCFG_C8050_SYNC_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_pb7))
|
||||
MCFG_C8050_READY_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_ca1))
|
||||
MCFG_C8050_BRDY_CALLBACK(INPUTLINE(M6504_TAG, M6502_SET_OVERFLOW)) MCFG_DEVCB_XOR(1)
|
||||
MCFG_C8050_ERROR_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_cb1))
|
||||
MCFG_C8050_WPS_CALLBACK(DEVWRITELINE(M6530_TAG, mos6530_t, pb3_w))
|
||||
MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":0", c8050_floppies, "525ssqd", c8050_device::floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":1", c8050_floppies, "525ssqd", c8050_device::floppy_formats)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
@ -779,19 +598,28 @@ static MACHINE_CONFIG_FRAGMENT( c8250 )
|
||||
MCFG_CPU_PROGRAM_MAP(c8050_fdc_mem)
|
||||
|
||||
MCFG_DEVICE_ADD(M6522_TAG, VIA6522, XTAL_12MHz/12)
|
||||
MCFG_VIA6522_READPA_HANDLER(READ8(c8050_device, via_pa_r))
|
||||
MCFG_VIA6522_READPB_HANDLER(READ8(c8050_device, via_pb_r))
|
||||
MCFG_VIA6522_READPA_HANDLER(DEVREAD8(FDC_TAG, c8050_fdc_t, read))
|
||||
MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(c8050_device, via_pb_w))
|
||||
MCFG_VIA6522_CA2_HANDLER(WRITELINE(c8050_device, mode_sel_w))
|
||||
MCFG_VIA6522_CB2_HANDLER(WRITELINE(c8050_device, rw_sel_w))
|
||||
MCFG_VIA6522_CA2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, mode_sel_w))
|
||||
MCFG_VIA6522_CB2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, rw_sel_w))
|
||||
|
||||
MCFG_DEVICE_ADD(M6530_TAG, MOS6530, XTAL_12MHz/12)
|
||||
MCFG_MOS6530_IN_PA_CB(READ8(c8050_device, pi_r))
|
||||
MCFG_MOS6530_OUT_PA_CB(WRITE8(c8050_device, pi_w))
|
||||
MCFG_MOS6530_IN_PB_CB(READ8(c8050_device, miot_pb_r))
|
||||
MCFG_MOS6530_OUT_PB_CB(WRITE8(c8050_device, miot_pb_w))
|
||||
MCFG_DEVICE_ADD(M6530_TAG, MOS6530n, XTAL_12MHz/12)
|
||||
MCFG_MOS6530n_IRQ_CB(INPUTLINE(M6504_TAG, M6502_IRQ_LINE))
|
||||
MCFG_MOS6530n_OUT_PA_CB(DEVWRITE8(FDC_TAG, c8050_fdc_t, write))
|
||||
MCFG_MOS6530n_OUT_PB0_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, drv_sel_w))
|
||||
MCFG_MOS6530n_OUT_PB1_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds0_w))
|
||||
MCFG_MOS6530n_OUT_PB2_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds1_w))
|
||||
MCFG_MOS6530n_OUT_PB4_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, odd_hd_w))
|
||||
MCFG_MOS6530n_IN_PB6_CB(GND) // DOUBLE SIDED
|
||||
|
||||
MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(c8250_floppy_interface)
|
||||
MCFG_DEVICE_ADD(FDC_TAG, C8050_FDC, XTAL_12MHz/2)
|
||||
MCFG_C8050_SYNC_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_pb7))
|
||||
MCFG_C8050_READY_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_ca1))
|
||||
MCFG_C8050_BRDY_CALLBACK(INPUTLINE(M6504_TAG, M6502_SET_OVERFLOW)) MCFG_DEVCB_XOR(1)
|
||||
MCFG_C8050_ERROR_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_cb1))
|
||||
MCFG_C8050_WPS_CALLBACK(DEVWRITELINE(M6530_TAG, mos6530_t, pb3_w))
|
||||
MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":0", c8250_floppies, "525qd", c8250_device::floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":1", c8250_floppies, "525qd", c8250_device::floppy_formats)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
@ -831,19 +659,28 @@ static MACHINE_CONFIG_FRAGMENT( c8250lp )
|
||||
MCFG_CPU_PROGRAM_MAP(c8250lp_fdc_mem)
|
||||
|
||||
MCFG_DEVICE_ADD(M6522_TAG, VIA6522, XTAL_12MHz/12)
|
||||
MCFG_VIA6522_READPA_HANDLER(READ8(c8050_device, via_pa_r))
|
||||
MCFG_VIA6522_READPB_HANDLER(READ8(c8050_device, via_pb_r))
|
||||
MCFG_VIA6522_READPA_HANDLER(DEVREAD8(FDC_TAG, c8050_fdc_t, read))
|
||||
MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(c8050_device, via_pb_w))
|
||||
MCFG_VIA6522_CA2_HANDLER(WRITELINE(c8050_device, mode_sel_w))
|
||||
MCFG_VIA6522_CB2_HANDLER(WRITELINE(c8050_device, rw_sel_w))
|
||||
MCFG_VIA6522_CA2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, mode_sel_w))
|
||||
MCFG_VIA6522_CB2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, rw_sel_w))
|
||||
|
||||
MCFG_DEVICE_ADD(M6530_TAG, MOS6530, XTAL_12MHz/12)
|
||||
MCFG_MOS6530_IN_PA_CB(READ8(c8050_device, pi_r))
|
||||
MCFG_MOS6530_OUT_PA_CB(WRITE8(c8050_device, pi_w))
|
||||
MCFG_MOS6530_IN_PB_CB(READ8(c8050_device, miot_pb_r))
|
||||
MCFG_MOS6530_OUT_PB_CB(WRITE8(c8050_device, miot_pb_w))
|
||||
MCFG_DEVICE_ADD(M6530_TAG, MOS6530n, XTAL_12MHz/12)
|
||||
MCFG_MOS6530n_IRQ_CB(INPUTLINE(M6504_TAG, M6502_IRQ_LINE))
|
||||
MCFG_MOS6530n_OUT_PA_CB(DEVWRITE8(FDC_TAG, c8050_fdc_t, write))
|
||||
MCFG_MOS6530n_OUT_PB0_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, drv_sel_w))
|
||||
MCFG_MOS6530n_OUT_PB1_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds0_w))
|
||||
MCFG_MOS6530n_OUT_PB2_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds1_w))
|
||||
MCFG_MOS6530n_OUT_PB4_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, odd_hd_w))
|
||||
MCFG_MOS6530n_IN_PB6_CB(GND) // DOUBLE SIDED
|
||||
|
||||
MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(c8250_floppy_interface)
|
||||
MCFG_DEVICE_ADD(FDC_TAG, C8050_FDC, XTAL_12MHz/2)
|
||||
MCFG_C8050_SYNC_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_pb7))
|
||||
MCFG_C8050_READY_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_ca1))
|
||||
MCFG_C8050_BRDY_CALLBACK(INPUTLINE(M6504_TAG, M6502_SET_OVERFLOW)) MCFG_DEVCB_XOR(1)
|
||||
MCFG_C8050_ERROR_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_cb1))
|
||||
MCFG_C8050_WPS_CALLBACK(DEVWRITELINE(M6530_TAG, mos6530_t, pb3_w))
|
||||
MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":0", c8250_floppies, "525qd", c8250lp_device::floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":1", c8250_floppies, "525qd", c8250lp_device::floppy_formats)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
@ -883,19 +720,28 @@ static MACHINE_CONFIG_FRAGMENT( sfd1001 )
|
||||
MCFG_CPU_PROGRAM_MAP(sfd1001_fdc_mem)
|
||||
|
||||
MCFG_DEVICE_ADD(M6522_TAG, VIA6522, XTAL_12MHz/12)
|
||||
MCFG_VIA6522_READPA_HANDLER(READ8(c8050_device, via_pa_r))
|
||||
MCFG_VIA6522_READPB_HANDLER(READ8(c8050_device, via_pb_r))
|
||||
MCFG_VIA6522_READPA_HANDLER(DEVREAD8(FDC_TAG, c8050_fdc_t, read))
|
||||
MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(c8050_device, via_pb_w))
|
||||
MCFG_VIA6522_CA2_HANDLER(WRITELINE(c8050_device, mode_sel_w))
|
||||
MCFG_VIA6522_CB2_HANDLER(WRITELINE(c8050_device, rw_sel_w))
|
||||
MCFG_VIA6522_CA2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, mode_sel_w))
|
||||
MCFG_VIA6522_CB2_HANDLER(DEVWRITELINE(FDC_TAG, c8050_fdc_t, rw_sel_w))
|
||||
|
||||
MCFG_DEVICE_ADD(M6530_TAG, MOS6530, XTAL_12MHz/12)
|
||||
MCFG_MOS6530_IN_PA_CB(READ8(c8050_device, pi_r))
|
||||
MCFG_MOS6530_OUT_PA_CB(WRITE8(c8050_device, pi_w))
|
||||
MCFG_MOS6530_IN_PB_CB(READ8(c8050_device, miot_pb_r))
|
||||
MCFG_MOS6530_OUT_PB_CB(WRITE8(c8050_device, miot_pb_w))
|
||||
MCFG_DEVICE_ADD(M6530_TAG, MOS6530n, XTAL_12MHz/12)
|
||||
MCFG_MOS6530n_IRQ_CB(INPUTLINE(M6504_TAG, M6502_IRQ_LINE))
|
||||
MCFG_MOS6530n_OUT_PA_CB(DEVWRITE8(FDC_TAG, c8050_fdc_t, write))
|
||||
MCFG_MOS6530n_OUT_PB0_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, drv_sel_w))
|
||||
MCFG_MOS6530n_OUT_PB1_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds0_w))
|
||||
MCFG_MOS6530n_OUT_PB2_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, ds1_w))
|
||||
MCFG_MOS6530n_OUT_PB4_CB(DEVWRITELINE(FDC_TAG, c8050_fdc_t, odd_hd_w))
|
||||
MCFG_MOS6530n_IN_PB6_CB(GND) // DOUBLE SIDED
|
||||
|
||||
MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, c8250_floppy_interface)
|
||||
MCFG_DEVICE_ADD(FDC_TAG, C8050_FDC, XTAL_12MHz/2)
|
||||
MCFG_C8050_SYNC_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_pb7))
|
||||
MCFG_C8050_READY_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_ca1))
|
||||
MCFG_C8050_BRDY_CALLBACK(INPUTLINE(M6504_TAG, M6502_SET_OVERFLOW)) MCFG_DEVCB_XOR(1)
|
||||
MCFG_C8050_ERROR_CALLBACK(DEVWRITELINE(M6522_TAG, via6522_device, write_cb1))
|
||||
MCFG_C8050_WPS_CALLBACK(DEVWRITELINE(M6530_TAG, mos6530_t, pb3_w))
|
||||
MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":0", c8250_floppies, "525qd", sfd1001_device::floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD(FDC_TAG ":1", c8250_floppies, NULL, sfd1001_device::floppy_formats)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
@ -958,133 +804,6 @@ inline void c8050_device::update_ieee_signals()
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// update_gcr_data -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void c8050_device::update_gcr_data()
|
||||
{
|
||||
if (m_rw)
|
||||
{
|
||||
/*
|
||||
|
||||
bit description
|
||||
|
||||
I0 SR0
|
||||
I1 SR1
|
||||
I2 SR2
|
||||
I3 SR3
|
||||
I4 SR4
|
||||
I5 SR5
|
||||
I6 SR6
|
||||
I7 SR7
|
||||
I8 SR8
|
||||
I9 SR9
|
||||
I10 R/_W SEL
|
||||
|
||||
*/
|
||||
|
||||
m_i = (m_rw << 10) | (m_sr & 0x3ff);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
|
||||
bit description
|
||||
|
||||
I0 PI0
|
||||
I1 PI1
|
||||
I2 PI2
|
||||
I3 PI3
|
||||
I4 MODE SEL
|
||||
I5 PI4
|
||||
I6 PI5
|
||||
I7 PI6
|
||||
I8 PI7
|
||||
I9 0
|
||||
I10 R/_W SEL
|
||||
|
||||
*/
|
||||
|
||||
m_i = (m_rw << 10) | ((m_pi & 0xf0) << 1) | (m_mode << 4) | (m_pi & 0x0f);
|
||||
}
|
||||
|
||||
m_e = m_gcr->base()[m_i];
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// read_current_track -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void c8050_device::read_current_track(int unit)
|
||||
{
|
||||
m_unit[unit].m_track_len = G64_BUFFER_SIZE;
|
||||
m_unit[unit].m_buffer_pos = 0;
|
||||
m_unit[unit].m_bit_pos = 7;
|
||||
m_bit_count = 0;
|
||||
|
||||
// read track data
|
||||
m_unit[unit].m_image->floppy_drive_read_track_data_info_buffer(m_side, m_unit[unit].m_track_buffer, &m_unit[unit].m_track_len);
|
||||
|
||||
// extract track length
|
||||
m_unit[unit].m_track_len = m_unit[unit].m_image->floppy_drive_get_current_track_size(m_side);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// spindle_motor -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void c8050_device::spindle_motor(int unit, int mtr)
|
||||
{
|
||||
if (m_unit[unit].m_mtr != mtr)
|
||||
{
|
||||
if (!mtr)
|
||||
{
|
||||
// read track data
|
||||
read_current_track(unit);
|
||||
}
|
||||
|
||||
m_unit[unit].m_image->floppy_mon_w(mtr);
|
||||
|
||||
m_unit[unit].m_mtr = mtr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// mpi_step_motor -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void c8050_device::mpi_step_motor(int unit, int stp)
|
||||
{
|
||||
if (!m_unit[unit].m_mtr && (m_unit[unit].m_stp != stp))
|
||||
{
|
||||
int tracks = 0;
|
||||
|
||||
switch (m_unit[unit].m_stp)
|
||||
{
|
||||
case 0: if (stp == 1) tracks++; else if (stp == 2) tracks--; break;
|
||||
case 1: if (stp == 3) tracks++; else if (stp == 0) tracks--; break;
|
||||
case 2: if (stp == 0) tracks++; else if (stp == 3) tracks--; break;
|
||||
case 3: if (stp == 2) tracks++; else if (stp == 1) tracks--; break;
|
||||
}
|
||||
|
||||
if (tracks != 0)
|
||||
{
|
||||
// step read/write head
|
||||
m_unit[unit].m_image->floppy_drive_seek(tracks);
|
||||
|
||||
// read new track data
|
||||
read_current_track(unit);
|
||||
}
|
||||
|
||||
m_unit[unit].m_stp = stp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
@ -1094,83 +813,42 @@ inline void c8050_device::mpi_step_motor(int unit, int stp)
|
||||
// c8050_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
c8050_device::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)
|
||||
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
device_ieee488_interface(mconfig, *this),
|
||||
m_maincpu(*this, M6502_TAG),
|
||||
m_fdccpu(*this, M6504_TAG),
|
||||
m_riot0(*this, M6532_0_TAG),
|
||||
m_riot1(*this, M6532_1_TAG),
|
||||
m_miot(*this, M6530_TAG),
|
||||
m_via(*this, M6522_TAG),
|
||||
m_image0(*this, FLOPPY_0),
|
||||
m_image1(*this, FLOPPY_1),
|
||||
m_gcr(*this, "gcr"),
|
||||
m_address(*this, "ADDRESS"),
|
||||
m_drive(0),
|
||||
m_side(0),
|
||||
m_double_sided(double_sided),
|
||||
m_rfdo(1),
|
||||
m_daco(1),
|
||||
m_atna(1),
|
||||
m_ifc(0),
|
||||
m_ds(-1),
|
||||
m_bit_count(0),
|
||||
m_sr(0),
|
||||
m_pi(0),
|
||||
m_ready(0),
|
||||
m_mode(0),
|
||||
m_rw(0),
|
||||
m_miot_irq(CLEAR_LINE)
|
||||
c8050_device::c8050_device(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, source),
|
||||
device_ieee488_interface(mconfig, *this),
|
||||
m_maincpu(*this, M6502_TAG),
|
||||
m_fdccpu(*this, M6504_TAG),
|
||||
m_riot0(*this, M6532_0_TAG),
|
||||
m_riot1(*this, M6532_1_TAG),
|
||||
m_miot(*this, M6530_TAG),
|
||||
m_via(*this, M6522_TAG),
|
||||
m_floppy0(*this, FDC_TAG ":0"),
|
||||
m_floppy1(*this, FDC_TAG ":1"),
|
||||
m_fdc(*this, FDC_TAG),
|
||||
m_address(*this, "ADDRESS"),
|
||||
m_rfdo(1),
|
||||
m_daco(1),
|
||||
m_atna(1)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_unit[i].m_stp = 0;
|
||||
m_unit[i].m_mtr = 1;
|
||||
m_unit[i].m_track_len = 0;
|
||||
m_unit[i].m_buffer_pos = 0;
|
||||
m_unit[i].m_bit_pos = 0;
|
||||
memset(m_unit[i].m_track_buffer, 0, sizeof(m_unit[i].m_track_buffer));
|
||||
}
|
||||
}
|
||||
|
||||
c8050_device::c8050_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, C8050, "C8050", tag, owner, clock, "c8050", __FILE__),
|
||||
device_ieee488_interface(mconfig, *this),
|
||||
m_maincpu(*this, M6502_TAG),
|
||||
m_fdccpu(*this, M6504_TAG),
|
||||
m_riot0(*this, M6532_0_TAG),
|
||||
m_riot1(*this, M6532_1_TAG),
|
||||
m_miot(*this, M6530_TAG),
|
||||
m_via(*this, M6522_TAG),
|
||||
m_image0(*this, FLOPPY_0),
|
||||
m_image1(*this, FLOPPY_1),
|
||||
m_gcr(*this, "gcr"),
|
||||
m_address(*this, "ADDRESS"),
|
||||
m_drive(0),
|
||||
m_side(0),
|
||||
m_double_sided(false),
|
||||
m_rfdo(1),
|
||||
m_daco(1),
|
||||
m_atna(1),
|
||||
m_ifc(0),
|
||||
m_ds(-1),
|
||||
m_bit_count(0),
|
||||
m_sr(0),
|
||||
m_pi(0),
|
||||
m_ready(0),
|
||||
m_mode(0),
|
||||
m_rw(0),
|
||||
m_miot_irq(CLEAR_LINE)
|
||||
c8050_device::c8050_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, C8050, "C8050", tag, owner, clock, "c8050", __FILE__),
|
||||
device_ieee488_interface(mconfig, *this),
|
||||
m_maincpu(*this, M6502_TAG),
|
||||
m_fdccpu(*this, M6504_TAG),
|
||||
m_riot0(*this, M6532_0_TAG),
|
||||
m_riot1(*this, M6532_1_TAG),
|
||||
m_miot(*this, M6530_TAG),
|
||||
m_via(*this, M6522_TAG),
|
||||
m_floppy0(*this, FDC_TAG ":0"),
|
||||
m_floppy1(*this, FDC_TAG ":1"),
|
||||
m_fdc(*this, FDC_TAG),
|
||||
m_address(*this, "ADDRESS"),
|
||||
m_rfdo(1),
|
||||
m_daco(1),
|
||||
m_atna(1)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
m_unit[i].m_stp = 0;
|
||||
m_unit[i].m_mtr = 1;
|
||||
m_unit[i].m_track_len = 0;
|
||||
m_unit[i].m_buffer_pos = 0;
|
||||
m_unit[i].m_bit_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1178,24 +856,24 @@ c8050_device::c8050_device(const machine_config &mconfig, const char *tag, devic
|
||||
// c8250_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
c8250_device::c8250_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: c8050_device(mconfig, C8250, "C8250", tag, owner, clock, true, "c8250", __FILE__) { }
|
||||
c8250_device::c8250_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
c8050_device(mconfig, C8250, "C8250", tag, owner, clock, "c8250", __FILE__) { }
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// c8250lp_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
c8250lp_device::c8250lp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: c8050_device(mconfig, C8250LP, "C8250LP", tag, owner, clock, true, "c8250lp", __FILE__) { }
|
||||
c8250lp_device::c8250lp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
c8050_device(mconfig, C8250LP, "C8250LP", tag, owner, clock, "c8250lp", __FILE__) { }
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sfd1001_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
sfd1001_device::sfd1001_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: c8050_device(mconfig, SFD1001, "SFD1001", tag, owner, clock, true, "sfd1001", __FILE__) { }
|
||||
sfd1001_device::sfd1001_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
c8050_device(mconfig, SFD1001, "SFD1001", tag, owner, clock, "sfd1001", __FILE__) { }
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -1204,50 +882,13 @@ sfd1001_device::sfd1001_device(const machine_config &mconfig, const char *tag, d
|
||||
|
||||
void c8050_device::device_start()
|
||||
{
|
||||
m_bit_timer = timer_alloc();
|
||||
|
||||
// install image callbacks
|
||||
m_unit[0].m_image = m_image0;
|
||||
|
||||
m_image0->floppy_install_load_proc(c8050_device::on_disk0_change);
|
||||
|
||||
if (m_image1)
|
||||
{
|
||||
m_unit[1].m_image = m_image1;
|
||||
|
||||
m_image1->floppy_install_load_proc(c8050_device::on_disk1_change);
|
||||
}
|
||||
m_fdc->set_floppy(m_floppy0->get_device(), m_floppy1->get_device());
|
||||
|
||||
// register for state saving
|
||||
save_item(NAME(m_drive));
|
||||
save_item(NAME(m_side));
|
||||
save_item(NAME(m_rfdo));
|
||||
save_item(NAME(m_daco));
|
||||
save_item(NAME(m_atna));
|
||||
save_item(NAME(m_ds));
|
||||
save_item(NAME(m_bit_count));
|
||||
save_item(NAME(m_sr));
|
||||
save_item(NAME(m_pi));
|
||||
save_item(NAME(m_i));
|
||||
save_item(NAME(m_e));
|
||||
save_item(NAME(m_ready));
|
||||
save_item(NAME(m_mode));
|
||||
save_item(NAME(m_rw));
|
||||
save_item(NAME(m_miot_irq));
|
||||
save_item(NAME(m_unit[0].m_stp));
|
||||
save_item(NAME(m_unit[0].m_mtr));
|
||||
save_item(NAME(m_unit[0].m_track_len));
|
||||
save_item(NAME(m_unit[0].m_buffer_pos));
|
||||
save_item(NAME(m_unit[0].m_bit_pos));
|
||||
|
||||
if (m_image1)
|
||||
{
|
||||
save_item(NAME(m_unit[1].m_stp));
|
||||
save_item(NAME(m_unit[1].m_mtr));
|
||||
save_item(NAME(m_unit[1].m_track_len));
|
||||
save_item(NAME(m_unit[1].m_buffer_pos));
|
||||
save_item(NAME(m_unit[1].m_bit_pos));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1271,73 +912,11 @@ void c8050_device::device_reset()
|
||||
m_via->reset();
|
||||
|
||||
// turn off spindle motors
|
||||
m_unit[0].m_mtr = m_unit[1].m_mtr = 1;
|
||||
m_fdc->mtr0_w(1);
|
||||
m_fdc->mtr1_w(1);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_timer - handler timer events
|
||||
//-------------------------------------------------
|
||||
|
||||
void c8050_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
int ready = 1;
|
||||
|
||||
// shift in data from the read head
|
||||
m_sr <<= 1;
|
||||
m_sr |= BIT(m_unit[m_drive].m_track_buffer[m_unit[m_drive].m_buffer_pos], m_unit[m_drive].m_bit_pos);
|
||||
|
||||
// update GCR data
|
||||
update_gcr_data();
|
||||
|
||||
// update bit counters
|
||||
m_unit[m_drive].m_bit_pos--;
|
||||
m_bit_count++;
|
||||
|
||||
if (m_unit[m_drive].m_bit_pos < 0)
|
||||
{
|
||||
m_unit[m_drive].m_bit_pos = 7;
|
||||
m_unit[m_drive].m_buffer_pos++;
|
||||
|
||||
if (m_unit[m_drive].m_buffer_pos >= m_unit[m_drive].m_track_len)
|
||||
{
|
||||
// loop to the start of the track
|
||||
m_unit[m_drive].m_buffer_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SYNC)
|
||||
{
|
||||
// SYNC detected
|
||||
m_bit_count = 0;
|
||||
}
|
||||
|
||||
if (m_bit_count == 10)
|
||||
{
|
||||
// byte ready
|
||||
m_bit_count = 0;
|
||||
ready = 0;
|
||||
}
|
||||
|
||||
if (m_ready != ready)
|
||||
{
|
||||
// set byte ready flag
|
||||
m_ready = ready;
|
||||
|
||||
m_via->write_ca1(ready);
|
||||
m_via->write_cb1(ERROR);
|
||||
|
||||
this->byte_ready(ready);
|
||||
}
|
||||
}
|
||||
|
||||
inline void c8050_device::byte_ready(int state)
|
||||
{
|
||||
m_fdccpu->set_input_line(M6502_SET_OVERFLOW, state ? CLEAR_LINE : ASSERT_LINE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ieee488_atn -
|
||||
//-------------------------------------------------
|
||||
@ -1364,27 +943,3 @@ void c8050_device::ieee488_ifc(int state)
|
||||
|
||||
m_ifc = state;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// on_disk0_change -
|
||||
//-------------------------------------------------
|
||||
|
||||
void c8050_device::on_disk0_change(device_image_interface &image)
|
||||
{
|
||||
c8050_device *c8050 = static_cast<c8050_device *>(image.device().owner());
|
||||
|
||||
c8050->read_current_track(0);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// on_disk1_change -
|
||||
//-------------------------------------------------
|
||||
|
||||
void c8050_device::on_disk1_change(device_image_interface &image)
|
||||
{
|
||||
c8050_device *c8050 = static_cast<c8050_device *>(image.device().owner());
|
||||
|
||||
c8050->read_current_track(1);
|
||||
}
|
||||
|
@ -16,32 +16,12 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "ieee488.h"
|
||||
#include "c8050fdc.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"
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MACROS / CONSTANTS
|
||||
//**************************************************************************
|
||||
|
||||
#define G64_BUFFER_SIZE 32768
|
||||
#define G64_SYNC_MARK 0x3ff
|
||||
|
||||
|
||||
const int C8050_BITRATE[] =
|
||||
{
|
||||
XTAL_12MHz/2/16, /* tracks 1-39 */
|
||||
XTAL_12MHz/2/15, /* tracks 40-53 */
|
||||
XTAL_12MHz/2/14, /* tracks 54-65 */
|
||||
XTAL_12MHz/2/13 /* tracks 65-84 */
|
||||
};
|
||||
#include "machine/mos6530n.h"
|
||||
|
||||
|
||||
|
||||
@ -52,11 +32,11 @@ const int C8050_BITRATE[] =
|
||||
// ======================> c8050_device
|
||||
|
||||
class c8050_device : public device_t,
|
||||
public device_ieee488_interface
|
||||
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, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
|
||||
c8050_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// optional information overrides
|
||||
@ -64,96 +44,45 @@ 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_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 );
|
||||
|
||||
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);
|
||||
|
||||
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<mos6530_t> 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_device<floppy_connector> m_floppy0;
|
||||
optional_device<floppy_connector> m_floppy1;
|
||||
required_device<c8050_fdc_t> m_fdc;
|
||||
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
|
||||
legacy_floppy_image_device *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;
|
||||
};
|
||||
|
||||
|
||||
@ -167,6 +96,8 @@ public:
|
||||
|
||||
// optional information overrides
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
DECLARE_FLOPPY_FORMATS( floppy_formats );
|
||||
};
|
||||
|
||||
|
||||
@ -181,6 +112,8 @@ public:
|
||||
// optional information overrides
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
DECLARE_FLOPPY_FORMATS( floppy_formats );
|
||||
};
|
||||
|
||||
|
||||
@ -195,6 +128,8 @@ public:
|
||||
// optional information overrides
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
DECLARE_FLOPPY_FORMATS( floppy_formats );
|
||||
};
|
||||
|
||||
|
||||
|
@ -9,6 +9,16 @@
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
|
||||
- write mode
|
||||
- write protect
|
||||
- separate read/write methods
|
||||
|
||||
*/
|
||||
|
||||
#include "c8050fdc.h"
|
||||
|
||||
|
||||
@ -17,7 +27,7 @@
|
||||
// MACROS / CONSTANTS
|
||||
//**************************************************************************
|
||||
|
||||
#define LOG 1
|
||||
#define LOG 0
|
||||
|
||||
#define GCR_DECODE(_e, _i) \
|
||||
((BIT(_e, 6) << 7) | (BIT(_i, 7) << 6) | (_e & 0x33) | (BIT(_e, 2) << 3) | (_i & 0x04))
|
||||
@ -67,7 +77,9 @@ c8050_fdc_t::c8050_fdc_t(const machine_config &mconfig, const char *tag, device_
|
||||
device_t(mconfig, C8050_FDC, "C8050 FDC", tag, owner, clock, "c8050fdc", __FILE__),
|
||||
m_write_sync(*this),
|
||||
m_write_ready(*this),
|
||||
m_write_brdy(*this),
|
||||
m_write_error(*this),
|
||||
m_write_wps(*this),
|
||||
m_gcr_rom(*this, "gcr"),
|
||||
m_floppy0(NULL),
|
||||
m_floppy1(NULL),
|
||||
@ -78,7 +90,10 @@ c8050_fdc_t::c8050_fdc_t(const machine_config &mconfig, const char *tag, device_
|
||||
m_ds(0),
|
||||
m_drv_sel(0),
|
||||
m_mode_sel(0),
|
||||
m_rw_sel(0)
|
||||
m_rw_sel(0),
|
||||
m_wps(0),
|
||||
m_wps0(0),
|
||||
m_wps1(0)
|
||||
{
|
||||
cur_live.tm = attotime::never;
|
||||
cur_live.state = IDLE;
|
||||
@ -87,7 +102,6 @@ c8050_fdc_t::c8050_fdc_t(const machine_config &mconfig, const char *tag, device_
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
@ -97,7 +111,9 @@ void c8050_fdc_t::device_start()
|
||||
// resolve callbacks
|
||||
m_write_sync.resolve_safe();
|
||||
m_write_ready.resolve_safe();
|
||||
m_write_brdy.resolve_safe();
|
||||
m_write_error.resolve_safe();
|
||||
m_write_wps.resolve_safe();
|
||||
|
||||
// allocate timer
|
||||
t_gen = timer_alloc(0);
|
||||
@ -206,7 +222,47 @@ void c8050_fdc_t::ds_w(int ds)
|
||||
void c8050_fdc_t::set_floppy(floppy_image_device *floppy0, floppy_image_device *floppy1)
|
||||
{
|
||||
m_floppy0 = floppy0;
|
||||
m_floppy1 = floppy1;
|
||||
m_floppy0->setup_wpt_cb(floppy_image_device::wpt_cb(FUNC(c8050_fdc_t::wps0_w), this));
|
||||
|
||||
if (floppy1) {
|
||||
m_floppy1 = floppy1;
|
||||
m_floppy1->setup_wpt_cb(floppy_image_device::wpt_cb(FUNC(c8050_fdc_t::wps1_w), this));
|
||||
}
|
||||
}
|
||||
|
||||
void c8050_fdc_t::update_wps()
|
||||
{
|
||||
int state = m_drv_sel ? m_wps1 : m_wps0;
|
||||
|
||||
if (m_wps != state)
|
||||
{
|
||||
m_wps = state;
|
||||
m_write_wps(m_wps);
|
||||
}
|
||||
}
|
||||
|
||||
void c8050_fdc_t::wps0_w(floppy_image_device *floppy, int state)
|
||||
{
|
||||
if (m_wps0 != state)
|
||||
{
|
||||
live_sync();
|
||||
m_wps0 = state;
|
||||
update_wps();
|
||||
checkpoint();
|
||||
live_run();
|
||||
}
|
||||
}
|
||||
|
||||
void c8050_fdc_t::wps1_w(floppy_image_device *floppy, int state)
|
||||
{
|
||||
if (m_wps1 != state)
|
||||
{
|
||||
live_sync();
|
||||
m_wps0 = state;
|
||||
update_wps();
|
||||
checkpoint();
|
||||
live_run();
|
||||
}
|
||||
}
|
||||
|
||||
void c8050_fdc_t::live_start()
|
||||
@ -225,6 +281,7 @@ void c8050_fdc_t::live_start()
|
||||
cur_live.mode_sel = m_mode_sel;
|
||||
cur_live.rw_sel = m_rw_sel;
|
||||
cur_live.pi = m_pi;
|
||||
cur_live.wps = m_wps;
|
||||
|
||||
pll_reset(cur_live.tm, attotime::from_hz(clock() / (16 - m_ds)));
|
||||
checkpoint_live = cur_live;
|
||||
@ -333,6 +390,7 @@ void c8050_fdc_t::live_abort()
|
||||
cur_live.next_state = -1;
|
||||
|
||||
cur_live.ready = 1;
|
||||
cur_live.brdy = 1;
|
||||
cur_live.sync = 1;
|
||||
cur_live.error = 1;
|
||||
}
|
||||
@ -390,7 +448,8 @@ void c8050_fdc_t::live_run(const attotime &limit)
|
||||
if (LOG) logerror("%s cyl %u bit %u sync %u bc %u sr %03x i %03x e %02x\n",cur_live.tm.as_string(),get_floppy()->get_cyl(),bit,sync,cur_live.bit_counter,cur_live.shift_reg,cur_live.i,cur_live.e);
|
||||
|
||||
// byte ready
|
||||
int ready = !(cur_live.bit_counter == 9);
|
||||
int ready = !(cur_live.bit_counter == 9); // 74190 _RC, should be triggered on the falling edge of the clock
|
||||
int brdy = ready; // 74190 TC
|
||||
|
||||
// GCR error
|
||||
int error = !(ready || BIT(cur_live.e, 3));
|
||||
@ -419,14 +478,20 @@ void c8050_fdc_t::live_run(const attotime &limit)
|
||||
syncpoint = true;
|
||||
}
|
||||
|
||||
if (brdy != cur_live.brdy) {
|
||||
if (LOG) logerror("%s BRDY %u\n", cur_live.tm.as_string(), brdy);
|
||||
cur_live.brdy = brdy;
|
||||
syncpoint = true;
|
||||
}
|
||||
|
||||
if (sync != cur_live.sync) {
|
||||
if (LOG) logerror("%s SYNC %u\n", cur_live.tm.as_string(),sync);
|
||||
if (LOG) logerror("%s SYNC %u\n", cur_live.tm.as_string(), sync);
|
||||
cur_live.sync = sync;
|
||||
syncpoint = true;
|
||||
}
|
||||
|
||||
if (error != cur_live.error) {
|
||||
if (LOG) logerror("%s ERROR %u\n", cur_live.tm.as_string(),error);
|
||||
if (LOG) logerror("%s ERROR %u\n", cur_live.tm.as_string(), error);
|
||||
cur_live.error = error;
|
||||
syncpoint = true;
|
||||
}
|
||||
@ -439,7 +504,12 @@ void c8050_fdc_t::live_run(const attotime &limit)
|
||||
}
|
||||
|
||||
case RUNNING_SYNCPOINT: {
|
||||
if (LOG) {
|
||||
if (!cur_live.sync) logerror("%s SYNC\n",cur_live.tm.as_string());
|
||||
if (!cur_live.ready && cur_live.bit_counter == 9) logerror("%s DATA %02x\n",cur_live.tm.as_string(),GCR_DECODE(cur_live.e,cur_live.i));
|
||||
}
|
||||
m_write_ready(cur_live.ready);
|
||||
m_write_brdy(cur_live.brdy);
|
||||
m_write_sync(cur_live.sync);
|
||||
m_write_error(cur_live.error);
|
||||
|
||||
@ -456,9 +526,9 @@ READ8_MEMBER( c8050_fdc_t::read )
|
||||
UINT8 e = checkpoint_live.e;
|
||||
offs_t i = checkpoint_live.i;
|
||||
|
||||
UINT8 data = (BIT(e, 6) << 7) | (BIT(i, 7) << 6) | (e & 0x33) | (BIT(e, 2) << 3) | (i & 0x04);
|
||||
UINT8 data = GCR_DECODE(e, i);
|
||||
|
||||
if (LOG) logerror("%s %s VIA reads data %02x (%03x)\n", machine().time().as_string(), machine().describe_context(), data, checkpoint_live.shift_reg);
|
||||
if (LOG)logerror("%s %s VIA reads data %02x (%03x)\n", machine().time().as_string(), machine().describe_context(), data, checkpoint_live.shift_reg);
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -475,12 +545,25 @@ WRITE8_MEMBER( c8050_fdc_t::write )
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( c8050_fdc_t::ds0_w )
|
||||
{
|
||||
m_ds0 = state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( c8050_fdc_t::ds1_w )
|
||||
{
|
||||
m_ds1 = state;
|
||||
|
||||
ds_w(m_ds1 << 1 | m_ds0);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( c8050_fdc_t::drv_sel_w )
|
||||
{
|
||||
if (m_drv_sel != state)
|
||||
{
|
||||
live_sync();
|
||||
m_drv_sel = cur_live.drv_sel = state;
|
||||
update_wps();
|
||||
checkpoint();
|
||||
if (LOG) logerror("%s %s DRV SEL %u\n", machine().time().as_string(), machine().describe_context(), state);
|
||||
live_run();
|
||||
@ -576,6 +659,5 @@ WRITE_LINE_MEMBER( c8050_fdc_t::odd_hd_w )
|
||||
|
||||
WRITE_LINE_MEMBER( c8050_fdc_t::pull_sync_w )
|
||||
{
|
||||
// TODO
|
||||
if (LOG) logerror("%s %s PULL SYNC %u\n", machine().time().as_string(), machine().describe_context(), state);
|
||||
}
|
||||
|
@ -32,9 +32,15 @@
|
||||
#define MCFG_C8050_READY_CALLBACK(_write) \
|
||||
devcb = &c8050_fdc_t::set_ready_wr_callback(*device, DEVCB_##_write);
|
||||
|
||||
#define MCFG_C8050_BRDY_CALLBACK(_write) \
|
||||
devcb = &c8050_fdc_t::set_brdy_wr_callback(*device, DEVCB_##_write);
|
||||
|
||||
#define MCFG_C8050_ERROR_CALLBACK(_write) \
|
||||
devcb = &c8050_fdc_t::set_error_wr_callback(*device, DEVCB_##_write);
|
||||
|
||||
#define MCFG_C8050_WPS_CALLBACK(_write) \
|
||||
devcb = &c8050_fdc_t::set_wps_wr_callback(*device, DEVCB_##_write);
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
@ -51,11 +57,15 @@ public:
|
||||
|
||||
template<class _Object> static devcb_base &set_sync_wr_callback(device_t &device, _Object object) { return downcast<c8050_fdc_t &>(device).m_write_sync.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_ready_wr_callback(device_t &device, _Object object) { return downcast<c8050_fdc_t &>(device).m_write_ready.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_brdy_wr_callback(device_t &device, _Object object) { return downcast<c8050_fdc_t &>(device).m_write_brdy.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_error_wr_callback(device_t &device, _Object object) { return downcast<c8050_fdc_t &>(device).m_write_error.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_wps_wr_callback(device_t &device, _Object object) { return downcast<c8050_fdc_t &>(device).m_write_wps.set_callback(object); }
|
||||
|
||||
DECLARE_READ8_MEMBER( read );
|
||||
DECLARE_WRITE8_MEMBER( write );
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( ds0_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( ds1_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( drv_sel_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( mode_sel_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( rw_sel_w );
|
||||
@ -64,13 +74,13 @@ public:
|
||||
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(); }
|
||||
|
||||
void stp0_w(int stp);
|
||||
void stp1_w(int stp);
|
||||
void ds_w(int ds);
|
||||
|
||||
void set_floppy(floppy_image_device *floppy0, floppy_image_device *floppy1);
|
||||
void wps0_w(floppy_image_device *floppy, int state);
|
||||
void wps1_w(floppy_image_device *floppy, int state);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -82,6 +92,7 @@ protected:
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
|
||||
void stp_w(floppy_image_device *floppy, int mtr, int &old_stp, int stp);
|
||||
void update_wps();
|
||||
|
||||
enum {
|
||||
IDLE,
|
||||
@ -94,6 +105,7 @@ protected:
|
||||
int state, next_state;
|
||||
int sync;
|
||||
int ready;
|
||||
int brdy;
|
||||
int error;
|
||||
int ds;
|
||||
int drv_sel;
|
||||
@ -111,11 +123,14 @@ protected:
|
||||
|
||||
UINT8 pi;
|
||||
UINT16 shift_reg_write;
|
||||
int wps;
|
||||
};
|
||||
|
||||
devcb_write_line m_write_sync;
|
||||
devcb_write_line m_write_ready;
|
||||
devcb_write_line m_write_brdy;
|
||||
devcb_write_line m_write_error;
|
||||
devcb_write_line m_write_wps;
|
||||
|
||||
required_memory_region m_gcr_rom;
|
||||
|
||||
@ -127,11 +142,16 @@ protected:
|
||||
int m_stp0;
|
||||
int m_stp1;
|
||||
int m_ds;
|
||||
int m_ds0;
|
||||
int m_ds1;
|
||||
int m_drv_sel;
|
||||
int m_mode_sel;
|
||||
int m_rw_sel;
|
||||
int m_odd_hd;
|
||||
UINT8 m_pi;
|
||||
int m_wps;
|
||||
int m_wps0;
|
||||
int m_wps1;
|
||||
|
||||
live_info cur_live, checkpoint_live;
|
||||
fdc_pll_t cur_pll, checkpoint_pll;
|
||||
|
@ -15,9 +15,9 @@
|
||||
|
||||
http://personalpages.tds.net/~rcarlsen/cbm/1541/1541%20EARLY/1540-2.GIF
|
||||
|
||||
- write
|
||||
- write protect
|
||||
- separate read/write methods
|
||||
- cycle exact VIA
|
||||
|
||||
- get these running and we're golden
|
||||
- Bounty Bob Strikes Back (aligned halftracks)
|
||||
- Quiwi (speed change within track)
|
||||
@ -306,7 +306,7 @@ void c64h156_device::live_run(const attotime &limit)
|
||||
syncpoint = true;
|
||||
}
|
||||
|
||||
if (BIT(cell_counter, 1) && !BIT(cur_live.cell_counter, 1) && !cur_live.oe) {
|
||||
if (BIT(cell_counter, 1) && !BIT(cur_live.cell_counter, 1) && !cur_live.oe) { // TODO WPS
|
||||
write_next_bit(BIT(cur_live.shift_reg_write, 7), limit);
|
||||
}
|
||||
|
||||
|
@ -493,6 +493,8 @@ void via6522_device::output_pb()
|
||||
READ8_MEMBER( via6522_device::read )
|
||||
{
|
||||
int val = 0;
|
||||
if (space.debugger_access())
|
||||
return 0;
|
||||
|
||||
offset &= 0xf;
|
||||
|
||||
|
@ -391,6 +391,9 @@ READ8_MEMBER( mos6530_t::timer_r )
|
||||
{
|
||||
UINT8 data = 0;
|
||||
|
||||
if (space.debugger_access())
|
||||
return 0;
|
||||
|
||||
if (offset & 0x01)
|
||||
{
|
||||
data = m_irq ? 0x80 : 0x00;
|
||||
@ -565,7 +568,7 @@ void mos6530_t::live_run(const attotime &limit)
|
||||
}
|
||||
|
||||
case RUNNING_SYNCPOINT: {
|
||||
logerror("%s MOS6530 '%s' IRQ\n", machine().time().as_string(), tag());
|
||||
if (LOG) logerror("%s MOS6530 '%s' IRQ\n", machine().time().as_string(), tag());
|
||||
|
||||
m_irq = true;
|
||||
update_pb();
|
||||
|
@ -245,852 +245,3 @@ bool d64_format::supports_save() const
|
||||
}
|
||||
|
||||
const floppy_format_type FLOPPY_D64_FORMAT = &floppy_image_format_creator<d64_format>;
|
||||
|
||||
|
||||
// ------ LEGACY -----
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
formats/d64_dsk.c
|
||||
|
||||
Floppy format code for Commodore 1541/2040/8050 disk images
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
|
||||
- write to disk
|
||||
- disk errors 24, 25, 26, 28, 74
|
||||
- variable gaps
|
||||
|
||||
*/
|
||||
|
||||
#define XTAL_16MHz 16000000
|
||||
#define XTAL_12MHz 12000000
|
||||
#include "g64_dsk.h"
|
||||
#include "flopimg.h"
|
||||
#include "d64_dsk.h"
|
||||
|
||||
/***************************************************************************
|
||||
PARAMETERS
|
||||
***************************************************************************/
|
||||
|
||||
#define MAX_HEADS 2
|
||||
#define MAX_TRACKS 84
|
||||
#define MAX_ERROR_SECTORS 4166
|
||||
#define SECTOR_SIZE 256
|
||||
#define SECTOR_SIZE_GCR 368
|
||||
|
||||
#define INVALID_OFFSET 0xbadbad
|
||||
|
||||
#define D64_SIZE_35_TRACKS 174848
|
||||
#define D64_SIZE_35_TRACKS_WITH_ERRORS 175531
|
||||
#define D64_SIZE_40_TRACKS 196608
|
||||
#define D64_SIZE_40_TRACKS_WITH_ERRORS 197376
|
||||
#define D64_SIZE_42_TRACKS 205312
|
||||
#define D64_SIZE_42_TRACKS_WITH_ERRORS 206114
|
||||
#define D67_SIZE_35_TRACKS 176640
|
||||
#define D71_SIZE_70_TRACKS 349696
|
||||
#define D71_SIZE_70_TRACKS_WITH_ERRORS 351062
|
||||
#define D80_SIZE_77_TRACKS 533248
|
||||
#define D80_SIZE_77_TRACKS_WITH_ERRORS 535331
|
||||
#define D82_SIZE_154_TRACKS 1066496
|
||||
#define D82_SIZE_154_TRACKS_WITH_ERRORS 1070662
|
||||
|
||||
#define G64_SPEED_BLOCK_SIZE 1982
|
||||
|
||||
enum
|
||||
{
|
||||
DOS1,
|
||||
DOS2,
|
||||
DOS25
|
||||
};
|
||||
|
||||
static const char *const DOS_VERSION[] = { "1.0", "2.0", "2.5" };
|
||||
|
||||
enum
|
||||
{
|
||||
ERROR_00 = 1,
|
||||
ERROR_20, /* header block not found */
|
||||
ERROR_21, /* no sync character */
|
||||
ERROR_22, /* data block not present */
|
||||
ERROR_23, /* checksum error in data block */
|
||||
ERROR_24, /* write verify (on format) UNIMPLEMENTED */
|
||||
ERROR_25, /* write verify error UNIMPLEMENTED */
|
||||
ERROR_26, /* write protect on UNIMPLEMENTED */
|
||||
ERROR_27, /* checksum error in header block */
|
||||
ERROR_28, /* write error UNIMPLEMENTED */
|
||||
ERROR_29, /* disk ID mismatch */
|
||||
ERROR_74, /* disk not ready (no device 1) UNIMPLEMENTED */
|
||||
};
|
||||
|
||||
static const char *const ERROR_CODE[] = { "00", "00", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "74" };
|
||||
|
||||
static const UINT8 bin_2_gcr[] =
|
||||
{
|
||||
0x0a, 0x0b, 0x12, 0x13, 0x0e, 0x0f, 0x16, 0x17,
|
||||
0x09, 0x19, 0x1a, 0x1b, 0x0d, 0x1d, 0x1e, 0x15
|
||||
};
|
||||
|
||||
/* This could be of use if we ever implement saving in .d64 format, to convert back GCR -> d64 */
|
||||
/*
|
||||
static const int gcr_2_bin[] =
|
||||
{
|
||||
-1, -1, -1, -1,
|
||||
-1, -1, -1, -1,
|
||||
-1, 0x08, 0x00, 0x01,
|
||||
-1, 0x0c, 0x04, 0x05,
|
||||
-1, -1, 0x02, 0x03,
|
||||
-1, 0x0f, 0x06, 0x07,
|
||||
-1, 0x09, 0x0a, 0x0b,
|
||||
-1, 0x0d, 0x0e, -1
|
||||
};
|
||||
*/
|
||||
|
||||
static const int DOS1_SECTORS_PER_TRACK[] =
|
||||
{
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
20, 20, 20, 20, 20, 20, 20,
|
||||
18, 18, 18, 18, 18, 18,
|
||||
17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17,
|
||||
17, 17
|
||||
};
|
||||
|
||||
static const int DOS1_SPEED_ZONE[] =
|
||||
{
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 2, 2,
|
||||
1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0
|
||||
};
|
||||
|
||||
static const int DOS2_SECTORS_PER_TRACK[] =
|
||||
{
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
19, 19, 19, 19, 19, 19, 19,
|
||||
18, 18, 18, 18, 18, 18,
|
||||
17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17,
|
||||
17, 17
|
||||
};
|
||||
|
||||
static const int DOS25_SECTORS_PER_TRACK[] =
|
||||
{
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, /* 1-39 */
|
||||
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, /* 40-53 */
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, /* 54-64 */
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, /* 65-77 */
|
||||
23, 23, 23, 23, 23, 23, 23 /* 78-84 */
|
||||
};
|
||||
|
||||
static const int DOS25_SPEED_ZONE[] =
|
||||
{
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 1-39 */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 40-53 */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 54-64 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 65-77 */
|
||||
0, 0, 0, 0, 0, 0, 0 /* 78-84 */
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
struct d64dsk_tag
|
||||
{
|
||||
int dos; /* CBM DOS version */
|
||||
int heads; /* number of physical heads */
|
||||
int tracks; /* number of physical tracks */
|
||||
int dos_tracks; /* number of logical tracks */
|
||||
int track_offset[MAX_HEADS][MAX_TRACKS]; /* offset within image for each physical track */
|
||||
UINT32 speed_zone[MAX_TRACKS]; /* speed zone for each physical track */
|
||||
bool has_errors; /* flag to check for available error codes */
|
||||
UINT8 error[MAX_ERROR_SECTORS]; /* error code for each logical sector */
|
||||
int error_offset[MAX_HEADS][MAX_TRACKS]; /* offset within error array for sector 0 of each logical track */
|
||||
|
||||
UINT8 id1, id2; /* DOS disk format ID */
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
INLINE FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
INLINE struct d64dsk_tag *get_tag(floppy_image_legacy *floppy)
|
||||
{
|
||||
return (d64dsk_tag *)floppy_tag(floppy);
|
||||
}
|
||||
|
||||
INLINE float get_dos_track(int track)
|
||||
{
|
||||
return ((float)track / 2) + 1;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
IMPLEMENTATION
|
||||
***************************************************************************/
|
||||
|
||||
/*-------------------------------------------------
|
||||
d64_get_heads_per_disk - returns the number
|
||||
of heads in the disk image
|
||||
-------------------------------------------------*/
|
||||
|
||||
static int d64_get_heads_per_disk(floppy_image_legacy *floppy)
|
||||
{
|
||||
return get_tag(floppy)->heads;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
d64_get_tracks_per_disk - returns the number
|
||||
of DOS tracks in the disk image
|
||||
-------------------------------------------------*/
|
||||
|
||||
static int d64_get_tracks_per_disk(floppy_image_legacy *floppy)
|
||||
{
|
||||
return get_tag(floppy)->tracks;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
d64_get_sectors_per_track - returns the number
|
||||
of sectors per given track
|
||||
-------------------------------------------------*/
|
||||
|
||||
static int d64_get_sectors_per_track(floppy_image_legacy *floppy, int head, int track)
|
||||
{
|
||||
int sectors_per_track = 0;
|
||||
|
||||
switch (get_tag(floppy)->dos)
|
||||
{
|
||||
case DOS1: sectors_per_track = DOS1_SECTORS_PER_TRACK[track / 2]; break;
|
||||
case DOS2: sectors_per_track = DOS2_SECTORS_PER_TRACK[track / 2]; break;
|
||||
case DOS25: sectors_per_track = DOS25_SECTORS_PER_TRACK[track]; break;
|
||||
}
|
||||
|
||||
return sectors_per_track;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
get_track_offset - returns the offset within
|
||||
the disk image for a given track
|
||||
-------------------------------------------------*/
|
||||
|
||||
static floperr_t get_track_offset(floppy_image_legacy *floppy, int head, int track, UINT64 *offset)
|
||||
{
|
||||
struct d64dsk_tag *tag = get_tag(floppy);
|
||||
UINT64 offs = 0;
|
||||
|
||||
if ((track < 0) || (track >= tag->tracks))
|
||||
return FLOPPY_ERROR_SEEKERROR;
|
||||
|
||||
offs = tag->track_offset[head][track];
|
||||
|
||||
if (offset)
|
||||
*offset = offs;
|
||||
|
||||
return FLOPPY_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
d64_get_track_size - returns the track size
|
||||
-------------------------------------------------*/
|
||||
|
||||
static UINT32 d64_get_track_size(floppy_image_legacy *floppy, int head, int track)
|
||||
{
|
||||
struct d64dsk_tag *tag = get_tag(floppy);
|
||||
|
||||
if (tag->track_offset[head][track] == INVALID_OFFSET)
|
||||
return 0;
|
||||
|
||||
/* determine number of sectors per track */
|
||||
int sectors_per_track = d64_get_sectors_per_track(floppy, head, track);
|
||||
|
||||
/* allocate temporary GCR track data buffer */
|
||||
UINT32 track_length = sectors_per_track * SECTOR_SIZE_GCR;
|
||||
|
||||
return track_length;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
get_sector_error_code - returns the error
|
||||
code for the given sector
|
||||
-------------------------------------------------*/
|
||||
|
||||
static int get_sector_error_code(floppy_image_legacy *floppy, int head, int dos_track, int sector)
|
||||
{
|
||||
struct d64dsk_tag *tag = get_tag(floppy);
|
||||
|
||||
if (!tag->has_errors)
|
||||
return ERROR_00;
|
||||
|
||||
int sector_error = tag->error[tag->error_offset[head][dos_track] + sector]; // TODO index out of bounds!!!
|
||||
|
||||
if (sector_error != ERROR_00)
|
||||
{
|
||||
LOG_FORMATS("D64 error %s head %d track %d sector %d\n", ERROR_CODE[sector_error], head, dos_track, sector);
|
||||
}
|
||||
|
||||
return sector_error;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
gcr_double_2_gcr - GCR decodes given data
|
||||
-------------------------------------------------*/
|
||||
|
||||
/* gcr_double_2_gcr takes 4 bytes (a, b, c, d) and shuffles their nibbles to obtain 5 bytes in dest */
|
||||
/* The result is basically res = (enc(a) << 15) | (enc(b) << 10) | (enc(c) << 5) | enc(d)
|
||||
* with res being 5 bytes long and enc(x) being the GCR encode of x.
|
||||
* In fact, we store the result as five separate bytes in the dest argument
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Commodore GCR format
|
||||
|
||||
Original Encoded
|
||||
4 bits 5 bits
|
||||
|
||||
0000 -> 01010 = 0x0a
|
||||
0001 -> 01011 = 0x0b
|
||||
0010 -> 10010 = 0x12
|
||||
0011 -> 10011 = 0x13
|
||||
0100 -> 01110 = 0x0e
|
||||
0101 -> 01111 = 0x0f
|
||||
0110 -> 10110 = 0x16
|
||||
0111 -> 10111 = 0x17
|
||||
1000 -> 01001 = 0x09
|
||||
1001 -> 11001 = 0x19
|
||||
1010 -> 11010 = 0x1a
|
||||
1011 -> 11011 = 0x1b
|
||||
1100 -> 01101 = 0x0d
|
||||
1101 -> 11101 = 0x1d
|
||||
1110 -> 11110 = 0x1e
|
||||
1111 -> 10101 = 0x15
|
||||
|
||||
We use the encoded values in bytes because we use them to encode
|
||||
groups of 4 bytes into groups of 5 bytes, below.
|
||||
|
||||
*/
|
||||
|
||||
static void gcr_double_2_gcr(UINT8 a, UINT8 b, UINT8 c, UINT8 d, UINT8 *dest)
|
||||
{
|
||||
UINT8 gcr[8];
|
||||
|
||||
/* Encode each nibble to 5 bits */
|
||||
gcr[0] = bin_2_gcr[a >> 4];
|
||||
gcr[1] = bin_2_gcr[a & 0x0f];
|
||||
gcr[2] = bin_2_gcr[b >> 4];
|
||||
gcr[3] = bin_2_gcr[b & 0x0f];
|
||||
gcr[4] = bin_2_gcr[c >> 4];
|
||||
gcr[5] = bin_2_gcr[c & 0x0f];
|
||||
gcr[6] = bin_2_gcr[d >> 4];
|
||||
gcr[7] = bin_2_gcr[d & 0x0f];
|
||||
|
||||
/* Re-order the encoded data to only keep the 5 lower bits of each byte */
|
||||
dest[0] = (gcr[0] << 3) | (gcr[1] >> 2);
|
||||
dest[1] = (gcr[1] << 6) | (gcr[2] << 1) | (gcr[3] >> 4);
|
||||
dest[2] = (gcr[3] << 4) | (gcr[4] >> 1);
|
||||
dest[3] = (gcr[4] << 7) | (gcr[5] << 2) | (gcr[6] >> 3);
|
||||
dest[4] = (gcr[6] << 5) | gcr[7];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
d64_read_track - reads a full track from the
|
||||
disk image
|
||||
-------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
||||
Commodore sector format
|
||||
|
||||
SYNC FF * 5
|
||||
08
|
||||
CHECKSUM sector ^ track ^ id2 ^ id1
|
||||
SECTOR 0..20 (2040), 0..28 (8050)
|
||||
TRACK 1..35 (2040), 1..77 (8050), 1..70 (1571)
|
||||
ID2
|
||||
ID1
|
||||
GAP 1 55 * 9 (2040), 55 * 8 (1541)
|
||||
|
||||
SYNC FF * 5
|
||||
07
|
||||
NEXT TRACK
|
||||
NEXT SECTOR
|
||||
254 BYTES OF DATA
|
||||
CHECKSUM
|
||||
GAP 2 55 * 8..19
|
||||
|
||||
*/
|
||||
|
||||
static floperr_t d64_read_track(floppy_image_legacy *floppy, int head, int track, UINT64 offset, void *buffer, size_t buflen)
|
||||
{
|
||||
struct d64dsk_tag *tag = get_tag(floppy);
|
||||
floperr_t err;
|
||||
UINT64 track_offset;
|
||||
|
||||
/* get track offset */
|
||||
err = get_track_offset(floppy, head, track, &track_offset);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (track_offset != INVALID_OFFSET)
|
||||
{
|
||||
UINT8 id1 = tag->id1;
|
||||
UINT8 id2 = tag->id2;
|
||||
int sectors_per_track;
|
||||
UINT16 d64_track_size;
|
||||
UINT8 *d64_track_data;
|
||||
UINT16 gcr_track_size;
|
||||
UINT8 *gcr_track_data;
|
||||
UINT64 gcr_pos = 0;
|
||||
|
||||
/* determine logical track number */
|
||||
int dos_track = get_dos_track(track);
|
||||
|
||||
if (tag->dos == DOS25)
|
||||
{
|
||||
dos_track = track + 1;
|
||||
}
|
||||
|
||||
/* logical track numbers continue on the flip side */
|
||||
if (head == 1) dos_track += tag->dos_tracks;
|
||||
|
||||
/* determine number of sectors per track */
|
||||
sectors_per_track = d64_get_sectors_per_track(floppy, head, track);
|
||||
|
||||
/* allocate D64 track data buffer */
|
||||
d64_track_size = sectors_per_track * SECTOR_SIZE;
|
||||
d64_track_data = (UINT8 *)alloca(d64_track_size);
|
||||
|
||||
/* allocate temporary GCR track data buffer */
|
||||
gcr_track_size = sectors_per_track * SECTOR_SIZE_GCR;
|
||||
gcr_track_data = (UINT8 *)alloca(gcr_track_size);
|
||||
|
||||
if (buflen < gcr_track_size) { fatalerror("D64 track buffer too small: %u!\n", (UINT32)buflen); }
|
||||
|
||||
/* read D64 track data */
|
||||
floppy_image_read(floppy, d64_track_data, track_offset, d64_track_size);
|
||||
|
||||
/* GCR encode D64 sector data */
|
||||
for (int sector = 0; sector < sectors_per_track; sector++)
|
||||
{
|
||||
// here we convert the sector data to gcr directly!
|
||||
// IMPORTANT: errors in reading sectors can modify e.g. header info $01 & $05
|
||||
int sector_error = get_sector_error_code(floppy, head, track, sector);
|
||||
|
||||
/* first we set the position at which sector data starts in the image */
|
||||
UINT64 d64_pos = sector * SECTOR_SIZE;
|
||||
int i;
|
||||
|
||||
/*
|
||||
1. Header sync FF FF FF FF FF (40 'on' bits, not GCR encoded)
|
||||
2. Header info 52 54 B5 29 4B 7A 5E 95 55 55 (10 GCR bytes)
|
||||
3. Header gap 55 55 55 55 55 55 55 55 55 (9 bytes, never read)
|
||||
4. Data sync FF FF FF FF FF (40 'on' bits, not GCR encoded)
|
||||
5. Data block 55...4A (325 GCR bytes)
|
||||
6. Inter-sector gap 55 55 55 55...55 55 (4 to 19 bytes, never read)
|
||||
*/
|
||||
|
||||
if (sector_error == ERROR_29)
|
||||
id1 ^= 0xff;
|
||||
|
||||
/* Header sync */
|
||||
if (sector_error != ERROR_21)
|
||||
{
|
||||
for (i = 0; i < 5; i++)
|
||||
gcr_track_data[gcr_pos + i] = 0xff;
|
||||
gcr_pos += 5;
|
||||
}
|
||||
|
||||
/* Header info */
|
||||
/* These are 8 bytes unencoded, which become 10 bytes encoded */
|
||||
// $00 - header block ID ($08) // this byte can be modified by error code 20 -> 0xff
|
||||
// $01 - header block checksum (EOR of $02-$05) // this byte can be modified by error code 27 -> ^ 0xff
|
||||
// $02 - Sector# of data block
|
||||
// $03 - Track# of data block
|
||||
UINT8 header_block_id = (sector_error == ERROR_20) ? 0xff : 0x08;
|
||||
UINT8 header_block_checksum = sector ^ dos_track ^ id2 ^ id1;
|
||||
|
||||
if (sector_error == ERROR_27)
|
||||
header_block_checksum ^= 0xff;
|
||||
|
||||
gcr_double_2_gcr(header_block_id, header_block_checksum, sector, dos_track, gcr_track_data + gcr_pos);
|
||||
gcr_pos += 5;
|
||||
|
||||
// $04 - Format ID byte #2
|
||||
// $05 - Format ID byte #1
|
||||
// $06 - $0F ("off" byte)
|
||||
// $07 - $0F ("off" byte)
|
||||
gcr_double_2_gcr(id2, id1, 0x0f, 0x0f, gcr_track_data + gcr_pos);
|
||||
gcr_pos += 5;
|
||||
|
||||
/* Header gap */
|
||||
for (i = 0; i < 9; i++)
|
||||
gcr_track_data[gcr_pos + i] = 0x55;
|
||||
gcr_pos += 9;
|
||||
|
||||
/* Data sync */
|
||||
for (i = 0; i < 5; i++)
|
||||
gcr_track_data[gcr_pos + i] = 0xff;
|
||||
gcr_pos += 5;
|
||||
|
||||
/* Data block */
|
||||
UINT8 data_block_id = (sector_error == ERROR_22) ? 0xff : 0x07;
|
||||
|
||||
// we first need to calculate the checksum of the 256 bytes of the sector
|
||||
UINT8 sector_checksum = d64_track_data[d64_pos];
|
||||
for (i = 1; i < 256; i++)
|
||||
sector_checksum ^= d64_track_data[d64_pos + i];
|
||||
|
||||
if (sector_error == ERROR_23)
|
||||
sector_checksum ^= 0xff;
|
||||
|
||||
/*
|
||||
$00 - data block ID ($07)
|
||||
$01-100 - 256 bytes sector data
|
||||
$101 - data block checksum (EOR of $01-100)
|
||||
$102-103 - $00 ("off" bytes, to make the sector size a multiple of 5)
|
||||
*/
|
||||
gcr_double_2_gcr(data_block_id, d64_track_data[d64_pos], d64_track_data[d64_pos + 1], d64_track_data[d64_pos + 2], gcr_track_data + gcr_pos);
|
||||
gcr_pos += 5;
|
||||
|
||||
for (i = 1; i < 64; i++)
|
||||
{
|
||||
gcr_double_2_gcr(d64_track_data[d64_pos + 4 * i - 1], d64_track_data[d64_pos + 4 * i],
|
||||
d64_track_data[d64_pos + 4 * i + 1], d64_track_data[d64_pos + 4 * i + 2], gcr_track_data + gcr_pos);
|
||||
gcr_pos += 5;
|
||||
}
|
||||
|
||||
gcr_double_2_gcr(d64_track_data[d64_pos + 255], sector_checksum, 0x00, 0x00, gcr_track_data + gcr_pos);
|
||||
gcr_pos += 5;
|
||||
|
||||
/* Inter-sector gap */
|
||||
// "In tests that the author conducted on a real 1541 disk, gap sizes of 8 to 19 bytes were seen."
|
||||
// Here we put 14 as an average...
|
||||
for (i = 0; i < 14; i++)
|
||||
gcr_track_data[gcr_pos + i] = 0x55;
|
||||
gcr_pos += 14;
|
||||
}
|
||||
|
||||
/* copy GCR track data to buffer */
|
||||
memcpy((UINT8*)buffer, gcr_track_data, gcr_track_size);
|
||||
|
||||
// create a speed block with the same speed zone for the whole track
|
||||
UINT8 speed = tag->speed_zone[track] & 0x03;
|
||||
UINT8 speed_byte = (speed << 6) | (speed << 4) | (speed << 2) | speed;
|
||||
|
||||
memset(((UINT8*)buffer) + gcr_track_size, speed_byte, G64_SPEED_BLOCK_SIZE);
|
||||
|
||||
LOG_FORMATS("D64 side %u track %.1f length %u\n", head, get_dos_track(track), gcr_track_size);
|
||||
}
|
||||
else /* half tracks */
|
||||
{
|
||||
/* set track length to 0 */
|
||||
memset(buffer, 0, buflen);
|
||||
|
||||
LOG_FORMATS("D64 side %u track %.1f length %u\n", head, get_dos_track(track), 0);
|
||||
}
|
||||
|
||||
return FLOPPY_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
d64_write_track - writes a full track to the
|
||||
disk image
|
||||
-------------------------------------------------*/
|
||||
|
||||
static floperr_t d64_write_track(floppy_image_legacy *floppy, int head, int track, UINT64 offset, const void *buffer, size_t buflen)
|
||||
{
|
||||
return FLOPPY_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
d64_identify - identifies the disk image
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void d64_identify(floppy_image_legacy *floppy, int *dos, int *heads, int *tracks, bool *has_errors)
|
||||
{
|
||||
switch (floppy_image_size(floppy))
|
||||
{
|
||||
/* 2040/3040 */
|
||||
case D67_SIZE_35_TRACKS: *dos = DOS1; *heads = 1; *tracks = 35; *has_errors = false; break;
|
||||
|
||||
/* 4040/2031/1541/1551 */
|
||||
case D64_SIZE_35_TRACKS: *dos = DOS2; *heads = 1; *tracks = 35; *has_errors = false; break;
|
||||
case D64_SIZE_35_TRACKS_WITH_ERRORS: *dos = DOS2; *heads = 1; *tracks = 35; *has_errors = true; break;
|
||||
case D64_SIZE_40_TRACKS: *dos = DOS2; *heads = 1; *tracks = 40; *has_errors = false; break;
|
||||
case D64_SIZE_40_TRACKS_WITH_ERRORS: *dos = DOS2; *heads = 1; *tracks = 40; *has_errors = true; break;
|
||||
case D64_SIZE_42_TRACKS: *dos = DOS2; *heads = 1; *tracks = 42; *has_errors = false; break;
|
||||
case D64_SIZE_42_TRACKS_WITH_ERRORS: *dos = DOS2; *heads = 1; *tracks = 42; *has_errors = true; break;
|
||||
|
||||
/* 1571 */
|
||||
case D71_SIZE_70_TRACKS: *dos = DOS2; *heads = 2; *tracks = 35; *has_errors = false; break;
|
||||
case D71_SIZE_70_TRACKS_WITH_ERRORS: *dos = DOS2; *heads = 2; *tracks = 35; *has_errors = true; break;
|
||||
|
||||
/* 8050 */
|
||||
case D80_SIZE_77_TRACKS: *dos = DOS25; *heads = 1; *tracks = 77; *has_errors = false; break;
|
||||
case D80_SIZE_77_TRACKS_WITH_ERRORS: *dos = DOS25; *heads = 1; *tracks = 77; *has_errors = true; break;
|
||||
|
||||
/* 8250/SFD1001 */
|
||||
case D82_SIZE_154_TRACKS: *dos = DOS25; *heads = 2; *tracks = 77; *has_errors = false; break;
|
||||
case D82_SIZE_154_TRACKS_WITH_ERRORS: *dos = DOS25; *heads = 2; *tracks = 77; *has_errors = true; break;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
FLOPPY_IDENTIFY( d64_dsk_identify )
|
||||
-------------------------------------------------*/
|
||||
|
||||
FLOPPY_IDENTIFY( d64_dsk_identify )
|
||||
{
|
||||
int dos = 0, heads, tracks;
|
||||
bool has_errors = false;
|
||||
|
||||
*vote = 0;
|
||||
|
||||
d64_identify(floppy, &dos, &heads, &tracks, &has_errors);
|
||||
|
||||
if (dos == DOS2 && heads == 1)
|
||||
{
|
||||
*vote = 100;
|
||||
}
|
||||
|
||||
return FLOPPY_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
FLOPPY_IDENTIFY( d67_dsk_identify )
|
||||
-------------------------------------------------*/
|
||||
|
||||
FLOPPY_IDENTIFY( d67_dsk_identify )
|
||||
{
|
||||
*vote = 0;
|
||||
|
||||
if (floppy_image_size(floppy) == D67_SIZE_35_TRACKS)
|
||||
{
|
||||
*vote = 100;
|
||||
}
|
||||
|
||||
return FLOPPY_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
FLOPPY_IDENTIFY( d71_dsk_identify )
|
||||
-------------------------------------------------*/
|
||||
|
||||
FLOPPY_IDENTIFY( d71_dsk_identify )
|
||||
{
|
||||
int heads = 0, tracks = 0, dos = -1;
|
||||
bool has_errors = false;
|
||||
|
||||
*vote = 0;
|
||||
|
||||
d64_identify(floppy, &dos, &heads, &tracks, &has_errors);
|
||||
|
||||
if (dos == DOS2 && heads == 2)
|
||||
{
|
||||
*vote = 100;
|
||||
}
|
||||
|
||||
return FLOPPY_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
FLOPPY_IDENTIFY( d80_dsk_identify )
|
||||
-------------------------------------------------*/
|
||||
|
||||
FLOPPY_IDENTIFY( d80_dsk_identify )
|
||||
{
|
||||
int heads = 0, tracks = 0, dos = -1;
|
||||
bool has_errors = false;
|
||||
*vote = 0;
|
||||
|
||||
d64_identify(floppy, &dos, &heads, &tracks, &has_errors);
|
||||
|
||||
if (dos == DOS25 && heads == 1)
|
||||
{
|
||||
*vote = 100;
|
||||
}
|
||||
|
||||
return FLOPPY_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
FLOPPY_IDENTIFY( d82_dsk_identify )
|
||||
-------------------------------------------------*/
|
||||
|
||||
FLOPPY_IDENTIFY( d82_dsk_identify )
|
||||
{
|
||||
int heads = 0, tracks = 0, dos = -1;
|
||||
bool has_errors = false;
|
||||
*vote = 0;
|
||||
|
||||
d64_identify(floppy, &dos, &heads, &tracks, &has_errors);
|
||||
|
||||
if (dos == DOS25 && heads == 2)
|
||||
{
|
||||
*vote = 100;
|
||||
}
|
||||
|
||||
return FLOPPY_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
FLOPPY_CONSTRUCT( d64_dsk_construct )
|
||||
-------------------------------------------------*/
|
||||
|
||||
FLOPPY_CONSTRUCT( d64_dsk_construct )
|
||||
{
|
||||
struct FloppyCallbacks *callbacks;
|
||||
struct d64dsk_tag *tag;
|
||||
UINT8 id[2];
|
||||
|
||||
int track_offset = 0;
|
||||
int head, track;
|
||||
|
||||
int heads = 0, dos_tracks = 0, dos = 0;
|
||||
bool has_errors = 0;
|
||||
int errors_size = 0;
|
||||
|
||||
if (params)
|
||||
{
|
||||
/* create not supported */
|
||||
return FLOPPY_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
tag = (struct d64dsk_tag *) floppy_create_tag(floppy, sizeof(struct d64dsk_tag));
|
||||
|
||||
if (!tag) return FLOPPY_ERROR_OUTOFMEMORY;
|
||||
|
||||
/* identify image type */
|
||||
d64_identify(floppy, &dos, &heads, &dos_tracks, &has_errors);
|
||||
|
||||
tag->dos = dos;
|
||||
tag->heads = heads;
|
||||
tag->tracks = MAX_TRACKS;
|
||||
tag->dos_tracks = dos_tracks;
|
||||
tag->has_errors = has_errors;
|
||||
|
||||
LOG_FORMATS("D64 size: %04x\n", (UINT32)floppy_image_size(floppy));
|
||||
LOG_FORMATS("D64 heads: %d\n", heads);
|
||||
LOG_FORMATS("D64 tracks: %d\n", dos_tracks);
|
||||
LOG_FORMATS("D64 DOS version: %s\n", DOS_VERSION[dos]);
|
||||
LOG_FORMATS("D64 error codes: %s\n", has_errors ? "yes" : "no");
|
||||
|
||||
/* clear track data offsets */
|
||||
for (head = 0; head < MAX_HEADS; head++)
|
||||
{
|
||||
for (track = 0; track < MAX_TRACKS; track++)
|
||||
{
|
||||
tag->track_offset[head][track] = INVALID_OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
/* determine track data offsets */
|
||||
for (head = 0; head < heads; head++)
|
||||
{
|
||||
for (track = 0; track < tag->tracks; track++)
|
||||
{
|
||||
if (dos == DOS25)
|
||||
{
|
||||
if (track >= dos_tracks)
|
||||
{
|
||||
/* track out of range */
|
||||
tag->track_offset[head][track] = INVALID_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
tag->track_offset[head][track] = track_offset;
|
||||
tag->error_offset[head][track] = errors_size;
|
||||
tag->speed_zone[track] = DOS25_SPEED_ZONE[track];
|
||||
|
||||
track_offset += DOS25_SECTORS_PER_TRACK[track] * SECTOR_SIZE;
|
||||
/* also store an error entry for each sector */
|
||||
errors_size += DOS25_SECTORS_PER_TRACK[track];
|
||||
|
||||
LOG_FORMATS("D64 head %d track %d offset %05x", head, track + 1, tag->track_offset[head][track]);
|
||||
if (has_errors) LOG_FORMATS(" errors %05x", tag->error_offset[head][track]);
|
||||
LOG_FORMATS(" speed %u\n", tag->speed_zone[track]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((track % 2) || ((track / 2) >= dos_tracks))
|
||||
{
|
||||
/* half track or out of range */
|
||||
tag->track_offset[head][track] = INVALID_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* full track */
|
||||
tag->track_offset[head][track] = track_offset;
|
||||
tag->error_offset[head][track] = errors_size;
|
||||
tag->speed_zone[track] = DOS1_SPEED_ZONE[track / 2];
|
||||
|
||||
if (dos == DOS1)
|
||||
{
|
||||
track_offset += DOS1_SECTORS_PER_TRACK[track / 2] * SECTOR_SIZE;
|
||||
/* also store an error entry for each sector */
|
||||
errors_size += DOS1_SECTORS_PER_TRACK[track / 2];
|
||||
}
|
||||
else
|
||||
{
|
||||
track_offset += DOS2_SECTORS_PER_TRACK[track / 2] * SECTOR_SIZE;
|
||||
/* also store an error entry for each sector */
|
||||
errors_size += DOS2_SECTORS_PER_TRACK[track / 2];
|
||||
}
|
||||
|
||||
LOG_FORMATS("D64 head %d track %.1f offset %05x", head, get_dos_track(track), tag->track_offset[head][track]);
|
||||
if (has_errors) LOG_FORMATS(" errors %05x", tag->error_offset[head][track]);
|
||||
LOG_FORMATS(" speed %u\n", tag->speed_zone[track]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* read format ID from directory */
|
||||
/*
|
||||
id1, id2 are the same for extended d64 (i.e. with error tables), for d67 and for d71
|
||||
|
||||
for d81 they are at track 40 bytes 0x17 & 0x18
|
||||
for d80 & d82 they are at track 39 bytes 0x18 & 0x19
|
||||
*/
|
||||
if (dos == DOS25)
|
||||
floppy_image_read(floppy, id, tag->track_offset[0][38] + 0x18, 2);
|
||||
else
|
||||
floppy_image_read(floppy, id, tag->track_offset[0][34] + 0xa2, 2);
|
||||
|
||||
tag->id1 = id[0];
|
||||
tag->id2 = id[1];
|
||||
|
||||
LOG_FORMATS("D64 format ID: %02x%02x\n", id[0], id[1]);
|
||||
|
||||
/* read errors */
|
||||
if (tag->has_errors)
|
||||
{
|
||||
LOG_FORMATS("D64 error blocks: %d %d\n", errors_size, track_offset);
|
||||
floppy_image_read(floppy, tag->error, track_offset, errors_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(tag->error, ERROR_00, MAX_ERROR_SECTORS);
|
||||
}
|
||||
|
||||
/* set callbacks */
|
||||
callbacks = floppy_callbacks(floppy);
|
||||
|
||||
callbacks->read_track = d64_read_track;
|
||||
callbacks->write_track = d64_write_track;
|
||||
callbacks->get_heads_per_disk = d64_get_heads_per_disk;
|
||||
callbacks->get_tracks_per_disk = d64_get_tracks_per_disk;
|
||||
callbacks->get_track_size = d64_get_track_size;
|
||||
|
||||
return FLOPPY_ERROR_SUCCESS;
|
||||
}
|
||||
|
@ -76,12 +76,5 @@ protected:
|
||||
extern const floppy_format_type FLOPPY_D64_FORMAT;
|
||||
|
||||
|
||||
FLOPPY_IDENTIFY( d64_dsk_identify );
|
||||
FLOPPY_IDENTIFY( d67_dsk_identify );
|
||||
FLOPPY_IDENTIFY( d71_dsk_identify );
|
||||
FLOPPY_IDENTIFY( d80_dsk_identify );
|
||||
FLOPPY_IDENTIFY( d82_dsk_identify );
|
||||
|
||||
FLOPPY_CONSTRUCT( d64_dsk_construct );
|
||||
|
||||
#endif
|
||||
|
@ -37,7 +37,7 @@ const char *d80_format::extensions() const
|
||||
|
||||
const d80_format::format d80_format::file_formats[] = {
|
||||
{ // d80, dos 2.5, 77 tracks, head/stepper 100 tpi
|
||||
floppy_image::FF_525, floppy_image::SSQD, 2083, 77, 1, 256, 9, 8
|
||||
floppy_image::FF_525, floppy_image::SSQD, 2083, 77, 1, 256, 19, 19 // TODO verify gaps
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
@ -33,7 +33,7 @@ const char *d82_format::extensions() const
|
||||
|
||||
const d82_format::format d82_format::file_formats[] = {
|
||||
{ // d82, dos 2.5, 77 tracks, 2 heads, head/stepper 100 tpi
|
||||
floppy_image::FF_525, floppy_image::DSQD, 2083, 77, 2, 256, 9, 8
|
||||
floppy_image::FF_525, floppy_image::DSQD, 2083, 77, 2, 256, 19, 19 // TODO verify gaps
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
@ -32,6 +32,8 @@
|
||||
|
||||
TODO:
|
||||
|
||||
- write protect
|
||||
- separate read/write methods
|
||||
- communication error with SCP after loading boot sector
|
||||
- bp ff1a8
|
||||
- patch ff1ab=c3
|
||||
|
Loading…
Reference in New Issue
Block a user