mame/src/devices/machine/wd7600.cpp

593 lines
20 KiB
C++

// license:BSD-3-Clause
// copyright-holders:Barry Rodewald
/*
* Western Digital WD7600 PC system chipset
*
* WD76C10 - system control
* WD76C20 - FDC, RTC, Bus interface
* WD76C30 - 1 parallel and 2 serial ports
*
* Created on: 5/05/2014
*
* TODO: pretty much everything
*/
#include "emu.h"
#include "machine/wd7600.h"
#define VERBOSE 1
#include "logmacro.h"
DEFINE_DEVICE_TYPE(WD7600, wd7600_device, "wd7600", "Western Digital WD7600 chipset")
MACHINE_CONFIG_MEMBER( wd7600_device::device_add_mconfig )
MCFG_DEVICE_ADD("dma1", AM9517A, 0)
MCFG_I8237_OUT_HREQ_CB(DEVWRITELINE("dma2", am9517a_device, dreq0_w))
MCFG_I8237_OUT_EOP_CB(WRITELINE(wd7600_device, dma1_eop_w))
MCFG_I8237_IN_MEMR_CB(READ8(wd7600_device, dma_read_byte))
MCFG_I8237_OUT_MEMW_CB(WRITE8(wd7600_device, dma_write_byte))
MCFG_I8237_IN_IOR_0_CB(READ8(wd7600_device, dma1_ior0_r))
MCFG_I8237_IN_IOR_1_CB(READ8(wd7600_device, dma1_ior1_r))
MCFG_I8237_IN_IOR_2_CB(READ8(wd7600_device, dma1_ior2_r))
MCFG_I8237_IN_IOR_3_CB(READ8(wd7600_device, dma1_ior3_r))
MCFG_I8237_OUT_IOW_0_CB(WRITE8(wd7600_device, dma1_iow0_w))
MCFG_I8237_OUT_IOW_1_CB(WRITE8(wd7600_device, dma1_iow1_w))
MCFG_I8237_OUT_IOW_2_CB(WRITE8(wd7600_device, dma1_iow2_w))
MCFG_I8237_OUT_IOW_3_CB(WRITE8(wd7600_device, dma1_iow3_w))
MCFG_I8237_OUT_DACK_0_CB(WRITELINE(wd7600_device, dma1_dack0_w))
MCFG_I8237_OUT_DACK_1_CB(WRITELINE(wd7600_device, dma1_dack1_w))
MCFG_I8237_OUT_DACK_2_CB(WRITELINE(wd7600_device, dma1_dack2_w))
MCFG_I8237_OUT_DACK_3_CB(WRITELINE(wd7600_device, dma1_dack3_w))
MCFG_DEVICE_ADD("dma2", AM9517A, 0)
MCFG_I8237_OUT_HREQ_CB(WRITELINE(wd7600_device, dma2_hreq_w))
MCFG_I8237_IN_MEMR_CB(READ8(wd7600_device, dma_read_word))
MCFG_I8237_OUT_MEMW_CB(WRITE8(wd7600_device, dma_write_word))
MCFG_I8237_IN_IOR_1_CB(READ8(wd7600_device, dma2_ior1_r))
MCFG_I8237_IN_IOR_2_CB(READ8(wd7600_device, dma2_ior2_r))
MCFG_I8237_IN_IOR_3_CB(READ8(wd7600_device, dma2_ior3_r))
MCFG_I8237_OUT_IOW_1_CB(WRITE8(wd7600_device, dma2_iow1_w))
MCFG_I8237_OUT_IOW_2_CB(WRITE8(wd7600_device, dma2_iow2_w))
MCFG_I8237_OUT_IOW_3_CB(WRITE8(wd7600_device, dma2_iow3_w))
MCFG_I8237_OUT_DACK_0_CB(WRITELINE(wd7600_device, dma2_dack0_w))
MCFG_I8237_OUT_DACK_1_CB(WRITELINE(wd7600_device, dma2_dack1_w))
MCFG_I8237_OUT_DACK_2_CB(WRITELINE(wd7600_device, dma2_dack2_w))
MCFG_I8237_OUT_DACK_3_CB(WRITELINE(wd7600_device, dma2_dack3_w))
MCFG_DEVICE_ADD("intc1", PIC8259, 0)
MCFG_PIC8259_OUT_INT_CB(WRITELINE(wd7600_device, pic1_int_w))
MCFG_PIC8259_IN_SP_CB(VCC)
MCFG_PIC8259_CASCADE_ACK_CB(READ8(wd7600_device, pic1_slave_ack_r))
MCFG_DEVICE_ADD("intc2", PIC8259, 0)
MCFG_PIC8259_OUT_INT_CB(DEVWRITELINE("intc1", pic8259_device, ir2_w))
MCFG_PIC8259_IN_SP_CB(GND)
MCFG_DEVICE_ADD("ctc", PIT8254, 0)
MCFG_PIT8253_CLK0(XTAL_14_31818MHz / 12.0)
MCFG_PIT8253_OUT0_HANDLER(DEVWRITELINE("intc1", pic8259_device, ir0_w))
MCFG_PIT8253_CLK1(XTAL_14_31818MHz / 12.0)
MCFG_PIT8253_OUT1_HANDLER(WRITELINE(wd7600_device, ctc_out1_w))
MCFG_PIT8253_CLK2(XTAL_14_31818MHz / 12.0)
MCFG_PIT8253_OUT2_HANDLER(WRITELINE(wd7600_device, ctc_out2_w))
MCFG_DS12885_ADD("rtc")
MCFG_MC146818_IRQ_HANDLER(WRITELINE(wd7600_device, rtc_irq_w))
MCFG_MC146818_CENTURY_INDEX(0x32)
MACHINE_CONFIG_END
void wd7600_device::static_set_cputag(device_t &device, const char *tag)
{
wd7600_device &chip = downcast<wd7600_device &>(device);
chip.m_cputag = tag;
}
void wd7600_device::static_set_isatag(device_t &device, const char *tag)
{
wd7600_device &chip = downcast<wd7600_device &>(device);
chip.m_isatag = tag;
}
void wd7600_device::static_set_biostag(device_t &device, const char *tag)
{
wd7600_device &chip = downcast<wd7600_device &>(device);
chip.m_biostag = tag;
}
void wd7600_device::static_set_keybctag(device_t &device, const char *tag)
{
wd7600_device &chip = downcast<wd7600_device &>(device);
chip.m_keybctag = tag;
}
wd7600_device::wd7600_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, WD7600, tag, owner, clock),
m_read_ior(*this),
m_write_iow(*this),
m_write_tc(*this),
m_write_hold(*this),
m_write_nmi(*this),
m_write_intr(*this),
m_write_cpureset(*this),
m_write_a20m(*this),
m_write_spkr(*this),
m_dma1(*this, "dma1"),
m_dma2(*this, "dma2"),
m_pic1(*this, "intc1"),
m_pic2(*this, "intc2"),
m_ctc(*this, "ctc"),
m_rtc(*this, "rtc"),
m_portb(0x0f),
m_iochck(1),
m_nmi_mask(1),
m_alt_a20(0),
m_ext_gatea20(0),
m_kbrst(1),
m_refresh_toggle(0),
m_dma_eop(0),
m_dma_high_byte(0xff),
m_dma_channel(-1)
{}
void wd7600_device::device_start()
{
ram_device *ram_dev = machine().device<ram_device>(RAM_TAG);
// make sure the ram device is already running
if (!ram_dev->started())
throw device_missing_dependencies();
// resolve callbacks
m_read_ior.resolve_safe(0);
m_write_iow.resolve_safe();
m_write_tc.resolve_safe();
m_write_hold.resolve_safe();
m_write_nmi.resolve_safe();
m_write_intr.resolve_safe();
m_write_cpureset.resolve_safe();
m_write_a20m.resolve_safe();
m_write_spkr.resolve_safe();
device_t *cpu = machine().device(m_cputag);
m_space = &cpu->memory().space(AS_PROGRAM);
m_space_io = &cpu->memory().space(AS_IO);
m_isa = machine().root_device().memregion(m_isatag)->base();
m_bios = machine().root_device().memregion(m_biostag)->base();
m_keybc = downcast<at_keyboard_controller_device *>(machine().device(m_keybctag));
m_ram = ram_dev->pointer();
uint32_t ram_size = ram_dev->size();
// install base memory
m_space->install_ram(0x000000, 0x09ffff, m_ram);
m_space->install_ram(0x0d0000, 0x0effff, m_ram + 0xd0000);
// install extended memory
if (ram_size > 0x100000)
m_space->install_ram(0x100000, ram_size - 1, m_ram + 0x100000);
// install video BIOS (we should use the VGA BIOS at the beginning of the system BIOS ROM, but that gives a
// blank display (but still runs))
//m_space->install_rom(0x000c0000, 0x000cffff, m_bios);
m_space->install_rom(0x000c0000, 0x000cffff, m_isa);
// install BIOS ROM at cpu initial pc
m_space->install_rom(0x000f0000, 0x000fffff, m_bios + 0x10000);
if(m_space->addrmask() == 0xffffffff) // 32-bit address space only
m_space->install_rom(0xffff0000, 0xffffffff, m_bios + 0x10000);
else
m_space->install_rom(0x00ff0000, 0x00ffffff, m_bios + 0x10000);
// install i/o accesses
if (m_space_io->data_width() == 16)
{
// FIXME: are all these address ranges correct?
m_space_io->install_readwrite_handler(0x0000, 0x000f, read8_delegate(FUNC(am9517a_device::read), &(*m_dma1)), write8_delegate(FUNC(am9517a_device::write), &(*m_dma1)), 0xffff);
m_space_io->install_readwrite_handler(0x0020, 0x003f, read8_delegate(FUNC(pic8259_device::read), &(*m_pic1)), write8_delegate(FUNC(pic8259_device::write), &(*m_pic1)), 0xffff);
m_space_io->install_readwrite_handler(0x0040, 0x0043, read8_delegate(FUNC(pit8254_device::read), &(*m_ctc)), write8_delegate(FUNC(pit8254_device::write), &(*m_ctc)), 0xffff);
m_space_io->install_readwrite_handler(0x0060, 0x0061, read8_delegate(FUNC(wd7600_device::keyb_data_r), this), write8_delegate(FUNC(wd7600_device::keyb_data_w), this), 0x00ff);
m_space_io->install_readwrite_handler(0x0060, 0x0061, read8_delegate(FUNC(wd7600_device::portb_r), this), write8_delegate(FUNC(wd7600_device::portb_w), this), 0xff00);
m_space_io->install_readwrite_handler(0x0064, 0x0065, read8_delegate(FUNC(wd7600_device::keyb_status_r), this), write8_delegate(FUNC(wd7600_device::keyb_cmd_w), this), 0x00ff);
m_space_io->install_readwrite_handler(0x0070, 0x007f, read8_delegate(FUNC(mc146818_device::read), &(*m_rtc)), write8_delegate(FUNC(wd7600_device::rtc_w), this), 0xffff);
m_space_io->install_readwrite_handler(0x0080, 0x008f, read8_delegate(FUNC(wd7600_device::dma_page_r), this), write8_delegate(FUNC(wd7600_device::dma_page_w), this), 0xffff);
m_space_io->install_readwrite_handler(0x0092, 0x0093, read8_delegate(FUNC(wd7600_device::a20_reset_r), this), write8_delegate(FUNC(wd7600_device::a20_reset_w), this), 0x00ff);
m_space_io->install_readwrite_handler(0x00a0, 0x00a3, read8_delegate(FUNC(pic8259_device::read), &(*m_pic2)), write8_delegate(FUNC(pic8259_device::write), &(*m_pic2)), 0xffff);
m_space_io->install_readwrite_handler(0x00c0, 0x00df, read8_delegate(FUNC(am9517a_device::read), &(*m_dma2)), write8_delegate(FUNC(am9517a_device::write), &(*m_dma2)), 0x00ff);
m_space_io->install_readwrite_handler(0x2072, 0x2073, read16_delegate(FUNC(wd7600_device::refresh_r), this), write16_delegate(FUNC(wd7600_device::refresh_w), this));
m_space_io->install_readwrite_handler(0x2872, 0x2873, read16_delegate(FUNC(wd7600_device::chipsel_r), this), write16_delegate(FUNC(wd7600_device::chipsel_w), this));
m_space_io->install_readwrite_handler(0x3872, 0x3873, read16_delegate(FUNC(wd7600_device::mem_ctrl_r), this), write16_delegate(FUNC(wd7600_device::mem_ctrl_w), this));
m_space_io->install_readwrite_handler(0x4872, 0x4873, read16_delegate(FUNC(wd7600_device::bank_01_start_r), this), write16_delegate(FUNC(wd7600_device::bank_01_start_w), this));
m_space_io->install_readwrite_handler(0x5072, 0x5073, read16_delegate(FUNC(wd7600_device::bank_23_start_r), this), write16_delegate(FUNC(wd7600_device::bank_23_start_w), this));
m_space_io->install_readwrite_handler(0x5872, 0x5873, read16_delegate(FUNC(wd7600_device::split_addr_r), this), write16_delegate(FUNC(wd7600_device::split_addr_w), this));
m_space_io->install_readwrite_handler(0x9872, 0x9873, read16_delegate(FUNC(wd7600_device::diag_r), this), write16_delegate(FUNC(wd7600_device::diag_w), this));
}
else
{
assert(m_space_io->data_width() == 32);
m_space_io->install_readwrite_handler(0x0000, 0x000f, read8_delegate(FUNC(am9517a_device::read), &(*m_dma1)), write8_delegate(FUNC(am9517a_device::write), &(*m_dma1)), 0xffffffff);
m_space_io->install_readwrite_handler(0x0020, 0x003f, read8_delegate(FUNC(pic8259_device::read), &(*m_pic1)), write8_delegate(FUNC(pic8259_device::write), &(*m_pic1)), 0x0000ffff);
m_space_io->install_readwrite_handler(0x0040, 0x0043, read8_delegate(FUNC(pit8254_device::read), &(*m_ctc)), write8_delegate(FUNC(pit8254_device::write), &(*m_ctc)), 0xffffffff);
m_space_io->install_readwrite_handler(0x0060, 0x0063, read8_delegate(FUNC(wd7600_device::keyb_data_r), this), write8_delegate(FUNC(wd7600_device::keyb_data_w), this), 0x000000ff);
m_space_io->install_readwrite_handler(0x0060, 0x0063, read8_delegate(FUNC(wd7600_device::portb_r), this), write8_delegate(FUNC(wd7600_device::portb_w), this), 0x0000ff00);
m_space_io->install_readwrite_handler(0x0064, 0x0067, read8_delegate(FUNC(wd7600_device::keyb_status_r), this), write8_delegate(FUNC(wd7600_device::keyb_cmd_w), this), 0x000000ff);
m_space_io->install_readwrite_handler(0x0070, 0x007f, read8_delegate(FUNC(mc146818_device::read), &(*m_rtc)), write8_delegate(FUNC(wd7600_device::rtc_w), this), 0x0000ffff);
m_space_io->install_readwrite_handler(0x0080, 0x008f, read8_delegate(FUNC(wd7600_device::dma_page_r), this), write8_delegate(FUNC(wd7600_device::dma_page_w), this), 0xffffffff);
m_space_io->install_readwrite_handler(0x0090, 0x0093, read8_delegate(FUNC(wd7600_device::a20_reset_r), this), write8_delegate(FUNC(wd7600_device::a20_reset_w), this), 0x00ff0000);
m_space_io->install_readwrite_handler(0x00a0, 0x00a3, read8_delegate(FUNC(pic8259_device::read), &(*m_pic2)), write8_delegate(FUNC(pic8259_device::write), &(*m_pic2)), 0x0000ffff);
m_space_io->install_readwrite_handler(0x00c0, 0x00df, read8_delegate(FUNC(am9517a_device::read), &(*m_dma2)), write8_delegate(FUNC(am9517a_device::write), &(*m_dma2)), 0x00ff00ff);
m_space_io->install_readwrite_handler(0x2070, 0x2073, read16_delegate(FUNC(wd7600_device::refresh_r), this), write16_delegate(FUNC(wd7600_device::refresh_w), this), 0xffff0000);
m_space_io->install_readwrite_handler(0x2870, 0x2873, read16_delegate(FUNC(wd7600_device::chipsel_r), this), write16_delegate(FUNC(wd7600_device::chipsel_w), this), 0xffff0000);
m_space_io->install_readwrite_handler(0x3870, 0x3873, read16_delegate(FUNC(wd7600_device::mem_ctrl_r), this), write16_delegate(FUNC(wd7600_device::mem_ctrl_w), this), 0xffff0000);
m_space_io->install_readwrite_handler(0x4870, 0x4873, read16_delegate(FUNC(wd7600_device::bank_01_start_r), this), write16_delegate(FUNC(wd7600_device::bank_01_start_w), this), 0xffff0000);
m_space_io->install_readwrite_handler(0x5070, 0x5073, read16_delegate(FUNC(wd7600_device::bank_23_start_r), this), write16_delegate(FUNC(wd7600_device::bank_23_start_w), this), 0xffff0000);
m_space_io->install_readwrite_handler(0x5870, 0x5873, read16_delegate(FUNC(wd7600_device::split_addr_r), this), write16_delegate(FUNC(wd7600_device::split_addr_w), this), 0xffff0000);
m_space_io->install_readwrite_handler(0x9870, 0x9873, read16_delegate(FUNC(wd7600_device::diag_r), this), write16_delegate(FUNC(wd7600_device::diag_w), this), 0xffff0000);
}
}
void wd7600_device::device_reset()
{
m_split_start = 0;
m_chip_sel = 0;
m_refresh_ctrl = 0;
m_memory_ctrl = 0;
m_diagnostic = 0xe080;
for(auto & elem : m_bank_start)
elem = 0;
// initialize dma controller clocks
m_dma1->set_unscaled_clock(clock());
m_dma2->set_unscaled_clock(clock());
}
WRITE_LINE_MEMBER( wd7600_device::iochck_w )
{
if (BIT(m_portb, 3) == 0)
{
if (m_iochck && state == 0)
{
// set channel check latch
m_portb |= 1 << 6;
nmi();
}
m_iochck = state;
}
}
void wd7600_device::nmi()
{
if (m_nmi_mask & BIT(m_portb, 6))
{
m_write_nmi(1);
m_write_nmi(0);
}
}
void wd7600_device::a20m()
{
// TODO: ignore keyboard A20 signal if set in Diagnostic register (0x9872)
m_write_a20m(m_alt_a20 | m_ext_gatea20);
}
void wd7600_device::keyboard_gatea20(int state)
{
m_ext_gatea20 = state;
a20m();
}
WRITE8_MEMBER( wd7600_device::rtc_w )
{
if (offset == 0)
{
m_nmi_mask = !BIT(data, 7);
data &= 0x7f;
}
m_rtc->write(space, offset, data);
}
WRITE_LINE_MEMBER( wd7600_device::rtc_irq_w )
{
m_pic2->ir0_w(state ? 0 : 1); // inverted?
}
READ8_MEMBER( wd7600_device::pic1_slave_ack_r )
{
if (offset == 2) // IRQ 2
return m_pic2->acknowledge();
return 0x00;
}
// Timer outputs
WRITE_LINE_MEMBER( wd7600_device::ctc_out1_w )
{
m_refresh_toggle ^= state;
m_portb = (m_portb & 0xef) | (m_refresh_toggle << 4);
}
WRITE_LINE_MEMBER( wd7600_device::ctc_out2_w )
{
m_write_spkr(!(state));
m_portb = (m_portb & 0xdf) | (state << 5);
}
// Keyboard
WRITE8_MEMBER( wd7600_device::keyb_data_w )
{
// LOG("WD7600: keyboard data write %02x\n", data);
m_keybc->data_w(space,0,data);
}
READ8_MEMBER( wd7600_device::keyb_data_r )
{
uint8_t ret = m_keybc->data_r(space,0);
// LOG("WD7600: keyboard data read %02x\n", ret);
return ret;
}
WRITE8_MEMBER( wd7600_device::keyb_cmd_w )
{
// LOG("WD7600: keyboard command %02x\n", data);
m_keybc->command_w(space,0,data);
}
READ8_MEMBER( wd7600_device::keyb_status_r )
{
return m_keybc->status_r(space,0);
}
READ8_MEMBER( wd7600_device::portb_r )
{
return m_portb;
}
WRITE8_MEMBER( wd7600_device::portb_w )
{
m_portb = (m_portb & 0xf0) | (data & 0x0f);
// bit 5 forced to 1 if timer disabled
if (!BIT(m_portb, 0))
m_portb |= 1 << 5;
m_ctc->write_gate2(BIT(m_portb, 0));
m_write_spkr(!BIT(m_portb, 1));
// clear channel check latch?
if (BIT(m_portb, 3))
m_portb &= 0xbf;
}
// DMA controllers
offs_t wd7600_device::page_offset()
{
switch (m_dma_channel)
{
case 0: return (offs_t) m_dma_page[0x07] << 16;
case 1: return (offs_t) m_dma_page[0x03] << 16;
case 2: return (offs_t) m_dma_page[0x01] << 16;
case 3: return (offs_t) m_dma_page[0x02] << 16;
case 5: return (offs_t) m_dma_page[0x0b] << 16;
case 6: return (offs_t) m_dma_page[0x09] << 16;
case 7: return (offs_t) m_dma_page[0x0a] << 16;
}
// should never get here
return 0xff0000;
}
READ8_MEMBER( wd7600_device::dma_read_byte )
{
if (m_dma_channel == -1)
return 0xff;
return m_space->read_byte(page_offset() + offset);
}
WRITE8_MEMBER( wd7600_device::dma_write_byte )
{
if (m_dma_channel == -1)
return;
m_space->write_byte(page_offset() + offset, data);
}
READ8_MEMBER( wd7600_device::dma_read_word )
{
if (m_dma_channel == -1)
return 0xff;
uint16_t result = m_space->read_word((page_offset() & 0xfe0000) | (offset << 1));
m_dma_high_byte = result >> 8;
return result;
}
WRITE8_MEMBER( wd7600_device::dma_write_word )
{
if (m_dma_channel == -1)
return;
m_space->write_word((page_offset() & 0xfe0000) | (offset << 1), (m_dma_high_byte << 8) | data);
}
WRITE_LINE_MEMBER( wd7600_device::dma2_dack0_w )
{
m_dma1->hack_w(state ? 0 : 1); // inverted?
}
WRITE_LINE_MEMBER( wd7600_device::dma1_eop_w )
{
m_dma_eop = state;
if (m_dma_channel != -1)
m_write_tc(m_dma_channel, state, 0xff);
}
void wd7600_device::set_dma_channel(int channel, bool state)
{
if (!state)
{
m_dma_channel = channel;
if (m_dma_eop)
m_write_tc(channel, 1, 0xff);
}
else
{
if (m_dma_channel == channel)
{
m_dma_channel = -1;
if (m_dma_eop)
m_write_tc(channel, 0, 0xff);
}
}
}
WRITE_LINE_MEMBER( wd7600_device::gatea20_w )
{
keyboard_gatea20(state);
}
WRITE_LINE_MEMBER( wd7600_device::kbrst_w )
{
// convert to active low signal (gets inverted in at_keybc.c)
state = (state == ASSERT_LINE ? 0 : 1);
// detect transition
if (m_kbrst == 1 && state == 0)
{
m_write_cpureset(1);
m_write_cpureset(0);
}
m_kbrst = state;
}
WRITE8_MEMBER( wd7600_device::a20_reset_w )
{
m_alt_a20 = BIT(data,1);
a20m();
// TODO: proper timing. Reset occurs 128 cycles after changing to a 1, and lasts for 16 cycles
if(BIT(data,0))
{
m_write_cpureset(1);
m_write_cpureset(0);
LOG("WD7600: System reset\n");
}
}
READ8_MEMBER( wd7600_device::a20_reset_r )
{
uint8_t ret = 0;
if(m_alt_a20)
ret |= 0x02;
return ret;
}
// port 0x2072 - Refresh Control, and serial/parallel port address select
READ16_MEMBER(wd7600_device::refresh_r)
{
return m_refresh_ctrl;
}
WRITE16_MEMBER(wd7600_device::refresh_w)
{
// TODO: select serial/parallel I/O port location
m_refresh_ctrl = data;
LOG("WD7600: Refresh Control write %04x\n", data);
}
// port 0x2872 - chip select
READ16_MEMBER(wd7600_device::chipsel_r)
{
return m_chip_sel;
}
WRITE16_MEMBER(wd7600_device::chipsel_w)
{
m_chip_sel = data;
LOG("WD7600: Chip Select write %04x\n", data);
}
// port 0x3872 - Memory Control
READ16_MEMBER(wd7600_device::mem_ctrl_r)
{
return m_memory_ctrl;
}
WRITE16_MEMBER(wd7600_device::mem_ctrl_w)
{
m_memory_ctrl = data;
LOG("WD7600: Memory Control write %04x\n", data);
}
// port 0x4872 - Bank 0 and 1 start address
READ16_MEMBER(wd7600_device::bank_01_start_r)
{
return (m_bank_start[1] << 8) | m_bank_start[0];
}
WRITE16_MEMBER(wd7600_device::bank_01_start_w)
{
if(ACCESSING_BITS_0_7)
{
m_bank_start[0] = data & 0xff;
LOG("WD7600: Bank 0 start address %08x\n", m_bank_start[0] << 16);
}
if(ACCESSING_BITS_8_15)
{
m_bank_start[1] = (data & 0xff00) >> 8;
LOG("WD7600: Bank 1 start address %08x\n", m_bank_start[1] << 16);
}
}
// port 0x5072 - Bank 2 and 3 start address
READ16_MEMBER(wd7600_device::bank_23_start_r)
{
return (m_bank_start[3] << 8) | m_bank_start[2];
}
WRITE16_MEMBER(wd7600_device::bank_23_start_w)
{
if(ACCESSING_BITS_0_7)
{
m_bank_start[2] = data & 0xff;
LOG("WD7600: Bank 2 start address %08x\n", m_bank_start[2] << 16);
}
if(ACCESSING_BITS_8_15)
{
m_bank_start[3] = (data & 0xff00) >> 8;
LOG("WD7600: Bank 3 start address %08x\n", m_bank_start[3] << 16);
}
}
// port 0x5872 - split starting address (used for BIOS shadowing)
READ16_MEMBER(wd7600_device::split_addr_r)
{
return m_split_start;
}
WRITE16_MEMBER(wd7600_device::split_addr_w)
{
m_split_start = data;
LOG("WD7600: Split start address write %04x\n", data);
}
// port 0x9872 - Diagnostic
READ16_MEMBER(wd7600_device::diag_r)
{
return m_diagnostic | 0xe080;
}
WRITE16_MEMBER(wd7600_device::diag_w)
{
m_diagnostic = data;
LOG("WD7600: Diagnostic write %04x\n", data);
}