summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/multibus/isbc202.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/multibus/isbc202.cpp')
-rw-r--r--src/devices/bus/multibus/isbc202.cpp183
1 files changed, 76 insertions, 107 deletions
diff --git a/src/devices/bus/multibus/isbc202.cpp b/src/devices/bus/multibus/isbc202.cpp
index 490ed125e97..97b7bca71ae 100644
--- a/src/devices/bus/multibus/isbc202.cpp
+++ b/src/devices/bus/multibus/isbc202.cpp
@@ -61,6 +61,7 @@
#include "emu.h"
#include "isbc202.h"
#include "formats/img_dsk.h"
+#include "formats/fs_isis.h"
// Debugging
#include "logmacro.h"
@@ -100,13 +101,6 @@ constexpr unsigned HALF_BIT_CELL_US = 1;// Half bit cell duration in µs
constexpr unsigned BIT_FREQUENCY = 500000; // Frequency of bit cells in Hz
constexpr uint16_t CRC_POLY = 0x1021; // CRC-CCITT
-// Timers
-enum {
- TIMEOUT_TMR_ID,
- BYTE_TMR_ID,
- F_TMR_ID
-};
-
// device type definition
DEFINE_DEVICE_TYPE(ISBC202, isbc202_device, "isbc202", "iSBC-202 floppy controller")
@@ -213,13 +207,12 @@ offs_t isbc202_disassembler::disassemble(std::ostream &stream, offs_t pc, const
// isbc202_device
isbc202_device::isbc202_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : cpu_device(mconfig , ISBC202 , tag , owner , multibus_slot_device::BUS_CLOCK / 4)
+ : cpu_device(mconfig , ISBC202 , tag , owner , DERIVED_CLOCK(1, 4))
, device_multibus_interface(mconfig , *this)
, m_mcu(*this , "mcu")
, m_cpes(*this , "cpe%u" , 0)
, m_drives(*this , "floppy%u" , 0)
, m_program_config("microprogram" , ENDIANNESS_BIG , 32 , 9 , -2)
- , m_cache(nullptr)
, m_mem_space(nullptr)
{
}
@@ -228,17 +221,7 @@ isbc202_device::~isbc202_device()
{
}
-void isbc202_device::install_io_rw(address_space& space)
-{
- space.install_readwrite_handler(0x78 , 0x7f , read8_delegate(*this , FUNC(isbc202_device::io_r)) , write8_delegate(*this , FUNC(isbc202_device::io_w)));
-}
-
-void isbc202_device::install_mem_rw(address_space& space)
-{
- m_mem_space = &space;
-}
-
-READ8_MEMBER(isbc202_device::io_r)
+uint8_t isbc202_device::io_r(address_space &space, offs_t offset)
{
uint8_t res = 0;
@@ -284,11 +267,10 @@ READ8_MEMBER(isbc202_device::io_r)
case 3:
// Read result byte (no auto XACK)
- if (m_cpu == nullptr) {
- m_cpu = dynamic_cast<cpu_device*>(&space.device());
+ if (!m_2nd_pass) {
set_start(3 , true);
} else {
- m_cpu = nullptr;
+ m_2nd_pass = false;
res = m_data_low_out;
}
break;
@@ -302,7 +284,7 @@ READ8_MEMBER(isbc202_device::io_r)
return res;
}
-WRITE8_MEMBER(isbc202_device::io_w)
+void isbc202_device::io_w(address_space &space, offs_t offset, uint8_t data)
{
LOG_BUS("IO W @%u=%02x\n" , offset , data);
@@ -315,12 +297,12 @@ WRITE8_MEMBER(isbc202_device::io_w)
case 4:
case 5:
case 6:
- if (m_cpu != nullptr) {
- LOG("CPU != NULL!\n");
+ if (!m_2nd_pass) {
+ m_cpu_data = data;
+ set_start(offset , false);
+ } else {
+ m_2nd_pass = false;
}
- m_cpu = dynamic_cast<cpu_device*>(&space.device());
- m_cpu_data = data;
- set_start(offset , false);
break;
case 7:
@@ -334,14 +316,14 @@ WRITE8_MEMBER(isbc202_device::io_w)
}
}
-WRITE_LINE_MEMBER(isbc202_device::co_w)
+void isbc202_device::co_w(int state)
{
m_inputs[ IN_SEL_CO ] = state;
m_mcu->fi_w(state);
m_cpes[ 3 ]->li_w(state);
}
-READ8_MEMBER(isbc202_device::px_r)
+uint8_t isbc202_device::px_r()
{
if (BIT(m_px_s1s0 , 0)) {
return m_cmd & 7;
@@ -379,7 +361,7 @@ void isbc202_device::device_start()
save_item(NAME(m_op_us));
save_item(NAME(m_px_s1s0));
save_item(NAME(m_cmd));
- save_item(NAME(m_cpu_rd));
+ save_item(NAME(m_2nd_pass));
save_item(NAME(m_ready_in));
save_item(NAME(m_ready_ff));
save_item(NAME(m_gate_lower));
@@ -406,7 +388,7 @@ void isbc202_device::device_start()
save_item(NAME(m_amwrt));
save_item(NAME(m_dlyd_amwrt));
- m_cache = space(AS_PROGRAM).cache<2 , -2 , ENDIANNESS_BIG>();
+ space(AS_PROGRAM).cache(m_cache);
set_icountptr(m_icount);
space(AS_PROGRAM).install_rom(0 , 0x1ff , memregion("microcode")->base());
@@ -415,9 +397,12 @@ void isbc202_device::device_start()
d->get_device()->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(&isbc202_device::floppy_index_cb , this));
}
- m_timeout_timer = timer_alloc(TIMEOUT_TMR_ID);
- m_byte_timer = timer_alloc(BYTE_TMR_ID);
- m_f_timer = timer_alloc(F_TMR_ID);
+ m_timeout_timer = timer_alloc(FUNC(isbc202_device::timeout_tick), this);
+ m_byte_timer = timer_alloc(FUNC(isbc202_device::byte_tick), this);
+ m_f_timer = timer_alloc(FUNC(isbc202_device::f_tick), this);
+
+ m_mem_space = &m_bus->space(AS_PROGRAM);
+ m_bus->space(AS_IO).install_readwrite_handler(0x78, 0x7f, read8m_delegate(*this, FUNC(isbc202_device::io_r)), write8m_delegate(*this, FUNC(isbc202_device::io_w)));
}
void isbc202_device::device_reset()
@@ -434,7 +419,7 @@ void isbc202_device::device_reset()
m_inputs[ IN_SEL_TIMEOUT ] = true;
m_inputs[ IN_SEL_F ] = false;
- m_cpu = nullptr;
+ m_2nd_pass = false;
m_irq = false;
@@ -446,37 +431,32 @@ void isbc202_device::device_reset()
m_f_timer->reset();
}
-void isbc202_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+TIMER_CALLBACK_MEMBER(isbc202_device::timeout_tick)
{
- switch (id) {
- case TIMEOUT_TMR_ID:
- m_inputs[ IN_SEL_TIMEOUT ] = true;
- break;
-
- case BYTE_TMR_ID:
- m_inputs[ IN_SEL_F ] = true;
- m_f_timer->adjust(attotime::from_usec(HALF_BIT_CELL_US * 2));
- m_dlyd_amwrt = m_amwrt;
- if (m_reading) {
- m_last_f_time = machine().time();
- rd_bits(8);
- m_byte_timer->adjust(m_pll.ctime - machine().time());
- // Updating of AZ flag actually happens when F goes low
- m_inputs[ IN_SEL_AZ ] = m_crc == 0;
- }
- break;
+ m_inputs[ IN_SEL_TIMEOUT ] = true;
+}
- case F_TMR_ID:
- m_inputs[ IN_SEL_F ] = false;
- if (m_writing) {
- write_byte();
- m_data_sr = dbus_r();
- m_byte_timer->adjust(attotime::from_usec(HALF_BIT_CELL_US * 14));
- }
- break;
+TIMER_CALLBACK_MEMBER(isbc202_device::byte_tick)
+{
+ m_inputs[ IN_SEL_F ] = true;
+ m_f_timer->adjust(attotime::from_usec(HALF_BIT_CELL_US * 2));
+ m_dlyd_amwrt = m_amwrt;
+ if (m_reading) {
+ m_last_f_time = machine().time();
+ rd_bits(8);
+ m_byte_timer->adjust(m_pll.ctime - machine().time());
+ // Updating of AZ flag actually happens when F goes low
+ m_inputs[ IN_SEL_AZ ] = m_crc == 0;
+ }
+}
- default:
- break;
+TIMER_CALLBACK_MEMBER(isbc202_device::f_tick)
+{
+ m_inputs[ IN_SEL_F ] = false;
+ if (m_writing) {
+ write_byte();
+ m_data_sr = dbus_r();
+ m_byte_timer->adjust(attotime::from_usec(HALF_BIT_CELL_US * 14));
}
}
@@ -498,10 +478,10 @@ static void isbc202_floppies(device_slot_interface &device)
device.option_add("8ssdd" , FLOPPY_8_SSDD);
}
-static const floppy_format_type isbc202_floppy_formats[] = {
- FLOPPY_MFI_FORMAT,
- FLOPPY_IMG_FORMAT,
- nullptr
+static void isbc202_floppy_formats(format_registration &fr)
+{
+ fr.add(FLOPPY_IMG_FORMAT);
+ fr.add(fs::ISIS);
};
void isbc202_device::device_add_mconfig(machine_config &config)
@@ -518,34 +498,34 @@ void isbc202_device::device_add_mconfig(machine_config &config)
}
// Connect CO/CI signals
- m_mcu->fo_w().set(m_cpes[ 0 ] , FUNC(i3002_device::ci_w));
- m_cpes[ 0 ]->co_w().set(m_cpes[ 1 ] , FUNC(i3002_device::ci_w));
- m_cpes[ 1 ]->co_w().set(m_cpes[ 2 ] , FUNC(i3002_device::ci_w));
- m_cpes[ 2 ]->co_w().set(m_cpes[ 3 ] , FUNC(i3002_device::ci_w));
- m_cpes[ 3 ]->co_w().set(FUNC(isbc202_device::co_w));
+ m_mcu->set_fo_w_cb(m_cpes[ 0 ] , FUNC(i3002_device::ci_w));
+ m_cpes[ 0 ]->set_co_w_cb(m_cpes[ 1 ] , FUNC(i3002_device::ci_w));
+ m_cpes[ 1 ]->set_co_w_cb(m_cpes[ 2 ] , FUNC(i3002_device::ci_w));
+ m_cpes[ 2 ]->set_co_w_cb(m_cpes[ 3 ] , FUNC(i3002_device::ci_w));
+ m_cpes[ 3 ]->set_co_w_cb(FUNC(isbc202_device::co_w));
// Connect RO/LI signals
- m_cpes[ 0 ]->ro_w().set(FUNC(isbc202_device::co_w));
- m_cpes[ 1 ]->ro_w().set(m_cpes[ 0 ] , FUNC(i3002_device::li_w));
- m_cpes[ 2 ]->ro_w().set(m_cpes[ 1 ] , FUNC(i3002_device::li_w));
- m_cpes[ 3 ]->ro_w().set(m_cpes[ 2 ] , FUNC(i3002_device::li_w));
+ m_cpes[ 0 ]->set_ro_w_cb(FUNC(isbc202_device::co_w));
+ m_cpes[ 1 ]->set_ro_w_cb(m_cpes[ 0 ] , FUNC(i3002_device::li_w));
+ m_cpes[ 2 ]->set_ro_w_cb(m_cpes[ 1 ] , FUNC(i3002_device::li_w));
+ m_cpes[ 3 ]->set_ro_w_cb(m_cpes[ 2 ] , FUNC(i3002_device::li_w));
// Connect M-bus
- m_cpes[ 0 ]->mbus_r().set([this]() { return mbus_r(); });
- m_cpes[ 1 ]->mbus_r().set([this]() { return mbus_r() >> 2; });
- m_cpes[ 2 ]->mbus_r().set([this]() { return mbus_r() >> 4; });
- m_cpes[ 3 ]->mbus_r().set([this]() { return mbus_r() >> 6; });
+ m_cpes[ 0 ]->set_mbus_r_cb(NAME([this]() { return mbus_r(); }));
+ m_cpes[ 1 ]->set_mbus_r_cb(NAME([this]() { return mbus_r() >> 2; }));
+ m_cpes[ 2 ]->set_mbus_r_cb(NAME([this]() { return mbus_r() >> 4; }));
+ m_cpes[ 3 ]->set_mbus_r_cb(NAME([this]() { return mbus_r() >> 6; }));
// Connect I-bus
- m_cpes[ 0 ]->ibus_r().set([this]() { return ibus_r(); });
- m_cpes[ 1 ]->ibus_r().set([this]() { return ibus_r() >> 2; });
- m_cpes[ 2 ]->ibus_r().set([this]() { return ibus_r() >> 4; });
- m_cpes[ 3 ]->ibus_r().set([this]() { return ibus_r() >> 6; });
+ m_cpes[ 0 ]->set_ibus_r_cb(NAME([this]() { return ibus_r(); }));
+ m_cpes[ 1 ]->set_ibus_r_cb(NAME([this]() { return ibus_r() >> 2; }));
+ m_cpes[ 2 ]->set_ibus_r_cb(NAME([this]() { return ibus_r() >> 4; }));
+ m_cpes[ 3 ]->set_ibus_r_cb(NAME([this]() { return ibus_r() >> 6; }));
// Connect SX input
- m_mcu->sx_r().set([this]() { return m_microcode_addr & 0xf; });
+ m_mcu->set_sx_r_cb(NAME([this]() { return m_microcode_addr & 0xf; }));
// Connect PX input
- m_mcu->px_r().set(FUNC(isbc202_device::px_r));
+ m_mcu->set_px_r_cb(FUNC(isbc202_device::px_r));
// Drives
for (auto& finder : m_drives) {
@@ -558,7 +538,7 @@ void isbc202_device::execute_run()
do {
m_microcode_addr = m_mcu->addr_r();
debugger_instruction_hook(m_microcode_addr);
- m_code_word = m_cache->read_dword(m_microcode_addr);
+ m_code_word = m_cache.read_dword(m_microcode_addr);
// Unpack microcode into fields
// Bits Field
@@ -761,18 +741,11 @@ void isbc202_device::set_output()
// 1 Reset RDY latches (0)
// 0 -
if (BIT(m_mask , 5)) {
- if (m_cpu != nullptr) {
- // Release CPU from wait state
- LOG_BUS("CPU out of wait state\n");
- m_cpu->trigger(1);
- if (!m_cpu_rd) {
- m_cpu = nullptr;
- }
- // Ensure the MCU executes a few instruction before the CPU
- machine().scheduler().boost_interleave(attotime::from_usec(1) , attotime::from_usec(5));
- } else {
- LOG("No CPU to wake up?\n");
- }
+ // Release CPU from wait state
+ LOG_BUS("CPU out of wait state\n");
+ xack_w(0);
+ // Ensure the MCU executes a few instruction before the CPU
+ machine().scheduler().add_quantum(attotime::from_usec(1) , attotime::from_usec(5));
m_inputs[ IN_SEL_START ] = false;
}
if (BIT(m_mask , 4)) {
@@ -1028,14 +1001,10 @@ void isbc202_device::set_start(uint8_t off , bool read)
m_cmd = off;
m_inputs[ IN_SEL_START ] = true;
// Put CPU in wait state
- m_cpu->spin_until_trigger(1);
+ xack_w(1);
m_cpu_rd = read;
+ m_2nd_pass = true;
LOG_BUS("CPU in wait state (rd=%d)\n" , read);
- if (read) {
- // If CPU is suspended when reading, rewind PC so that the
- // "IN" instruction is repeated when CPU is released
- m_cpu->set_pc(m_cpu->pc() - 2);
- }
}
void isbc202_device::set_rd_wr(bool new_rd , bool new_wr)