mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
cs4031.c: emulated the chipsets ability to intercept gate a20 and keyboard reset commands
This commit is contained in:
parent
600a425123
commit
9aaabd58ea
@ -17,9 +17,6 @@
|
||||
- MC14818 RTC
|
||||
|
||||
TODO:
|
||||
- The chipset has the ability to intercept the GATEA20 and
|
||||
RESET commands sent to the 8042 keyboard controller,
|
||||
this is not emulated yet
|
||||
- No emulation of memory parity checks
|
||||
- Move IPC core to its own file so it can be shared with
|
||||
other chipsets
|
||||
@ -38,7 +35,7 @@
|
||||
#define LOG_REGISTER 1
|
||||
#define LOG_MEMORY 1
|
||||
#define LOG_IO 1
|
||||
#define LOG_KEYBOARD 0
|
||||
#define LOG_KEYBOARD 0
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
@ -215,6 +212,9 @@ cs4031_device::cs4031_device(const machine_config &mconfig, const char *tag, dev
|
||||
m_kbrst(1),
|
||||
m_ext_gatea20(0),
|
||||
m_fast_gatea20(0),
|
||||
m_emu_gatea20(0),
|
||||
m_keybc_d1_written(false),
|
||||
m_keybc_data_blocked(false),
|
||||
m_address(0),
|
||||
m_address_valid(false)
|
||||
{
|
||||
@ -711,9 +711,35 @@ void cs4031_device::update_write_regions()
|
||||
// KEYBOARD / 8042
|
||||
//**************************************************************************
|
||||
|
||||
void cs4031_device::a20m()
|
||||
void cs4031_device::emulated_kbreset(int state)
|
||||
{
|
||||
m_write_a20m(m_fast_gatea20 | m_ext_gatea20);
|
||||
if (BIT(m_registers[SOFT_RESET_AND_GATEA20], 4))
|
||||
{
|
||||
// kbreset (input) is active low
|
||||
// cpureset (output) is active high
|
||||
m_write_cpureset(!state);
|
||||
}
|
||||
}
|
||||
|
||||
void cs4031_device::emulated_gatea20(int state)
|
||||
{
|
||||
if (BIT(m_registers[SOFT_RESET_AND_GATEA20], 5))
|
||||
{
|
||||
m_emu_gatea20 = state;
|
||||
a20m();
|
||||
}
|
||||
}
|
||||
|
||||
void cs4031_device::fast_gatea20(int state)
|
||||
{
|
||||
m_fast_gatea20 = state;
|
||||
a20m();
|
||||
}
|
||||
|
||||
void cs4031_device::keyboard_gatea20(int state)
|
||||
{
|
||||
m_ext_gatea20 = state;
|
||||
a20m();
|
||||
}
|
||||
|
||||
READ8_MEMBER( cs4031_device::keyb_status_r )
|
||||
@ -724,12 +750,83 @@ READ8_MEMBER( cs4031_device::keyb_status_r )
|
||||
return m_keybc->status_r(space, 0);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( cs4031_device::keyb_command_blocked_w )
|
||||
{
|
||||
// command is optionally blocked
|
||||
if (!BIT(m_registers[SOFT_RESET_AND_GATEA20], 7))
|
||||
m_keybc->command_w(space, 0, data);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( cs4031_device::keyb_command_w )
|
||||
{
|
||||
if (LOG_KEYBOARD)
|
||||
logerror("cs4031_device::keyb_command_w: %02x\n", data);
|
||||
|
||||
m_keybc->command_w(space, 0, data);
|
||||
m_keybc_d1_written = false;
|
||||
|
||||
switch (data)
|
||||
{
|
||||
// self-test
|
||||
case 0xaa:
|
||||
emulated_kbreset(1);
|
||||
emulated_gatea20(1);
|
||||
|
||||
// self-test is never blocked
|
||||
m_keybc->command_w(space, 0, data);
|
||||
break;
|
||||
|
||||
case 0xd1:
|
||||
m_keybc_d1_written = true;
|
||||
keyb_command_blocked_w(space, 0, data);
|
||||
break;
|
||||
|
||||
case 0xf0:
|
||||
case 0xf1:
|
||||
case 0xf2:
|
||||
case 0xf4:
|
||||
case 0xf5:
|
||||
case 0xf6:
|
||||
case 0xf8:
|
||||
case 0xf9:
|
||||
case 0xfa:
|
||||
case 0xfc:
|
||||
case 0xfd:
|
||||
case 0xfe:
|
||||
// toggle keyboard reset?
|
||||
if (!BIT(data, 0))
|
||||
{
|
||||
emulated_kbreset(0);
|
||||
emulated_kbreset(1);
|
||||
}
|
||||
|
||||
// toggle gatea20?
|
||||
if (!BIT(data, 1))
|
||||
{
|
||||
emulated_gatea20(0);
|
||||
emulated_gatea20(1);
|
||||
}
|
||||
|
||||
keyb_command_blocked_w(space, 0, data);
|
||||
|
||||
break;
|
||||
|
||||
case 0xff:
|
||||
// last data write was blocked?
|
||||
if (m_keybc_data_blocked)
|
||||
{
|
||||
m_keybc_data_blocked = false;
|
||||
keyb_command_blocked_w(space, 0, data);
|
||||
}
|
||||
else
|
||||
m_keybc->command_w(space, 0, data);
|
||||
|
||||
break;
|
||||
|
||||
// everything else goes directly to the keyboard controller
|
||||
default:
|
||||
m_keybc->command_w(space, 0, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER( cs4031_device::keyb_data_r )
|
||||
@ -745,7 +842,18 @@ WRITE8_MEMBER( cs4031_device::keyb_data_w )
|
||||
if (LOG_KEYBOARD)
|
||||
logerror("cs4031_device::keyb_data_w: %02x\n", data);
|
||||
|
||||
m_keybc->data_w(space, 0, data);
|
||||
// data is blocked only for d1 command
|
||||
if (BIT(m_registers[SOFT_RESET_AND_GATEA20], 7) && m_keybc_d1_written)
|
||||
{
|
||||
m_keybc_data_blocked = true;
|
||||
emulated_kbreset(BIT(data, 0));
|
||||
emulated_gatea20(BIT(data, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_keybc_data_blocked = false;
|
||||
m_keybc->data_w(space, 0, data);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( cs4031_device::gatea20_w )
|
||||
@ -753,11 +861,7 @@ WRITE_LINE_MEMBER( cs4031_device::gatea20_w )
|
||||
if (LOG_KEYBOARD)
|
||||
logerror("cs4031_device::gatea20_w: %u\n", state);
|
||||
|
||||
if (m_ext_gatea20 != state)
|
||||
{
|
||||
m_ext_gatea20 = state;
|
||||
a20m();
|
||||
}
|
||||
keyboard_gatea20(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( cs4031_device::kbrst_w )
|
||||
@ -765,9 +869,10 @@ WRITE_LINE_MEMBER( cs4031_device::kbrst_w )
|
||||
if (LOG_KEYBOARD)
|
||||
logerror("cs4031_device::kbrst_w: %u\n", state);
|
||||
|
||||
// active low signal
|
||||
// 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);
|
||||
@ -789,8 +894,7 @@ WRITE8_MEMBER( cs4031_device::sysctrl_w )
|
||||
if (LOG_IO)
|
||||
logerror("cs4031_device::sysctrl_w: %u\n", data);
|
||||
|
||||
m_fast_gatea20 = BIT(data, 1);
|
||||
a20m();
|
||||
fast_gatea20(BIT(data, 1));
|
||||
|
||||
if (m_cpureset == 0 && BIT(data, 0))
|
||||
{
|
||||
|
@ -148,6 +148,7 @@ public:
|
||||
DECLARE_WRITE8_MEMBER( keyb_data_w );
|
||||
DECLARE_READ8_MEMBER( keyb_status_r );
|
||||
DECLARE_WRITE8_MEMBER( keyb_command_w );
|
||||
DECLARE_WRITE8_MEMBER( keyb_command_blocked_w );
|
||||
|
||||
// input lines
|
||||
DECLARE_WRITE_LINE_MEMBER( irq01_w ) { m_intc1->ir1_w(state); }
|
||||
@ -203,8 +204,16 @@ private:
|
||||
offs_t page_offset();
|
||||
void set_dma_channel(int channel, bool state);
|
||||
void update_dma_clock();
|
||||
|
||||
void nmi();
|
||||
void a20m();
|
||||
|
||||
// gate a20, various sources are ored
|
||||
void a20m() { m_write_a20m(m_fast_gatea20 | m_ext_gatea20 | m_emu_gatea20); }
|
||||
|
||||
void emulated_kbreset(int state);
|
||||
void emulated_gatea20(int state);
|
||||
void fast_gatea20(int state);
|
||||
void keyboard_gatea20(int state);
|
||||
|
||||
void update_read_region(int index, const char *region, offs_t start, offs_t end);
|
||||
void update_write_region(int index, const char *region, offs_t start, offs_t end);
|
||||
@ -247,6 +256,9 @@ private:
|
||||
int m_kbrst;
|
||||
int m_ext_gatea20;
|
||||
int m_fast_gatea20;
|
||||
int m_emu_gatea20;
|
||||
bool m_keybc_d1_written;
|
||||
bool m_keybc_data_blocked;
|
||||
|
||||
// chipset configuration
|
||||
static const char* m_register_names[];
|
||||
|
Loading…
Reference in New Issue
Block a user