diff options
Diffstat (limited to 'src/devices/bus/hexbus/hx5102.cpp')
-rw-r--r-- | src/devices/bus/hexbus/hx5102.cpp | 307 |
1 files changed, 165 insertions, 142 deletions
diff --git a/src/devices/bus/hexbus/hx5102.cpp b/src/devices/bus/hexbus/hx5102.cpp index 6730c5dd453..999df7fe520 100644 --- a/src/devices/bus/hexbus/hx5102.cpp +++ b/src/devices/bus/hexbus/hx5102.cpp @@ -75,20 +75,21 @@ #include "hx5102.h" #include "formats/ti99_dsk.h" -#define LOG_HEXBUS (1U<<1) // Hexbus operation -#define LOG_RESET (1U<<2) // Reset -#define LOG_WARN (1U<<3) // Warnings -#define LOG_READY (1U<<4) // READY -#define LOG_SIGNALS (1U<<5) // IRQ/DRQ -#define LOG_CRU (1U<<6) // CRU -#define LOG_RAM (1U<<7) // RAM -#define LOG_DMA (1U<<8) // DMA -#define LOG_MOTOR (1U<<9) // Motor activity -#define LOG_STATUS (1U<<10) // Main status register -#define LOG_FIFO (1U<<11) // Data register +#define LOG_HEXBUS (1U << 1) // Hexbus operation +#define LOG_RESET (1U << 2) // Reset +#define LOG_WARN (1U << 3) // Warnings +#define LOG_READY (1U << 4) // READY +#define LOG_SIGNALS (1U << 5) // IRQ/DRQ +#define LOG_CRU (1U << 6) // CRU +#define LOG_RAM (1U << 7) // RAM +#define LOG_DMA (1U << 8) // DMA +#define LOG_MOTOR (1U << 9) // Motor activity +#define LOG_STATUS (1U << 10) // Main status register +#define LOG_FIFO (1U << 11) // Data register +#define LOG_CONFIG (1U << 12) // Configuration // Minimum log should be config and warnings -#define VERBOSE ( LOG_GENERAL | LOG_WARN ) +#define VERBOSE (LOG_GENERAL | LOG_WARN | LOG_CONFIG) #include "logmacro.h" @@ -104,12 +105,15 @@ #define ROM1_TAG "u25_rom" #define ROM2_TAG "u29_rom" +#define FLOP0 "d0" +#define FLOP1 "d1" + #define MOTOR_TIMER 1 #define UNDEF -1 -DEFINE_DEVICE_TYPE_NS(HX5102, bus::hexbus, hx5102_device, "ti_hx5102", "TI Hexbus Floppy Drive") +DEFINE_DEVICE_TYPE(HX5102, bus::hexbus::hx5102_device, "ti_hx5102", "TI Hexbus Floppy Drive") -namespace bus { namespace hexbus { +namespace bus::hexbus { void hx5102_device::memmap(address_map &map) { @@ -121,7 +125,9 @@ void hx5102_device::memmap(address_map &map) */ void hx5102_device::crumap(address_map &map) { - map(0x17e0, 0x17ff).rw(FUNC(hx5102_device::cruread), FUNC(hx5102_device::cruwrite)); + map(0x17e0, 0x17ff).r(FUNC(hx5102_device::cruread)); + map(0x17e0, 0x17ef).w(m_crulatch[0], FUNC(ls259_device::write_d0)); + map(0x17f0, 0x17ff).w(m_crulatch[1], FUNC(ls259_device::write_d0)); } hx5102_device::hx5102_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock): @@ -131,15 +137,19 @@ hx5102_device::hx5102_device(const machine_config &mconfig, const char *tag, dev m_motor_on(false), m_mspeed_on(false), m_pending_int(false), + m_pending_drq(false), m_dcs(false), m_dack(false), m_dacken(false), m_wait(false), + m_flopcon0(*this, FLOP0), + m_flopcon1(*this, FLOP1), m_current_floppy(nullptr), m_floppy_select(0), m_floppy_select_last(UNDEF), m_hexbus_ctrl(*this, IBC_TAG), m_floppy_ctrl(*this, FDC_TAG), + m_crulatch(*this, "crulatch%u", 0U), m_motormf(*this, MTRD_TAG), m_speedmf(*this, MTSPD_TAG), m_readyff(*this, READYFF_TAG), @@ -148,7 +158,7 @@ hx5102_device::hx5102_device(const machine_config &mconfig, const char *tag, dev { } -WRITE8_MEMBER( hx5102_device::external_operation ) +void hx5102_device::external_operation(offs_t offset, uint8_t data) { static char const *const extop[8] = { "inv1", "inv2", "IDLE", "RSET", "inv3", "CKON", "CKOF", "LREX" }; if (offset != IDLE_OP) LOGMASKED(LOG_WARN, "External operation %s not implemented on HX5102 board\n", extop[offset]); @@ -182,7 +192,7 @@ WRITE8_MEMBER( hx5102_device::external_operation ) /* Reading from the address space of the drive. */ -READ8_MEMBER( hx5102_device::read ) +uint8_t hx5102_device::read(offs_t offset) { bool ramen1 = ((offset & 0xf800)==0xe000); bool ramen2 = ((offset & 0xf800)==0xe800); @@ -220,11 +230,11 @@ READ8_MEMBER( hx5102_device::read ) // Floppy drive controller if (m_dcs) - return fdc_read(space, offset&0x000f); + return fdc_read(offset&0x000f); // Hexbus controller if (hcs) - return ibc_read(space, offset&0x000f); + return ibc_read(offset&0x000f); // DMA if (m_dack) @@ -243,7 +253,7 @@ READ8_MEMBER( hx5102_device::read ) /* Writing into the address space of the drive. */ -WRITE8_MEMBER( hx5102_device::write ) +void hx5102_device::write(offs_t offset, uint8_t data) { bool ramen1 = ((offset & 0xf800)==0xe000); bool ramen2 = ((offset & 0xf800)==0xe800); @@ -270,14 +280,14 @@ WRITE8_MEMBER( hx5102_device::write ) // Floppy drive controller if (m_dcs) { - fdc_write(space, offset&0x000f, data); + fdc_write(offset&0x000f, data); return; } // Hexbus controller if (hcs) { - ibc_write(space, offset&0x000f, data); + ibc_write(offset&0x000f, data); return; } @@ -296,7 +306,7 @@ WRITE8_MEMBER( hx5102_device::write ) /* Clock line from the CPU. Used to control wait state generation. */ -WRITE_LINE_MEMBER( hx5102_device::clock_out ) +void hx5102_device::clock_out(int state) { m_readyff->clock_w(state); } @@ -313,7 +323,7 @@ void hx5102_device::hexbus_value_changed(uint8_t data) Propagate READY signals to the CPU. This is used to hold the CPU during DMA accesses. */ -WRITE_LINE_MEMBER( hx5102_device::board_ready ) +void hx5102_device::board_ready(int state) { if (m_ready_old != state) { @@ -327,7 +337,7 @@ WRITE_LINE_MEMBER( hx5102_device::board_ready ) /* Trigger RESET. */ -WRITE_LINE_MEMBER( hx5102_device::board_reset ) +void hx5102_device::board_reset(int state) { LOGMASKED(LOG_RESET, "Incoming RESET line = %d\n", state); @@ -342,7 +352,7 @@ WRITE_LINE_MEMBER( hx5102_device::board_reset ) /* Effect from the motor monoflop. */ -WRITE_LINE_MEMBER( hx5102_device::motor_w ) +void hx5102_device::motor_w(int state) { m_motor_on = (state==ASSERT_LINE); LOGMASKED(LOG_MOTOR, "Motor %s\n", m_motor_on? "start" : "stop"); @@ -356,7 +366,7 @@ WRITE_LINE_MEMBER( hx5102_device::motor_w ) Effect from the speed monoflop. This is essentially a watchdog to check whether the lock on the CPU must be released due to an error. */ -WRITE_LINE_MEMBER( hx5102_device::mspeed_w ) +void hx5102_device::mspeed_w(int state) { m_mspeed_on = (state==ASSERT_LINE); LOGMASKED(LOG_READY, "Speedcheck %s\n", m_mspeed_on? "on" : "off"); @@ -366,7 +376,7 @@ WRITE_LINE_MEMBER( hx5102_device::mspeed_w ) /* Read access to the floppy controller */ -READ8_MEMBER(hx5102_device::fdc_read) +uint8_t hx5102_device::fdc_read(offs_t offset) { uint8_t val = 0; switch (offset) @@ -388,7 +398,7 @@ READ8_MEMBER(hx5102_device::fdc_read) /* Write access to the floppy controller */ -WRITE8_MEMBER(hx5102_device::fdc_write) +void hx5102_device::fdc_write(offs_t offset, uint8_t data) { m_dcs = ((offset & 0x0003)==0); @@ -416,21 +426,21 @@ void hx5102_device::update_readyff_input() /* Access to the Hexbus controller */ -READ8_MEMBER(hx5102_device::ibc_read) +uint8_t hx5102_device::ibc_read(offs_t offset) { if ((offset & 1)==0) - return m_hexbus_ctrl->read(space, (offset>>1)&1); + return m_hexbus_ctrl->read((offset>>1)&1); else return 0; } -WRITE8_MEMBER(hx5102_device::ibc_write) +void hx5102_device::ibc_write(offs_t offset, uint8_t data) { if ((offset & 1)==0) - m_hexbus_ctrl->write(space, (offset>>1)&1, data); + m_hexbus_ctrl->write((offset>>1)&1, data); } -WRITE8_MEMBER(hx5102_device::hexbus_out) +void hx5102_device::hexbus_out(uint8_t data) { LOGMASKED(LOG_HEXBUS, "Write to hexbus: BAV*=%d, HSK*=%d, data=%x\n", bav_line(data)==ASSERT_LINE? 0:1, hsk_line(data)==ASSERT_LINE? 0:1, data_lines(data)); @@ -445,7 +455,7 @@ WRITE8_MEMBER(hx5102_device::hexbus_out) /* Latch the HSK* to low. */ -WRITE_LINE_MEMBER(hx5102_device::hsklatch_out) +void hx5102_device::hsklatch_out(int state) { LOGMASKED(LOG_HEXBUS, "Latching HSK*\n"); m_myvalue &= ~HEXBUS_LINE_HSK; @@ -464,7 +474,7 @@ WRITE_LINE_MEMBER(hx5102_device::hsklatch_out) MON = Motor on INT = Interrupt from i8272A */ -READ8_MEMBER(hx5102_device::cruread) +uint8_t hx5102_device::cruread(offs_t offset) { uint8_t crubits = 0; // LOGMASKED(LOG_CRU, "Reading CRU addresses %04x-%04x\n", 0x17e0 + (offset<<4), 0x17ee + (offset<<4)); @@ -480,92 +490,81 @@ READ8_MEMBER(hx5102_device::cruread) /* CRU write access. */ -WRITE8_MEMBER(hx5102_device::cruwrite) +void hx5102_device::nocomp_w(int state) { - // LOG("Writing CRU address %04x: %x\n", 0x17e0 + (offset<<1), data); - switch (offset) - { - case 0: - // unused right now - LOGMASKED(LOG_CRU, "Set precompensation = %d\n", data); - break; - case 1: - if (data==1) - { - LOGMASKED(LOG_CRU, "Trigger motor monoflop\n"); - } - m_motormf->b_w(data); - break; - case 2: - LOGMASKED(LOG_CRU, "Set undefined CRU bit 2 to %d\n", data); - break; - case 3: - LOGMASKED(LOG_CRU, "Set step direction = %d\n", data); - if (m_current_floppy != nullptr) m_current_floppy->dir_w((data==0)? 1 : 0); - break; - case 4: - if (data==1) - { - LOGMASKED(LOG_CRU, "Assert DACK*\n"); - m_dacken = (data != 0); - } - break; - case 5: - if (data==1) - { - LOGMASKED(LOG_CRU, "Step pulse\n"); - } - if (m_current_floppy != nullptr) m_current_floppy->stp_w((data==0)? 1 : 0); - break; - case 6: - if (data==1) - { - LOGMASKED(LOG_CRU, "Start watchdog\n"); - } - m_speedmf->b_w(data); - break; - case 7: - if (data==0) - { - LOGMASKED(LOG_CRU, "Reset i8272A controller\n"); - m_floppy_ctrl->soft_reset(); - } - break; - case 8: - LOGMASKED(LOG_CRU, "Set drive select 0 to %d\n", data); - if (data == 1) m_floppy_select |= 1; - else m_floppy_select &= ~1; - break; - case 9: - LOGMASKED(LOG_CRU, "Set drive select 1 to %d\n", data); - if (data == 1) m_floppy_select |= 2; - else m_floppy_select &= ~2; - break; - case 10: - // External drive; not implemented - LOGMASKED(LOG_CRU, "Set drive select 2 to %d\n", data); - break; - case 11: - // External drive; not implemented - LOGMASKED(LOG_CRU, "Set drive select 3 to %d\n", data); - break; - case 12: - // External drive; not implemented - LOGMASKED(LOG_CRU, "Set auxiliary motor line to %d\n", data); - break; - case 13: - LOGMASKED(LOG_CRU, "Set CRU bit 13 to %d (unused)\n", data); - break; - case 14: - m_wait = (data!=0); - LOGMASKED(LOG_CRU, "READY circuit %s\n", m_wait? "active" : "inactive" ); - update_readyff_input(); - break; - case 15: - LOGMASKED(LOG_CRU, "Set CRU bit 15 to %d (unused)\n", data); - break; - } + // unused right now + LOGMASKED(LOG_CRU, "Set precompensation = %d\n", state); +} + +void hx5102_device::diren_w(int state) +{ + LOGMASKED(LOG_CRU, "Set step direction = %d\n", state); + if (m_current_floppy != nullptr) + m_current_floppy->dir_w((state==0)? 1 : 0); +} +void hx5102_device::dacken_w(int state) +{ + if (state==1) + LOGMASKED(LOG_CRU, "Assert DACK*\n"); + m_dacken = (state != 0); +} + +void hx5102_device::stepen_w(int state) +{ + if (state==1) + LOGMASKED(LOG_CRU, "Step pulse\n"); + if (m_current_floppy != nullptr) + m_current_floppy->stp_w((state==0)? 1 : 0); +} + +void hx5102_device::ds1_w(int state) +{ + LOGMASKED(LOG_CRU, "Set drive select 0 to %d\n", state); + if (state == 1) + m_floppy_select |= 1; + else + m_floppy_select &= ~1; + update_drive_select(); +} + +void hx5102_device::ds2_w(int state) +{ + LOGMASKED(LOG_CRU, "Set drive select 1 to %d\n", state); + if (state == 1) + m_floppy_select |= 2; + else + m_floppy_select &= ~2; + update_drive_select(); +} + +void hx5102_device::ds3_w(int state) +{ + // External drive; not implemented + LOGMASKED(LOG_CRU, "Set drive select 2 to %d\n", state); +} + +void hx5102_device::ds4_w(int state) +{ + // External drive; not implemented + LOGMASKED(LOG_CRU, "Set drive select 3 to %d\n", state); +} + +void hx5102_device::aux_motor_w(int state) +{ + // External drive; not implemented + LOGMASKED(LOG_CRU, "Set auxiliary motor line to %d\n", state); +} + +void hx5102_device::wait_w(int state) +{ + m_wait = (state!=0); + LOGMASKED(LOG_CRU, "READY circuit %s\n", m_wait? "active" : "inactive" ); + update_readyff_input(); +} + +void hx5102_device::update_drive_select() +{ if (m_floppy_select != m_floppy_select_last) { if (m_floppy_select == 1) @@ -588,13 +587,21 @@ WRITE8_MEMBER(hx5102_device::cruwrite) */ void hx5102_device::device_start() { - m_floppy[0] = m_floppy[1] = nullptr; - - if (subdevice("d0")!=nullptr) m_floppy[0] = static_cast<floppy_image_device*>(subdevice("d0")->subdevices().first()); - if (subdevice("d1")!=nullptr) m_floppy[1] = static_cast<floppy_image_device*>(subdevice("d1")->subdevices().first()); - m_rom1 = (uint8_t*)memregion(DSR_TAG)->base(); m_rom2 = (uint8_t*)memregion(DSR_TAG)->base() + 0x2000; + + m_floppy[0] = m_flopcon0->get_device(); + m_floppy[1] = m_flopcon1->get_device(); + + if (m_floppy[0] != nullptr) + LOGMASKED(LOG_CONFIG, "Internal floppy drive connected\n"); + else + LOGMASKED(LOG_WARN, "Internal floppy drive not found\n"); + + if (m_floppy[1] != nullptr) + LOGMASKED(LOG_CONFIG, "External floppy drive connected\n"); + else + LOGMASKED(LOG_CONFIG, "External floppy drive not connected\n"); } /* @@ -610,7 +617,7 @@ void hx5102_device::device_reset() Callbacks from the i8272A chip Interrupt */ -WRITE_LINE_MEMBER( hx5102_device::fdc_irq_w ) +void hx5102_device::fdc_irq_w(int state) { line_state irq = state? ASSERT_LINE : CLEAR_LINE; LOGMASKED(LOG_SIGNALS, "INTRQ callback = %d\n", irq); @@ -622,7 +629,7 @@ WRITE_LINE_MEMBER( hx5102_device::fdc_irq_w ) Callbacks from the i8272A chip DMA request */ -WRITE_LINE_MEMBER( hx5102_device::fdc_drq_w ) +void hx5102_device::fdc_drq_w(int state) { line_state drq = state? ASSERT_LINE : CLEAR_LINE; LOGMASKED(LOG_SIGNALS, "DRQ callback = %d\n", drq); @@ -633,10 +640,12 @@ WRITE_LINE_MEMBER( hx5102_device::fdc_drq_w ) /* Define the floppy formats. */ -FLOPPY_FORMATS_MEMBER(hx5102_device::floppy_formats) - FLOPPY_TI99_SDF_FORMAT, - FLOPPY_TI99_TDF_FORMAT -FLOPPY_FORMATS_END +void hx5102_device::floppy_formats(format_registration &fr) +{ + fr.add_mfm_containers(); + fr.add(FLOPPY_TI99_SDF_FORMAT); + fr.add(FLOPPY_TI99_TDF_FORMAT); +} /* Only one fixed floppy drive in the device. @@ -677,7 +686,7 @@ void hx5102_device::device_add_mconfig(machine_config& config) HEXBUS(config, "hexbus", 0, hexbus_options, nullptr); // TMS9995 CPU @ 12.0 MHz - TMS9995(config, m_flopcpu, XTAL(12'000'000)); + TMS9995(config, m_flopcpu, 12_MHz_XTAL); m_flopcpu->set_addrmap(AS_PROGRAM, &hx5102_device::memmap); m_flopcpu->set_addrmap(AS_IO, &hx5102_device::crumap); m_flopcpu->extop_cb().set(FUNC(hx5102_device::external_operation)); @@ -687,27 +696,41 @@ void hx5102_device::device_add_mconfig(machine_config& config) // Not connected: Select lines (DS0, DS1), Head load (HDL), VCO // Tied to 1: READY // Tied to 0: TC - I8272A(config, m_floppy_ctrl, 8'000'000, false); + I8272A(config, m_floppy_ctrl, 8_MHz_XTAL / 2, false); m_floppy_ctrl->intrq_wr_callback().set(FUNC(hx5102_device::fdc_irq_w)); m_floppy_ctrl->drq_wr_callback().set(FUNC(hx5102_device::fdc_drq_w)); - FLOPPY_CONNECTOR(config, "d0", hx5102_drive, "525dd", hx5102_device::floppy_formats).enable_sound(true); - FLOPPY_CONNECTOR(config, "d1", hx5102_drive, nullptr, hx5102_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_flopcon0, hx5102_drive, "525dd", hx5102_device::floppy_formats).enable_sound(true); + FLOPPY_CONNECTOR(config, m_flopcon1, hx5102_drive, nullptr, hx5102_device::floppy_formats).enable_sound(true); + + // Addressable latches + LS259(config, m_crulatch[0]); // U18 + m_crulatch[0]->q_out_cb<0>().set(FUNC(hx5102_device::nocomp_w)); + m_crulatch[0]->q_out_cb<1>().set(m_motormf, FUNC(ttl74123_device::b_w)); + m_crulatch[0]->q_out_cb<3>().set(FUNC(hx5102_device::diren_w)); + m_crulatch[0]->q_out_cb<4>().set(FUNC(hx5102_device::dacken_w)); + m_crulatch[0]->q_out_cb<5>().set(FUNC(hx5102_device::stepen_w)); + m_crulatch[0]->q_out_cb<6>().set(m_speedmf, FUNC(ttl74123_device::b_w)); + m_crulatch[0]->q_out_cb<7>().set(m_floppy_ctrl, FUNC(i8272a_device::reset_w)).invert(); + + LS259(config, m_crulatch[1]); // U10 + m_crulatch[1]->q_out_cb<0>().set(FUNC(hx5102_device::ds1_w)); + m_crulatch[1]->q_out_cb<1>().set(FUNC(hx5102_device::ds2_w)); + m_crulatch[1]->q_out_cb<2>().set(FUNC(hx5102_device::ds3_w)); + m_crulatch[1]->q_out_cb<3>().set(FUNC(hx5102_device::ds4_w)); + m_crulatch[1]->q_out_cb<4>().set(FUNC(hx5102_device::aux_motor_w)); + m_crulatch[1]->q_out_cb<6>().set(FUNC(hx5102_device::wait_w)); // Monoflops - TTL74123(config, m_motormf, 0); + TTL74123(config, m_motormf, RES_K(200), CAP_U(47)); m_motormf->set_connection_type(TTL74123_GROUNDED); - m_motormf->set_resistor_value(RES_K(200)); - m_motormf->set_capacitor_value(CAP_U(47)); m_motormf->set_a_pin_value(0); m_motormf->set_b_pin_value(1); m_motormf->set_clear_pin_value(1); m_motormf->out_cb().set(FUNC(hx5102_device::motor_w)); - TTL74123(config, m_speedmf, 0); + TTL74123(config, m_speedmf, RES_K(200), CAP_U(10)); m_speedmf->set_connection_type(TTL74123_GROUNDED); - m_speedmf->set_resistor_value(RES_K(200)); - m_speedmf->set_capacitor_value(CAP_U(10)); m_speedmf->set_a_pin_value(0); m_speedmf->set_b_pin_value(1); m_speedmf->set_clear_pin_value(1); @@ -738,5 +761,5 @@ ioport_constructor hx5102_device::device_input_ports() const return INPUT_PORTS_NAME( hx5102 ); } -} } // end namespace bus::hexbus +} // end namespace bus::hexbus |