summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/hexbus/hx5102.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/hexbus/hx5102.cpp')
-rw-r--r--src/devices/bus/hexbus/hx5102.cpp307
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