Skip to content

h89bus.cpp: setup io addresses instead of run-time decoding of PROM #13533

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 103 additions & 87 deletions src/devices/bus/heathzenith/h89/cdr_fdc_880h.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
#define LOG_ERR (1U << 5) // log errors
#define LOG_WAIT (1U << 6) // wait mode
#define LOG_DATA (1U << 7) // data read/writes
#define LOG_SETUP (1U << 8) // setup

#define VERBOSE (0xff)
#define VERBOSE (0)

#include "logmacro.h"

Expand All @@ -34,6 +35,7 @@
#define LOGERR(...) LOGMASKED(LOG_ERR, __VA_ARGS__)
#define LOGWAIT(...) LOGMASKED(LOG_WAIT, __VA_ARGS__)
#define LOGDATA(...) LOGMASKED(LOG_DATA, __VA_ARGS__)
#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__)

#ifdef _MSC_VER
#define FUNCNAME __func__
Expand All @@ -49,9 +51,6 @@ class cdr_fdc_880h_device : public device_t, public device_h89bus_right_card_int
public:
cdr_fdc_880h_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);

virtual void write(u8 select_lines, u8 offset, u8 data) override;
virtual u8 read(u8 select_lines, u8 offset) override;

// The controller has two 16L8 PALs which are not dumped (z15 and z20 from schematics).
static constexpr feature_type unemulated_features() { return feature::DISK; }

Expand All @@ -61,6 +60,9 @@ class cdr_fdc_880h_device : public device_t, public device_h89bus_right_card_int
virtual void device_reset() override ATTR_COLD;
virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;

void write(offs_t offset, u8 data);
u8 read(offs_t offset);

void cmd_w(u8 val);
void data_w(u8 val);
u8 data_r();
Expand All @@ -83,23 +85,24 @@ class cdr_fdc_880h_device : public device_t, public device_h89bus_right_card_int
required_device<fd1797_device> m_fdc;
required_device_array<floppy_connector, 4> m_floppies;

bool m_irq_allowed;
bool m_installed;
bool m_irq_allowed;

bool m_irq;
bool m_drq;
bool m_irq;
bool m_drq;

bool m_double_density;
bool m_five_in_drive;
bool m_mode_operate;
s8 m_drive;
bool m_double_density;
bool m_five_in_drive;
bool m_mode_operate;
s8 m_drive;
};


cdr_fdc_880h_device::cdr_fdc_880h_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock):
device_t(mconfig, H89BUS_CDR_FDC_880H, tag, owner, 0),
device_h89bus_right_card_interface(mconfig, *this),
m_fdc(*this, "cdr_fdc_880h"),
m_floppies(*this, "cdr_fdc_880h:%u", 0U)
cdr_fdc_880h_device::cdr_fdc_880h_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, H89BUS_CDR_FDC_880H, tag, owner, 0)
, device_h89bus_right_card_interface(mconfig, *this)
, m_fdc(*this, "cdr_fdc_880h")
, m_floppies(*this, "cdr_fdc_880h:%u", 0U)
{
}

Expand Down Expand Up @@ -174,63 +177,58 @@ void cdr_fdc_880h_device::data_w(u8 val)
m_fdc->data_w(val);
}

void cdr_fdc_880h_device::write(u8 select_lines, u8 offset, u8 data)
void cdr_fdc_880h_device::write(offs_t offset, u8 data)
{
if (!(select_lines & h89bus_device::H89_CASS))
{
return;
}

LOGREG("%s: reg: %d val: 0x%02x\n", FUNCNAME, offset, data);

switch (offset)
{
case 0:
case 1:
case 2:
// read not supported on these addresses
LOGERR("%s: Unexpected port read reg: %d\n", FUNCNAME, offset);
break;
case 3: // Select Port
cmd_w(data);
break;
case 4: // Command Port
m_fdc->cmd_w(data);
break;
case 5: // Track Port
m_fdc->track_w(data);
break;
case 6: // Sector Port
m_fdc->sector_w(data);
break;
case 7: // Data Port
data_w(data);
break;
case 0:
case 1:
case 2:
// read not supported on these addresses
LOGERR("%s: Unexpected port read reg: %d\n", FUNCNAME, offset);
break;
case 3: // Select Port
cmd_w(data);
break;
case 4: // Command Port
m_fdc->cmd_w(data);
break;
case 5: // Track Port
m_fdc->track_w(data);
break;
case 6: // Sector Port
m_fdc->sector_w(data);
break;
case 7: // Data Port
data_w(data);
break;
}
}

u8 cdr_fdc_880h_device::status_r()
{
u8 data = 0;

switch(m_drive)
switch (m_drive)
{
case 0:
data |= 0x0e;
break;
case 1:
data |= 0x0d;
break;
case 2:
data |= 0x0b;
break;
case 3:
data |= 0x07;
break;
case -1:
default:
data |= 0x0f;
break;
case 0:
data |= 0x0e;
break;
case 1:
data |= 0x0d;
break;
case 2:
data |= 0x0b;
break;
case 3:
data |= 0x07;
break;
case -1:
default:
data |= 0x0f;
break;
}
data |= m_mode_operate ? 0x10 : 0;
data |= m_five_in_drive ? 0 : 0x20;
Expand Down Expand Up @@ -263,38 +261,33 @@ u8 cdr_fdc_880h_device::data_r()
return data;
}

u8 cdr_fdc_880h_device::read(u8 select_lines, u8 offset)
u8 cdr_fdc_880h_device::read(offs_t offset)
{
if (!(select_lines & h89bus_device::H89_CASS))
{
return 0;
}

u8 value = 0;

switch (offset)
{
case 0:
case 1:
case 2:
// read not supported on these addresses
LOGERR("%s: Unexpected port read reg: %d\n", FUNCNAME, offset);
break;
case 3: // ??
value = status_r();
break;
case 4: // Drive Status Port
value = m_fdc->status_r();
break;
case 5: // Track Port
value = m_fdc->track_r();
break;
case 6: // Sector Port
value = m_fdc->sector_r();
break;
case 7: // Data Port
value = data_r();
break;
case 0:
case 1:
case 2:
// read not supported on these addresses
LOGERR("%s: Unexpected port read reg: %d\n", FUNCNAME, offset);
break;
case 3: // ??
value = status_r();
break;
case 4: // Drive Status Port
value = m_fdc->status_r();
break;
case 5: // Track Port
value = m_fdc->track_r();
break;
case 6: // Sector Port
value = m_fdc->sector_r();
break;
case 7: // Data Port
value = data_r();
break;
}

LOGREG("%s: reg: %d val: 0x%02x\n", FUNCNAME, offset, value);
Expand All @@ -304,13 +297,36 @@ u8 cdr_fdc_880h_device::read(u8 select_lines, u8 offset)

void cdr_fdc_880h_device::device_start()
{
m_installed = false;

save_item(NAME(m_installed));
save_item(NAME(m_irq_allowed));
save_item(NAME(m_irq));
save_item(NAME(m_drq));
}

void cdr_fdc_880h_device::device_reset()
{
if (!m_installed)
{
h89bus::addr_ranges addr_ranges = h89bus().get_address_ranges(h89bus::IO_CASS);

if (addr_ranges.size() == 1)
{
h89bus::addr_range range = addr_ranges.front();

h89bus().install_io_device(range.first, range.second,
read8sm_delegate(*this, FUNC(cdr_fdc_880h_device::read)),
write8sm_delegate(*this, FUNC(cdr_fdc_880h_device::write)));
}
else
{
LOGSETUP("%s: No address specified\n", FUNCNAME);
}

m_installed = true;
}

m_irq_allowed = false;
m_irq = false;

Expand Down
Loading
Loading