summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/machine/victor9k_fdc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/machine/victor9k_fdc.c')
-rw-r--r--src/mess/machine/victor9k_fdc.c1351
1 files changed, 0 insertions, 1351 deletions
diff --git a/src/mess/machine/victor9k_fdc.c b/src/mess/machine/victor9k_fdc.c
deleted file mode 100644
index ae04084757b..00000000000
--- a/src/mess/machine/victor9k_fdc.c
+++ /dev/null
@@ -1,1351 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Curt Coder
-/**********************************************************************
-
- Victor 9000 floppy disk controller emulation
-
-**********************************************************************/
-
-/*
-
- value error description
-
- 01 no sync pulse detected
- 02 no header track
- 03 checksum error in header
- 04 not right track
- 05 not right sector
- 06 not a data block
- 07 data checksum error
- 08 sync too long
- 99 not a system disc
-
- 11 Noise on sync
- FF No sync (bad or unformatted disk)
-
-*/
-
-/*
-
- TODO:
-
- - write protect
- - separate read/write methods
- - communication error with SCP after loading boot sector
- - bp ff1a8
- - patch ff1ab=c3
- - single/double sided jumper
- - header sync length unknown (6 is too short)
- - 8048 spindle speed control
-
-*/
-
-#include "victor9k_fdc.h"
-
-
-
-//**************************************************************************
-// MACROS / CONSTANTS
-//**************************************************************************
-
-#define LOG 0
-#define LOG_VIA 0
-#define LOG_SCP 0
-#define LOG_BITS 0
-
-#define I8048_TAG "5d"
-#define M6522_4_TAG "1f"
-#define M6522_5_TAG "1k"
-#define M6522_6_TAG "1h"
-
-// this is exactly the same decode/encode as used in the Commodore 4040/8050 series drives
-#define GCR_DECODE(_e, _i) \
- ((BIT(_e, 6) << 7) | (BIT(_i, 7) << 6) | (_e & 0x33) | (BIT(_e, 2) << 3) | (_i & 0x04))
-
-// E7 E6 I7 E5 E4 E3 E2 I2 E1 E0
-#define GCR_ENCODE(_e, _i) \
- ((_e & 0xc0) << 2 | (_i & 0x80) | (_e & 0x3c) << 1 | (_i & 0x04) | (_e & 0x03))
-
-// Tandon TM-100 spindle @ 300RPM, measured TACH 12VAC 256Hz
-// TACH = RPM / 60 * SPINDLE RATIO * MOTOR POLES
-// 256 = 300 / 60 * 6.4 * 8
-#define SPINDLE_RATIO 6.4
-#define MOTOR_POLES 8
-
-// TODO wrong values here! motor speed is controlled by an LM2917, with help from the spindle TACH and a DAC0808 whose value is set by the SCP 8048
-const int victor_9000_fdc_t::rpm[] = { 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 254, 255, 257, 259, 260, 262, 264, 266, 267, 269, 271, 273, 275, 276, 278, 280, 282, 284, 286, 288, 290, 291, 293, 295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 318, 320, 322, 324, 326, 328, 330, 333, 335, 337, 339, 342, 344, 346, 348, 351, 353, 355, 358, 360, 362, 365, 367, 370, 372, 375, 377, 380, 382, 385, 387, 390, 392, 395, 398, 400, 403, 406, 408, 411, 414, 416, 419, 422, 425, 428, 430, 433, 436, 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472, 475, 478, 482, 485, 488, 491, 494, 498, 501, 504, 508, 511, 514, 518, 521, 525, 528, 532, 535, 539, 542, 546, 550, 553, 557, 561, 564, 568, 572, 576, 579, 583, 587, 591, 595, 599, 603, 607, 611, 615, 619, 623, 627, 631, 636, 640, 644, 648, 653, 657, 661, 666, 670, 674, 679, 683, 688, 693, 697, 702, 706, 711, 716, 721, 725, 730, 735, 740, 745, 750, 755, 760, 765, 770, 775, 780, 785, 790, 796, 801, 806, 812, 817, 822, 828, 833, 839, 844, 850, 856, 861, 867, 873, 878, 884 };
-
-
-
-//**************************************************************************
-// DEVICE DEFINITIONS
-//**************************************************************************
-
-const device_type VICTOR_9000_FDC = &device_creator<victor_9000_fdc_t>;
-
-
-//-------------------------------------------------
-// ROM( victor_9000_fdc )
-//-------------------------------------------------
-
-ROM_START( victor_9000_fdc )
- ROM_REGION( 0x400, I8048_TAG, 0)
- ROM_LOAD( "36080.5d", 0x000, 0x400, CRC(9bf49f7d) SHA1(b3a11bb65105db66ae1985b6f482aab6ea1da38b) )
-
- ROM_REGION( 0x800, "gcr", 0 )
- ROM_LOAD( "100836-001.4k", 0x000, 0x800, CRC(adc601bd) SHA1(6eeff3d2063ae2d97452101aa61e27ef83a467e5) )
-ROM_END
-
-
-//-------------------------------------------------
-// rom_region - device-specific ROM region
-//-------------------------------------------------
-
-const rom_entry *victor_9000_fdc_t::device_rom_region() const
-{
- return ROM_NAME( victor_9000_fdc );
-}
-
-
-//-------------------------------------------------
-// ADDRESS_MAP( floppy_io )
-//-------------------------------------------------
-
-static ADDRESS_MAP_START( floppy_io, AS_IO, 8, victor_9000_fdc_t )
- AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(floppy_p1_r, floppy_p1_w)
- AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(floppy_p2_r, floppy_p2_w)
- AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T0) AM_READ(tach0_r)
- AM_RANGE(MCS48_PORT_T1, MCS48_PORT_T1) AM_READ(tach1_r)
- AM_RANGE(MCS48_PORT_BUS, MCS48_PORT_BUS) AM_WRITE(da_w)
-ADDRESS_MAP_END
-
-
-//-------------------------------------------------
-// SLOT_INTERFACE( victor9k_floppies )
-//-------------------------------------------------
-
-int victor_9000_fdc_t::load0_cb(floppy_image_device *device)
-{
- // DOOR OPEN 0
- m_via4->write_ca1(0);
-
- return IMAGE_INIT_PASS;
-}
-
-void victor_9000_fdc_t::unload0_cb(floppy_image_device *device)
-{
- // DOOR OPEN 0
- m_via4->write_ca1(1);
-}
-
-int victor_9000_fdc_t::load1_cb(floppy_image_device *device)
-{
- // DOOR OPEN 1
- m_via4->write_cb1(0);
-
- return IMAGE_INIT_PASS;
-}
-
-void victor_9000_fdc_t::unload1_cb(floppy_image_device *device)
-{
- // DOOR OPEN 1
- m_via4->write_cb1(1);
-}
-
-static SLOT_INTERFACE_START( victor9k_floppies )
- SLOT_INTERFACE( "525ssqd", FLOPPY_525_SSQD ) // Tandon TM100-3 with custom electronics
- SLOT_INTERFACE( "525qd", FLOPPY_525_QD ) // Tandon TM100-4 with custom electronics
-SLOT_INTERFACE_END
-
-FLOPPY_FORMATS_MEMBER( victor_9000_fdc_t::floppy_formats )
- FLOPPY_VICTOR_9000_FORMAT
-FLOPPY_FORMATS_END
-
-
-//-------------------------------------------------
-// MACHINE_CONFIG_FRAGMENT( victor_9000_fdc )
-//-------------------------------------------------
-
-static MACHINE_CONFIG_FRAGMENT( victor_9000_fdc )
- MCFG_CPU_ADD(I8048_TAG, I8048, XTAL_30MHz/6)
- MCFG_CPU_IO_MAP(floppy_io)
-
- MCFG_DEVICE_ADD(M6522_4_TAG, VIA6522, XTAL_30MHz/30)
- MCFG_VIA6522_READPA_HANDLER(READ8(victor_9000_fdc_t, via4_pa_r))
- MCFG_VIA6522_WRITEPA_HANDLER(WRITE8(victor_9000_fdc_t, via4_pa_w))
- MCFG_VIA6522_READPB_HANDLER(READ8(victor_9000_fdc_t, via4_pb_r))
- MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(victor_9000_fdc_t, via4_pb_w))
- MCFG_VIA6522_CA2_HANDLER(WRITELINE(victor_9000_fdc_t, wrsync_w))
- MCFG_VIA6522_IRQ_HANDLER(WRITELINE(victor_9000_fdc_t, via4_irq_w))
-
- MCFG_DEVICE_ADD(M6522_5_TAG, VIA6522, XTAL_30MHz/30)
- MCFG_VIA6522_IRQ_HANDLER(WRITELINE(victor_9000_fdc_t, via5_irq_w))
- MCFG_VIA6522_READPA_HANDLER(READ8(victor_9000_fdc_t, via5_pa_r))
- MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(victor_9000_fdc_t, via5_pb_w))
-
- MCFG_DEVICE_ADD(M6522_6_TAG, VIA6522, XTAL_30MHz/30)
- MCFG_VIA6522_READPA_HANDLER(READ8(victor_9000_fdc_t, via6_pa_r))
- MCFG_VIA6522_READPB_HANDLER(READ8(victor_9000_fdc_t, via6_pb_r))
- MCFG_VIA6522_WRITEPA_HANDLER(WRITE8(victor_9000_fdc_t, via6_pa_w))
- MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(victor_9000_fdc_t, via6_pb_w))
- MCFG_VIA6522_CA2_HANDLER(WRITELINE(victor_9000_fdc_t, drw_w))
- MCFG_VIA6522_CB2_HANDLER(WRITELINE(victor_9000_fdc_t, erase_w))
- MCFG_VIA6522_IRQ_HANDLER(WRITELINE(victor_9000_fdc_t, via6_irq_w))
-
- MCFG_FLOPPY_DRIVE_ADD(I8048_TAG":0", victor9k_floppies, "525qd", victor_9000_fdc_t::floppy_formats)
- MCFG_FLOPPY_DRIVE_ADD(I8048_TAG":1", victor9k_floppies, "525qd", victor_9000_fdc_t::floppy_formats)
-MACHINE_CONFIG_END
-
-
-//-------------------------------------------------
-// machine_config_additions - device-specific
-// machine configurations
-//-------------------------------------------------
-
-machine_config_constructor victor_9000_fdc_t::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME( victor_9000_fdc );
-}
-
-
-
-//**************************************************************************
-// LIVE DEVICE
-//**************************************************************************
-
-//-------------------------------------------------
-// victor_9000_fdc_t - constructor
-//-------------------------------------------------
-
-victor_9000_fdc_t::victor_9000_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
- device_t(mconfig, VICTOR_9000_FDC, "Victor 9000 FDC", tag, owner, clock, "victor9k_fdc", __FILE__),
- m_irq_cb(*this),
- m_syn_cb(*this),
- m_lbrdy_cb(*this),
- m_maincpu(*this, I8048_TAG),
- m_via4(*this, M6522_4_TAG),
- m_via5(*this, M6522_5_TAG),
- m_via6(*this, M6522_6_TAG),
- m_floppy0(*this, I8048_TAG":0:525qd"),
- m_floppy1(*this, I8048_TAG":1:525qd"),
- m_gcr_rom(*this, "gcr"),
- m_da(0),
- m_da0(0),
- m_da1(0),
- m_start0(1),
- m_stop0(1),
- m_start1(1),
- m_stop1(1),
- m_sel0(0),
- m_sel1(0),
- m_tach0(0),
- m_tach1(0),
- m_rdy0(0),
- m_rdy1(0),
- m_l0ms(0),
- m_l1ms(0),
- m_st0(0),
- m_st1(0),
- m_stp0(0),
- m_stp1(0),
- m_drive(0),
- m_side(0),
- m_via4_irq(CLEAR_LINE),
- m_via5_irq(CLEAR_LINE),
- m_via6_irq(CLEAR_LINE),
- m_period(attotime::from_hz(XTAL_15MHz/32))
-{
- cur_live.tm = attotime::never;
- cur_live.state = IDLE;
- cur_live.next_state = -1;
-}
-
-
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-
-void victor_9000_fdc_t::device_start()
-{
- // resolve callbacks
- m_irq_cb.resolve_safe();
- m_syn_cb.resolve_safe();
- m_lbrdy_cb.resolve_safe();
-
- // allocate timer
- t_gen = timer_alloc(TM_GEN);
- t_tach0 = timer_alloc(TM_TACH0);
- t_tach1 = timer_alloc(TM_TACH1);
-
- // state saving
- save_item(NAME(m_da));
- save_item(NAME(m_da0));
- save_item(NAME(m_da1));
- save_item(NAME(m_start0));
- save_item(NAME(m_stop0));
- save_item(NAME(m_start1));
- save_item(NAME(m_stop1));
- save_item(NAME(m_sel0));
- save_item(NAME(m_sel1));
- save_item(NAME(m_tach0));
- save_item(NAME(m_tach1));
- save_item(NAME(m_rdy0));
- save_item(NAME(m_rdy1));
- save_item(NAME(m_l0ms));
- save_item(NAME(m_l1ms));
- save_item(NAME(m_st0));
- save_item(NAME(m_st1));
- save_item(NAME(m_stp0));
- save_item(NAME(m_stp1));
- save_item(NAME(m_drive));
- save_item(NAME(m_side));
- save_item(NAME(m_drw));
- save_item(NAME(m_erase));
- save_item(NAME(m_via4_irq));
- save_item(NAME(m_via5_irq));
- save_item(NAME(m_via6_irq));
-}
-
-
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-
-void victor_9000_fdc_t::device_reset()
-{
- live_abort();
-
- // reset devices
- m_via4->reset();
- m_via5->reset();
- m_via6->reset();
-
- // set floppy callbacks
- m_floppy0->setup_load_cb(floppy_image_device::load_cb(FUNC(victor_9000_fdc_t::load0_cb), this));
- m_floppy0->setup_unload_cb(floppy_image_device::unload_cb(FUNC(victor_9000_fdc_t::unload0_cb), this));
-
- m_floppy1->setup_load_cb(floppy_image_device::load_cb(FUNC(victor_9000_fdc_t::load1_cb), this));
- m_floppy1->setup_unload_cb(floppy_image_device::unload_cb(FUNC(victor_9000_fdc_t::unload1_cb), this));
-}
-
-
-//-------------------------------------------------
-// device_timer - handler timer events
-//-------------------------------------------------
-
-void victor_9000_fdc_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- switch (id)
- {
- case TM_GEN:
- live_sync();
- live_run();
- break;
-
- case TM_TACH0:
- m_tach0 = !m_tach0;
- if (LOG_SCP) logerror("TACH0 %u\n", m_tach0);
- break;
-
- case TM_TACH1:
- m_tach1 = !m_tach1;
- if (LOG_SCP) logerror("TACH1 %u\n", m_tach1);
- break;
- }
-}
-
-
-//-------------------------------------------------
-// floppy_p1_r -
-//-------------------------------------------------
-
-READ8_MEMBER( victor_9000_fdc_t::floppy_p1_r )
-{
- /*
-
- bit description
-
- 0 L0MS0
- 1 L0MS1
- 2 L0MS2
- 3 L0MS3
- 4 L1MS0
- 5 L1MS1
- 6 L1MS2
- 7 L1MS3
-
- */
-
- return (m_l1ms << 4) | m_l0ms;
-}
-
-
-//-------------------------------------------------
-// floppy_p1_w -
-//-------------------------------------------------
-
-WRITE8_MEMBER( victor_9000_fdc_t::floppy_p1_w )
-{
- /*
-
- bit description
-
- 0 L0MS0
- 1 L0MS1
- 2 L0MS2
- 3 L0MS3
- 4 L1MS0
- 5 L1MS1
- 6 L1MS2
- 7 L1MS3
-
- */
-
- m_l0ms = data & 0x0f;
- m_l1ms = data >> 4;
-}
-
-
-//-------------------------------------------------
-// floppy_p2_r -
-//-------------------------------------------------
-
-READ8_MEMBER( victor_9000_fdc_t::floppy_p2_r )
-{
- /*
-
- bit description
-
- 0
- 1
- 2
- 3
- 4
- 5
- 6 RDY0
- 7 RDY1
-
- */
-
- UINT8 data = m_p2 & 0x3f;
-
- data |= m_rdy0 << 6;
- data |= m_rdy1 << 7;
-
- return data;
-}
-
-
-//-------------------------------------------------
-// floppy_p2_w -
-//-------------------------------------------------
-
-WRITE8_MEMBER( victor_9000_fdc_t::floppy_p2_w )
-{
- /*
-
- bit description
-
- 0 START0
- 1 STOP0
- 2 START1
- 3 STOP1
- 4 SEL1
- 5 SEL0
- 6 RDY0
- 7 RDY1
-
- */
-
- m_p2 = data;
-
- bool sync = false;
-
- int start0 = BIT(data, 0);
- if (m_start0 != start0) sync = true;
-
- int stop0 = BIT(data, 1);
- if (m_stop0 != stop0) sync = true;
-
- int start1 = BIT(data, 2);
- if (m_start1 != start1) sync = true;
-
- int stop1 = BIT(data, 3);
- if (m_stop1 != stop1) sync = true;
-
- int sel0 = BIT(data, 5);
- if (m_sel0 != sel0) sync = true;
-
- int sel1 = BIT(data, 4);
- if (m_sel1 != sel1) sync = true;
-
- set_rdy0(BIT(data, 6));
- set_rdy1(BIT(data, 7));
-
- if (LOG_SCP) logerror("%s %s START0/STOP0/SEL0/RDY0 %u/%u/%u/%u START1/STOP1/SEL1/RDY1 %u/%u/%u/%u\n", machine().time().as_string(), machine().describe_context(), start0, stop0, sel0, m_rdy0, start1, stop1, sel1, m_rdy1);
-
- if (sync)
- {
- live_sync();
-
- m_start0 = start0;
- m_stop0 = stop0;
- m_sel0 = sel0;
- //update_spindle_motor(m_floppy0, t_tach0, m_start0, m_stop0, m_sel0, m_da0);
-
- m_start1 = start1;
- m_stop1 = stop1;
- m_sel1 = sel1;
- //update_spindle_motor(m_floppy1, t_tach1, m_start1, m_stop1, m_sel1, m_da1);
-
- checkpoint();
-
- if (!m_floppy0->mon_r() || !m_floppy1->mon_r()) {
- if(cur_live.state == IDLE) {
- live_start();
- }
- } else {
- live_abort();
- }
-
- live_run();
- }
-}
-
-
-//-------------------------------------------------
-// tach0_r -
-//-------------------------------------------------
-
-READ8_MEMBER( victor_9000_fdc_t::tach0_r )
-{
- return m_tach0;
-}
-
-
-//-------------------------------------------------
-// tach1_r -
-//-------------------------------------------------
-
-READ8_MEMBER( victor_9000_fdc_t::tach1_r )
-{
- return m_tach1;
-}
-
-
-void victor_9000_fdc_t::update_stepper_motor(floppy_image_device *floppy, int stp, int old_st, int st)
-{
- if (stp) return;
-
- int tracks = 0;
-
- switch (old_st)
- {
- case 6: if (st == 0xa) tracks++; else if (st == 5) tracks--; break;
- case 5: if (st == 6) tracks++; else if (st == 9) tracks--; break;
- case 9: if (st == 5) tracks++; else if (st == 0xa) tracks--; break;
- case 0xa: if (st == 9) tracks++; else if (st == 6) tracks--; break;
- }
-
- if (tracks == -1)
- {
- floppy->dir_w(1);
- floppy->stp_w(1);
- floppy->stp_w(0);
- }
- else if (tracks == 1)
- {
- floppy->dir_w(0);
- floppy->stp_w(1);
- floppy->stp_w(0);
- }
-}
-
-void victor_9000_fdc_t::update_spindle_motor(floppy_image_device *floppy, emu_timer *t_tach, bool start, bool stop, bool sel, UINT8 &da)
-{
- if (start && !stop && floppy->mon_r()) {
- if (LOG_SCP) logerror("%s: motor start\n", floppy->tag());
- floppy->mon_w(0);
- } else if (stop && !floppy->mon_r()) {
- if (LOG_SCP) logerror("%s: motor stop\n", floppy->tag());
- floppy->mon_w(1);
- t_tach->reset();
- }
-
- if (sel) {
- da = m_da;
- if (!floppy->mon_r()) {
- float tach = rpm[da] / 60 * SPINDLE_RATIO * MOTOR_POLES;
-
- if (LOG_SCP) logerror("%s: motor speed %u rpm / tach %0.1f hz (DA %02x)\n", floppy->tag(), rpm[da], (double) tach, da);
-
- t_tach->adjust(attotime::from_hz(tach*2), 0, attotime::from_hz(tach*2));
- floppy->set_rpm(rpm[da]);
- }
- }
-}
-
-void victor_9000_fdc_t::set_rdy0(int state)
-{
- //m_rdy0 = state;
- //m_via5->write_ca2(m_rdy0);
-}
-
-void victor_9000_fdc_t::set_rdy1(int state)
-{
- //m_rdy1 = state;
- //m_via5->write_cb2(m_rdy1);
-}
-
-
-//-------------------------------------------------
-// da_w -
-//-------------------------------------------------
-
-WRITE8_MEMBER( victor_9000_fdc_t::da_w )
-{
- if (LOG_SCP) logerror("%s %s DA %02x\n", machine().time().as_string(), machine().describe_context(), data);
-
- if (m_da != data)
- {
- live_sync();
- m_da = data;
- update_spindle_motor(m_floppy0, t_tach0, m_start0, m_stop0, m_sel0, m_da0);
- update_spindle_motor(m_floppy1, t_tach1, m_start1, m_stop1, m_sel1, m_da1);
- checkpoint();
- live_run();
- }
-}
-
-READ8_MEMBER( victor_9000_fdc_t::via4_pa_r )
-{
- /*
-
- bit description
-
- PA0 L0MS0
- PA1 L0MS1
- PA2 L0MS2
- PA3 L0MS3
- PA4
- PA5
- PA6
- PA7
-
- */
-
- return m_l0ms;
-}
-
-WRITE8_MEMBER( victor_9000_fdc_t::via4_pa_w )
-{
- /*
-
- bit description
-
- PA0 L0MS0
- PA1 L0MS1
- PA2 L0MS2
- PA3 L0MS3
- PA4 ST0A
- PA5 ST0B
- PA6 ST0C
- PA7 ST0D
-
- */
-
- m_l0ms = data & 0x0f;
-
- { // HACK to bypass SCP
- m_floppy0->mon_w((m_l0ms == 0xf) ? 1 : 0);
- m_floppy0->set_rpm(victor9k_format::get_rpm(m_side, m_floppy0->get_cyl()));
- m_rdy0 = (m_l0ms == 0xf) ? 0 : 1;
- m_via5->write_ca2(m_rdy0);
- }
-
- UINT8 st0 = data >> 4;
-
- if (LOG_VIA) logerror("%s %s L0MS %01x ST0 %01x\n", machine().time().as_string(), machine().describe_context(), m_l0ms, st0);
-
- if (m_st0 != st0)
- {
- live_sync();
- update_stepper_motor(m_floppy0, m_stp0, st0, m_st0);
- m_st0 = st0;
- checkpoint();
- live_run();
- }
-}
-
-READ8_MEMBER( victor_9000_fdc_t::via4_pb_r )
-{
- /*
-
- bit description
-
- PB0 L1MS0
- PB1 L1MS1
- PB2 L1MS2
- PB3 L1MS3
- PB4
- PB5
- PB6
- PB7
-
- */
-
- return m_l1ms;
-}
-
-WRITE8_MEMBER( victor_9000_fdc_t::via4_pb_w )
-{
- /*
-
- bit description
-
- PB0 L1MS0
- PB1 L1MS1
- PB2 L1MS2
- PB3 L1MS3
- PB4 ST1A
- PB5 ST1B
- PB6 ST1C
- PB7 ST1D
-
- */
-
- m_l1ms = data & 0x0f;
-
- { // HACK to bypass SCP
- m_floppy1->mon_w((m_l1ms == 0xf) ? 1 : 0);
- m_floppy1->set_rpm(victor9k_format::get_rpm(m_side, m_floppy1->get_cyl()));
- m_rdy1 = (m_l1ms == 0xf) ? 0 : 1;
- m_via5->write_cb2(m_rdy1);
- }
-
- UINT8 st1 = data >> 4;
-
- if (LOG_VIA) logerror("%s %s L1MS %01x ST1 %01x\n", machine().time().as_string(), machine().describe_context(), m_l1ms, st1);
-
- if (m_st1 != st1)
- {
- live_sync();
- update_stepper_motor(m_floppy1, m_stp1, st1, m_st1);
- m_st1 = st1;
- checkpoint();
- live_run();
- }
-}
-
-WRITE_LINE_MEMBER( victor_9000_fdc_t::wrsync_w )
-{
- if (m_wrsync != state)
- {
- live_sync();
- m_wrsync = state;
- cur_live.wrsync = state;
- checkpoint();
- if (LOG_VIA) logerror("%s %s WRSYNC %u\n", machine().time().as_string(), machine().describe_context(), state);
- live_run();
- }
-}
-
-WRITE_LINE_MEMBER( victor_9000_fdc_t::via4_irq_w )
-{
- m_via4_irq = state;
-
- m_irq_cb(m_via4_irq || m_via5_irq || m_via6_irq);
-}
-
-READ8_MEMBER( victor_9000_fdc_t::via5_pa_r )
-{
- /*
-
- bit description
-
- PA0 E0
- PA1 E1
- PA2 I1
- PA3 E2
- PA4 E4
- PA5 E5
- PA6 I7
- PA7 E6
-
- */
-
- return GCR_DECODE(checkpoint_live.e, checkpoint_live.i);
-}
-
-WRITE8_MEMBER( victor_9000_fdc_t::via5_pb_w )
-{
- /*
-
- bit description
-
- PB0 WD0
- PB1 WD1
- PB2 WD2
- PB3 WD3
- PB4 WD4
- PB5 WD5
- PB6 WD6
- PB7 WD7
-
- */
-
- if (LOG_VIA) logerror("%s %s WD %02x\n", machine().time().as_string(), machine().describe_context(), data);
-
- if (m_wd != data)
- {
- live_sync();
- m_wd = cur_live.wd = data;
- checkpoint();
- live_run();
- }
-}
-
-WRITE_LINE_MEMBER( victor_9000_fdc_t::via5_irq_w )
-{
- m_via5_irq = state;
-
- m_irq_cb(m_via4_irq || m_via5_irq || m_via6_irq);
-}
-
-
-READ8_MEMBER( victor_9000_fdc_t::via6_pa_r )
-{
- /*
-
- bit description
-
- PA0
- PA1 _TRK0D0
- PA2
- PA3 _TRK0D1
- PA4
- PA5
- PA6 WPS
- PA7 _SYNC
-
- */
-
- if (LOG_VIA) logerror("%s %s TRK0D0 %u TRK0D1 %u SYNC %u\n", machine().time().as_string(), machine().describe_context(), m_floppy0->trk00_r(), m_floppy1->trk00_r(), checkpoint_live.sync);
-
- UINT8 data = 0;
-
- // track 0 drive A sense
- data |= m_floppy0->trk00_r() << 1;
-
- // track 0 drive B sense
- data |= m_floppy1->trk00_r() << 3;
-
- // write protect sense
- data |= (m_drive ? m_floppy1->wpt_r() : m_floppy0->wpt_r()) << 6;
-
- // disk sync detect
- data |= checkpoint_live.sync << 7;
-
- return data;
-}
-
-WRITE8_MEMBER( victor_9000_fdc_t::via6_pa_w )
-{
- /*
-
- bit description
-
- PA0 LED0A
- PA1
- PA2 LED1A
- PA3
- PA4 SIDE SELECT
- PA5 DRIVE SELECT
- PA6
- PA7
-
- */
-
- // LED, drive A
- output_set_led_value(LED_A, BIT(data, 0));
-
- // LED, drive B
- output_set_led_value(LED_B, BIT(data, 2));
-
- bool sync = false;
-
- // dual side select
- int side = BIT(data, 4);
- if (m_side != side) sync = true;
-
- // select drive A/B
- int drive = BIT(data, 5);
- if (m_drive != drive) sync = true;
-
- if (sync)
- {
- live_sync();
-
- m_side = side;
- cur_live.side = side;
- m_floppy0->ss_w(side);
- m_floppy1->ss_w(side);
-
- m_drive = drive;
- cur_live.drive = drive;
-
- if (LOG_VIA) logerror("%s %s SIDE %u DRIVE %u\n", machine().time().as_string(), machine().describe_context(), side, drive);
-
- checkpoint();
- live_run();
- }
-}
-
-READ8_MEMBER( victor_9000_fdc_t::via6_pb_r )
-{
- /*
-
- bit description
-
- PB0 RDY0
- PB1 RDY1
- PB2
- PB3 _DS1
- PB4 _DS0
- PB5 SINGLE/_DOUBLE SIDED
- PB6
- PB7
-
- */
-
- UINT8 data = 0;
-
- // motor speed status, drive A
- data |= m_rdy0;
-
- // motor speed status, drive B
- data |= m_rdy1 << 1;
-
- // door B sense
- data |= (m_floppy1->exists() ? 0 : 1) << 3;
-
- // door A sense
- data |= (m_floppy0->exists() ? 0 : 1) << 4;
-
- // single/double sided jumper
- //data |= 0x20;
-
- return data;
-}
-
-WRITE8_MEMBER( victor_9000_fdc_t::via6_pb_w )
-{
- /*
-
- bit description
-
- PB0 RDY0
- PB1 RDY1
- PB2 _SCRESET
- PB3
- PB4
- PB5
- PB6 STP0
- PB7 STP1
-
- */
-
- set_rdy0(BIT(data, 0));
- set_rdy1(BIT(data, 1));
-
- // motor speed controller reset
- if (!BIT(data, 2))
- m_maincpu->reset();
-
- bool sync = false;
-
- // stepper enable A
- int stp0 = BIT(data, 6);
- if (m_stp0 != stp0) sync = true;
-
- // stepper enable B
- int stp1 = BIT(data, 7);
- if (m_stp1 != stp1) sync = true;
-
- if (sync)
- {
- live_sync();
-
- m_stp0 = stp0;
- update_stepper_motor(m_floppy0, m_stp0, m_st0, m_st0);
-
- m_stp1 = stp1;
- update_stepper_motor(m_floppy1, m_stp1, m_st1, m_st1);
-
- if (LOG_VIA) logerror("%s %s STP0 %u STP1 %u\n", machine().time().as_string(), machine().describe_context(), stp0, stp1);
-
- checkpoint();
- live_run();
- }
-}
-
-WRITE_LINE_MEMBER( victor_9000_fdc_t::drw_w )
-{
- if (m_drw != state)
- {
- live_sync();
- m_drw = cur_live.drw = state;
- checkpoint();
- if (LOG_VIA) logerror("%s %s DRW %u\n", machine().time().as_string(), machine().describe_context(), state);
- if (state) {
- pll_stop_writing(get_floppy(), machine().time());
- } else {
- pll_start_writing(machine().time());
- }
- live_run();
- }
-}
-
-WRITE_LINE_MEMBER( victor_9000_fdc_t::erase_w )
-{
- if (m_erase != state)
- {
- live_sync();
- m_erase = cur_live.erase = state;
- checkpoint();
- if (LOG_VIA) logerror("%s %s ERASE %u\n", machine().time().as_string(), machine().describe_context(), state);
- live_run();
- }
-}
-
-WRITE_LINE_MEMBER( victor_9000_fdc_t::via6_irq_w )
-{
- m_via6_irq = state;
-
- m_irq_cb(m_via4_irq || m_via5_irq || m_via6_irq);
-}
-
-READ8_MEMBER( victor_9000_fdc_t::cs7_r )
-{
- m_lbrdy_cb(1);
-
- if (LOG_VIA) logerror("%s %s LBRDY 1 : %02x\n", machine().time().as_string(), machine().describe_context(), m_via5->read(space, offset));
-
- return m_via5->read(space, offset);
-}
-
-WRITE8_MEMBER( victor_9000_fdc_t::cs7_w )
-{
- m_lbrdy_cb(1);
-
- if (LOG_VIA) logerror("%s %s LBRDY 1\n", machine().time().as_string(), machine().describe_context());
-
- m_via5->write(space, offset, data);
-}
-
-floppy_image_device* victor_9000_fdc_t::get_floppy()
-{
- return m_drive ? m_floppy1 : m_floppy0;
-}
-
-void victor_9000_fdc_t::live_start()
-{
- cur_live.tm = machine().time();
- cur_live.state = RUNNING;
- cur_live.next_state = -1;
-
- cur_live.shift_reg = 0;
- cur_live.shift_reg_write = 0;
- cur_live.bit_counter = 0;
- cur_live.sync_bit_counter = 0;
- cur_live.sync_byte_counter = 0;
-
- cur_live.drive = m_drive;
- cur_live.side = m_side;
- cur_live.drw = m_drw;
- cur_live.wd = m_wd;
- cur_live.wrsync = m_wrsync;
- cur_live.erase = m_erase;
-
- pll_reset(cur_live.tm);
- checkpoint_live = cur_live;
- pll_save_checkpoint();
-
- live_run();
-}
-
-void victor_9000_fdc_t::pll_reset(const attotime &when)
-{
- cur_pll.reset(when);
- cur_pll.set_clock(attotime::from_nsec(2130));
-}
-
-void victor_9000_fdc_t::pll_start_writing(const attotime &tm)
-{
- cur_pll.start_writing(tm);
- pll_reset(cur_live.tm);
-}
-
-void victor_9000_fdc_t::pll_commit(floppy_image_device *floppy, const attotime &tm)
-{
- cur_pll.commit(floppy, tm);
-}
-
-void victor_9000_fdc_t::pll_stop_writing(floppy_image_device *floppy, const attotime &tm)
-{
- cur_pll.stop_writing(floppy, tm);
- pll_reset(cur_live.tm);
-}
-
-void victor_9000_fdc_t::pll_save_checkpoint()
-{
- checkpoint_pll = cur_pll;
-}
-
-void victor_9000_fdc_t::pll_retrieve_checkpoint()
-{
- cur_pll = checkpoint_pll;
-}
-
-int victor_9000_fdc_t::pll_get_next_bit(attotime &tm, floppy_image_device *floppy, const attotime &limit)
-{
- return cur_pll.get_next_bit(tm, floppy, limit);
-}
-
-bool victor_9000_fdc_t::pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit)
-{
- return cur_pll.write_next_bit(bit, tm, floppy, limit);
-}
-
-void victor_9000_fdc_t::checkpoint()
-{
- pll_commit(get_floppy(), cur_live.tm);
- checkpoint_live = cur_live;
- pll_save_checkpoint();
-}
-
-void victor_9000_fdc_t::rollback()
-{
- cur_live = checkpoint_live;
- pll_retrieve_checkpoint();
-}
-
-void victor_9000_fdc_t::live_delay(int state)
-{
- cur_live.next_state = state;
- if(cur_live.tm != machine().time())
- t_gen->adjust(cur_live.tm - machine().time());
- else
- live_sync();
-}
-
-void victor_9000_fdc_t::live_sync()
-{
- if(!cur_live.tm.is_never()) {
- if(cur_live.tm > machine().time()) {
- rollback();
- live_run(machine().time());
- pll_commit(get_floppy(), cur_live.tm);
- } else {
- pll_commit(get_floppy(), cur_live.tm);
- if(cur_live.next_state != -1) {
- cur_live.state = cur_live.next_state;
- cur_live.next_state = -1;
- }
- if(cur_live.state == IDLE) {
- pll_stop_writing(get_floppy(), cur_live.tm);
- cur_live.tm = attotime::never;
- }
- }
- cur_live.next_state = -1;
- checkpoint();
- }
-}
-
-void victor_9000_fdc_t::live_abort()
-{
- if(!cur_live.tm.is_never() && cur_live.tm > machine().time()) {
- rollback();
- live_run(machine().time());
- }
-
- pll_stop_writing(get_floppy(), cur_live.tm);
-
- cur_live.tm = attotime::never;
- cur_live.state = IDLE;
- cur_live.next_state = -1;
-
- cur_live.brdy = 1;
- cur_live.lbrdy_changed = true;
- cur_live.sync = 1;
- cur_live.syn = 1;
- cur_live.syn_changed = true;
- cur_live.gcr_err = 1;
-}
-
-void victor_9000_fdc_t::live_run(const attotime &limit)
-{
- if(cur_live.state == IDLE || cur_live.next_state != -1)
- return;
-
- for(;;) {
- switch(cur_live.state) {
- case RUNNING: {
- bool syncpoint = false;
-
- if (cur_live.tm > limit)
- return;
-
- // read bit
- int bit = 0;
- if (cur_live.drw) {
- bit = pll_get_next_bit(cur_live.tm, get_floppy(), limit);
- if(bit < 0)
- return;
- }
-
- // write bit
- int write_bit = 0;
- if (!cur_live.drw) { // TODO WPS
- write_bit = BIT(cur_live.shift_reg_write, 9);
- if (pll_write_next_bit(write_bit, cur_live.tm, get_floppy(), limit))
- return;
- }
-
- // clock read shift register
- cur_live.shift_reg <<= 1;
- cur_live.shift_reg |= bit;
- cur_live.shift_reg &= 0x3ff;
-
- // sync
- int sync = !(cur_live.shift_reg == 0x3ff);
-
- // bit counter
- if (cur_live.drw) {
- if (!sync) {
- cur_live.bit_counter = 0;
- } else if (cur_live.sync) {
- cur_live.bit_counter++;
- if (cur_live.bit_counter == 10) {
- cur_live.bit_counter = 0;
- }
- }
- } else {
- cur_live.bit_counter++;
- if (cur_live.bit_counter == 10) {
- cur_live.bit_counter = 0;
- }
- }
-
- // sync counter
- if (sync) {
- cur_live.sync_bit_counter = 0;
- cur_live.sync_byte_counter = 10; // TODO 9 in schematics
- } else if (!cur_live.sync) {
- cur_live.sync_bit_counter++;
- if (cur_live.sync_bit_counter == 10) {
- cur_live.sync_bit_counter = 0;
- cur_live.sync_byte_counter++;
- if (cur_live.sync_byte_counter == 16) {
- cur_live.sync_byte_counter = 0;
- }
- }
- }
-
- // syn
- int syn = !(cur_live.sync_byte_counter == 15);
-
- // GCR decoder
- if (cur_live.drw) {
- cur_live.i = cur_live.drw << 10 | cur_live.shift_reg;
- } else {
- cur_live.i = cur_live.drw << 10 | 0x200 | ((cur_live.wd & 0xf0) << 1) | cur_live.wrsync << 4 | (cur_live.wd & 0x0f);
- }
-
- cur_live.e = m_gcr_rom->base()[cur_live.i];
-
- attotime next = cur_live.tm + m_period;
- if (LOG) logerror("%s:%s cyl %u bit %u sync %u bc %u sr %03x sbc %u sBC %u syn %u i %03x e %02x\n",cur_live.tm.as_string(),next.as_string(),get_floppy()->get_cyl(),bit,sync,cur_live.bit_counter,cur_live.shift_reg,cur_live.sync_bit_counter,cur_live.sync_byte_counter,syn,cur_live.i,cur_live.e);
-
- // byte ready
- int brdy = !(cur_live.bit_counter == 9);
-
- // GCR error
- int gcr_err = !(brdy || BIT(cur_live.e, 3));
-
- if (LOG_BITS) {
- if (cur_live.drw) {
- 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);
- } else {
- logerror("%s cyl %u writing bit %u bc %u sr %03x i %03x e %02x\n",cur_live.tm.as_string(),get_floppy()->get_cyl(),write_bit,cur_live.bit_counter,cur_live.shift_reg_write,cur_live.i,cur_live.e);
- }
- }
-
- if (!brdy) {
- // load write shift register
- cur_live.shift_reg_write = GCR_ENCODE(cur_live.e, cur_live.i);
-
- if (LOG) logerror("%s load write shift register %03x\n",cur_live.tm.as_string(),cur_live.shift_reg_write);
- } else {
- // clock write shift register
- cur_live.shift_reg_write <<= 1;
- cur_live.shift_reg_write &= 0x3ff;
- }
-
- if (brdy != cur_live.brdy) {
- if (LOG) logerror("%s BRDY %u\n", cur_live.tm.as_string(),brdy);
- if (!brdy)
- {
- cur_live.lbrdy_changed = true;
- if (LOG_VIA) logerror("%s LBRDY 0 : %02x\n", cur_live.tm.as_string(), GCR_DECODE(cur_live.e, cur_live.i));
- }
- cur_live.brdy = brdy;
- 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;
- }
-
- if (syn != cur_live.syn) {
- if (LOG) logerror("%s SYN %u\n", cur_live.tm.as_string(),syn);
- cur_live.syn = syn;
- cur_live.syn_changed = true;
- syncpoint = true;
- }
-
- if (gcr_err != cur_live.gcr_err) {
- if (LOG) logerror("%s GCR ERR %u\n", cur_live.tm.as_string(),gcr_err);
- cur_live.gcr_err = gcr_err;
- syncpoint = true;
- }
-
- if (syncpoint) {
- live_delay(RUNNING_SYNCPOINT);
- return;
- }
- break;
- }
-
- case RUNNING_SYNCPOINT: {
- if (cur_live.lbrdy_changed) {
- m_lbrdy_cb(0);
- cur_live.lbrdy_changed = false;
- }
-
- if (cur_live.syn_changed) {
- m_syn_cb(cur_live.syn);
- cur_live.syn_changed = false;
- }
-
- m_via5->write_ca1(cur_live.brdy);
-
- cur_live.state = RUNNING;
- checkpoint();
- break;
- }
- }
- }
-}