mirror of
https://github.com/holub/mame
synced 2025-07-01 16:19:38 +03:00
i8279: Simplify handler signatures; add save state; disable read side effects (nw)
This commit is contained in:
parent
d192fa113d
commit
21e19cecd2
@ -17,7 +17,6 @@ ToDo:
|
|||||||
- Interrupts
|
- Interrupts
|
||||||
- BD pin
|
- BD pin
|
||||||
- Sensor ram stuff
|
- Sensor ram stuff
|
||||||
- save state
|
|
||||||
|
|
||||||
|
|
||||||
What has been done:
|
What has been done:
|
||||||
@ -91,7 +90,7 @@ DEFINE_DEVICE_TYPE(I8279, i8279_device, "i8279", "Intel 8279 KDC")
|
|||||||
// i8279_device - constructor
|
// i8279_device - constructor
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
i8279_device::i8279_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
i8279_device::i8279_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||||
: device_t(mconfig, I8279, tag, owner, clock),
|
: device_t(mconfig, I8279, tag, owner, clock),
|
||||||
m_out_irq_cb(*this),
|
m_out_irq_cb(*this),
|
||||||
m_out_sl_cb(*this),
|
m_out_sl_cb(*this),
|
||||||
@ -117,8 +116,23 @@ void i8279_device::device_start()
|
|||||||
m_in_rl_cb.resolve();
|
m_in_rl_cb.resolve();
|
||||||
m_in_shift_cb.resolve();
|
m_in_shift_cb.resolve();
|
||||||
m_in_ctrl_cb.resolve();
|
m_in_ctrl_cb.resolve();
|
||||||
m_clock = clock();
|
m_scanclock = clock();
|
||||||
m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(i8279_device::timerproc_callback), this));
|
m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(i8279_device::timerproc_callback), this));
|
||||||
|
|
||||||
|
// save state
|
||||||
|
save_item(NAME(m_d_ram));
|
||||||
|
save_item(NAME(m_d_ram_ptr));
|
||||||
|
save_item(NAME(m_s_ram));
|
||||||
|
save_item(NAME(m_s_ram_ptr));
|
||||||
|
save_item(NAME(m_fifo));
|
||||||
|
save_item(NAME(m_cmd));
|
||||||
|
save_item(NAME(m_status));
|
||||||
|
save_item(NAME(m_scanclock));
|
||||||
|
save_item(NAME(m_scanner));
|
||||||
|
save_item(NAME(m_autoinc));
|
||||||
|
save_item(NAME(m_read_flag));
|
||||||
|
save_item(NAME(m_ctrl_key));
|
||||||
|
save_item(NAME(m_key_down));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -128,13 +142,11 @@ void i8279_device::device_start()
|
|||||||
|
|
||||||
void i8279_device::device_reset()
|
void i8279_device::device_reset()
|
||||||
{
|
{
|
||||||
uint8_t i;
|
|
||||||
|
|
||||||
// startup values are unknown: setting to 0
|
// startup values are unknown: setting to 0
|
||||||
for (i = 2; i < 8; i++) m_cmd[i] = 0;
|
for (u8 i = 2; i < 8; i++) m_cmd[i] = 0;
|
||||||
for (i = 0; i < 8; i++) m_fifo[i] = 0;
|
for (u8 i = 0; i < 8; i++) m_fifo[i] = 0;
|
||||||
for (i = 0; i < 8; i++) m_s_ram[i] = 0;
|
for (u8 i = 0; i < 8; i++) m_s_ram[i] = 0;
|
||||||
for (i = 0; i < 16; i++) m_d_ram[i] = 0;
|
for (u8 i = 0; i < 16; i++) m_d_ram[i] = 0;
|
||||||
m_status = 0;
|
m_status = 0;
|
||||||
m_autoinc = true;
|
m_autoinc = true;
|
||||||
m_d_ram_ptr = 0;
|
m_d_ram_ptr = 0;
|
||||||
@ -159,17 +171,17 @@ void i8279_device::timer_adjust()
|
|||||||
// If this is too long, the sensor mode doesn't work correctly.
|
// If this is too long, the sensor mode doesn't work correctly.
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
uint8_t divider = (m_cmd[1]) ? m_cmd[1] : 1;
|
u8 divider = (m_cmd[1]) ? m_cmd[1] : 1;
|
||||||
uint32_t new_clock = clock() / divider;
|
u32 new_clock = clock() / divider;
|
||||||
#else
|
#else
|
||||||
uint32_t new_clock = 2000;
|
u32 new_clock = 2000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_clock != new_clock)
|
if (m_scanclock != new_clock)
|
||||||
{
|
{
|
||||||
m_timer->adjust(attotime::from_hz(new_clock), 0, attotime::from_hz(new_clock));
|
m_timer->adjust(attotime::from_hz(new_clock), 0, attotime::from_hz(new_clock));
|
||||||
|
|
||||||
m_clock = new_clock;
|
m_scanclock = new_clock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,8 +189,8 @@ void i8279_device::timer_adjust()
|
|||||||
void i8279_device::clear_display()
|
void i8279_device::clear_display()
|
||||||
{
|
{
|
||||||
// clear all digits
|
// clear all digits
|
||||||
uint8_t i,patterns[4] = { 0, 0, 0x20, 0xff };
|
u8 i,patterns[4] = { 0, 0, 0x20, 0xff };
|
||||||
uint8_t data = patterns[(m_cmd[6] & 12) >> 2];
|
u8 data = patterns[(m_cmd[6] & 12) >> 2];
|
||||||
|
|
||||||
// The CD high bit (also done by CA)
|
// The CD high bit (also done by CA)
|
||||||
if (m_cmd[6] & 0x11)
|
if (m_cmd[6] & 0x11)
|
||||||
@ -205,9 +217,9 @@ void i8279_device::set_irq(bool state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void i8279_device::new_key(uint8_t data, bool skey, bool ckey)
|
void i8279_device::new_key(u8 data, bool skey, bool ckey)
|
||||||
{
|
{
|
||||||
uint8_t i, rl, sl;
|
u8 i, rl, sl;
|
||||||
for (i = 0; BIT(data, i); i++) {};
|
for (i = 0; BIT(data, i); i++) {};
|
||||||
rl = i;
|
rl = i;
|
||||||
if (BIT(m_cmd[0], 0))
|
if (BIT(m_cmd[0], 0))
|
||||||
@ -222,7 +234,7 @@ void i8279_device::new_key(uint8_t data, bool skey, bool ckey)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void i8279_device::new_fifo(uint8_t data)
|
void i8279_device::new_fifo(u8 data)
|
||||||
{
|
{
|
||||||
// see if already overrun
|
// see if already overrun
|
||||||
if (BIT(m_status, 5))
|
if (BIT(m_status, 5))
|
||||||
@ -238,7 +250,7 @@ void i8279_device::new_fifo(uint8_t data)
|
|||||||
m_fifo[m_status & 7] = data;
|
m_fifo[m_status & 7] = data;
|
||||||
|
|
||||||
// bump fifo size & turn off underrun
|
// bump fifo size & turn off underrun
|
||||||
uint8_t fifo_size = m_status & 7;
|
u8 fifo_size = m_status & 7;
|
||||||
if ((fifo_size)==7)
|
if ((fifo_size)==7)
|
||||||
m_status |= 8; // full
|
m_status |= 8; // full
|
||||||
else
|
else
|
||||||
@ -263,9 +275,9 @@ void i8279_device::timer_mainloop()
|
|||||||
// bit 3 - number of digits to display
|
// bit 3 - number of digits to display
|
||||||
// bit 4 - left or right entry
|
// bit 4 - left or right entry
|
||||||
|
|
||||||
uint8_t scanner_mask = BIT(m_cmd[0], 0) ? 15 : BIT(m_cmd[0], 3) ? 15 : 7;
|
u8 scanner_mask = BIT(m_cmd[0], 0) ? 15 : BIT(m_cmd[0], 3) ? 15 : 7;
|
||||||
bool decoded = BIT(m_cmd[0], 0);
|
bool decoded = BIT(m_cmd[0], 0);
|
||||||
uint8_t kbd_type = (m_cmd[0] & 6) >> 1;
|
u8 kbd_type = (m_cmd[0] & 6) >> 1;
|
||||||
bool shift_key = 1;
|
bool shift_key = 1;
|
||||||
bool ctrl_key = 1;
|
bool ctrl_key = 1;
|
||||||
bool strobe_pulse = 0;
|
bool strobe_pulse = 0;
|
||||||
@ -292,10 +304,10 @@ void i8279_device::timer_mainloop()
|
|||||||
|
|
||||||
if ( !m_in_rl_cb.isnull() )
|
if ( !m_in_rl_cb.isnull() )
|
||||||
{
|
{
|
||||||
uint8_t rl = m_in_rl_cb(0);
|
u8 rl = m_in_rl_cb(0);
|
||||||
|
|
||||||
// see if key still down from last time
|
// see if key still down from last time
|
||||||
uint16_t key_down = (m_scanner << 8) | rl;
|
u16 key_down = (m_scanner << 8) | rl;
|
||||||
if (key_down == m_key_down)
|
if (key_down == m_key_down)
|
||||||
rl = 0xff;
|
rl = 0xff;
|
||||||
else
|
else
|
||||||
@ -314,7 +326,7 @@ void i8279_device::timer_mainloop()
|
|||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
uint8_t addr = m_scanner &7;
|
u8 addr = m_scanner &7;
|
||||||
|
|
||||||
if (decoded)
|
if (decoded)
|
||||||
for (addr=0; !BIT(m_scanner, addr); addr++) {};
|
for (addr=0; !BIT(m_scanner, addr); addr++) {};
|
||||||
@ -360,29 +372,29 @@ void i8279_device::timer_mainloop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
READ8_MEMBER(i8279_device::read)
|
u8 i8279_device::read(offs_t offset)
|
||||||
{
|
{
|
||||||
// A0 = control/data select
|
// A0 = control/data select
|
||||||
return (offset & 1) ? status_r(space, 0) : data_r(space, 0);
|
return (offset & 1) ? status_r() : data_r();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
READ8_MEMBER( i8279_device::status_r )
|
u8 i8279_device::status_r()
|
||||||
{
|
{
|
||||||
return m_status;
|
return m_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
READ8_MEMBER( i8279_device::data_r )
|
u8 i8279_device::data_r()
|
||||||
{
|
{
|
||||||
uint8_t i;
|
u8 i;
|
||||||
bool sensor_mode = ((m_cmd[0] & 6)==4);
|
bool sensor_mode = ((m_cmd[0] & 6)==4);
|
||||||
uint8_t data;
|
u8 data;
|
||||||
if (m_read_flag)
|
if (m_read_flag)
|
||||||
{
|
{
|
||||||
// read the display ram
|
// read the display ram
|
||||||
data = m_d_ram[m_d_ram_ptr];
|
data = m_d_ram[m_d_ram_ptr];
|
||||||
if (m_autoinc)
|
if (m_autoinc && !machine().side_effects_disabled())
|
||||||
{
|
{
|
||||||
m_d_ram_ptr++;
|
m_d_ram_ptr++;
|
||||||
}
|
}
|
||||||
@ -393,6 +405,8 @@ READ8_MEMBER( i8279_device::data_r )
|
|||||||
// read sensor ram
|
// read sensor ram
|
||||||
assert(m_s_ram_ptr < ARRAY_LENGTH(m_s_ram));
|
assert(m_s_ram_ptr < ARRAY_LENGTH(m_s_ram));
|
||||||
data = m_s_ram[m_s_ram_ptr];
|
data = m_s_ram[m_s_ram_ptr];
|
||||||
|
if (!machine().side_effects_disabled())
|
||||||
|
{
|
||||||
if (m_autoinc)
|
if (m_autoinc)
|
||||||
{
|
{
|
||||||
m_s_ram_ptr++;
|
m_s_ram_ptr++;
|
||||||
@ -402,11 +416,14 @@ READ8_MEMBER( i8279_device::data_r )
|
|||||||
set_irq(0);
|
set_irq(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// read a key from fifo
|
// read a key from fifo
|
||||||
data = m_fifo[0];
|
data = m_fifo[0];
|
||||||
uint8_t fifo_size = m_status & 7;
|
u8 fifo_size = m_status & 7;
|
||||||
|
if (!machine().side_effects_disabled())
|
||||||
|
{
|
||||||
switch (m_status & 0x38)
|
switch (m_status & 0x38)
|
||||||
{
|
{
|
||||||
case 0x00: // no errors
|
case 0x00: // no errors
|
||||||
@ -432,6 +449,7 @@ READ8_MEMBER( i8279_device::data_r )
|
|||||||
default:
|
default:
|
||||||
printf("Invalid status: %X\n", m_status);
|
printf("Invalid status: %X\n", m_status);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
m_status = (m_status & 0xd0) | fifo_size; // turn off overrun & full
|
m_status = (m_status & 0xd0) | fifo_size; // turn off overrun & full
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,19 +459,19 @@ READ8_MEMBER( i8279_device::data_r )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WRITE8_MEMBER(i8279_device::write)
|
void i8279_device::write(offs_t offset, u8 data)
|
||||||
{
|
{
|
||||||
// A0 = control/data select
|
// A0 = control/data select
|
||||||
if (offset & 1)
|
if (offset & 1)
|
||||||
cmd_w(space, 0, data);
|
cmd_w(data);
|
||||||
else
|
else
|
||||||
data_w(space, 0, data);
|
data_w(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WRITE8_MEMBER( i8279_device::cmd_w )
|
void i8279_device::cmd_w(u8 data)
|
||||||
{//printf("Command: %X=%X ",data>>5,data&31);
|
{//printf("Command: %X=%X ",data>>5,data&31);
|
||||||
uint8_t cmd = data >> 5;
|
u8 cmd = data >> 5;
|
||||||
data &= 0x1f;
|
data &= 0x1f;
|
||||||
m_cmd[cmd] = data;
|
m_cmd[cmd] = data;
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
@ -494,7 +512,7 @@ WRITE8_MEMBER( i8279_device::cmd_w )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WRITE8_MEMBER( i8279_device::data_w )
|
void i8279_device::data_w(u8 data)
|
||||||
{//printf("Data: %X ",data);
|
{//printf("Data: %X ",data);
|
||||||
if (BIT(m_cmd[0], 4) && m_autoinc)
|
if (BIT(m_cmd[0], 4) && m_autoinc)
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ class i8279_device : public device_t
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
i8279_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
i8279_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||||
|
|
||||||
auto out_irq_callback() { return m_out_irq_cb.bind(); }
|
auto out_irq_callback() { return m_out_irq_cb.bind(); }
|
||||||
auto out_sl_callback() { return m_out_sl_cb.bind(); }
|
auto out_sl_callback() { return m_out_sl_cb.bind(); }
|
||||||
@ -50,12 +50,12 @@ public:
|
|||||||
auto in_ctrl_callback() { return m_in_ctrl_cb.bind(); }
|
auto in_ctrl_callback() { return m_in_ctrl_cb.bind(); }
|
||||||
|
|
||||||
// read & write handlers
|
// read & write handlers
|
||||||
DECLARE_READ8_MEMBER(read);
|
u8 read(offs_t offset);
|
||||||
DECLARE_READ8_MEMBER(status_r);
|
u8 status_r();
|
||||||
DECLARE_READ8_MEMBER(data_r);
|
u8 data_r();
|
||||||
DECLARE_WRITE8_MEMBER(write);
|
void write(offs_t offset, u8 data);
|
||||||
DECLARE_WRITE8_MEMBER(cmd_w);
|
void cmd_w(u8 data);
|
||||||
DECLARE_WRITE8_MEMBER(data_w);
|
void data_w(u8 data);
|
||||||
void timer_mainloop();
|
void timer_mainloop();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -71,8 +71,8 @@ private:
|
|||||||
|
|
||||||
void timer_adjust();
|
void timer_adjust();
|
||||||
void clear_display();
|
void clear_display();
|
||||||
void new_key(uint8_t data, bool skey, bool ckey);
|
void new_key(u8 data, bool skey, bool ckey);
|
||||||
void new_fifo(uint8_t data);
|
void new_fifo(u8 data);
|
||||||
void set_irq(bool state);
|
void set_irq(bool state);
|
||||||
|
|
||||||
devcb_write_line m_out_irq_cb; // IRQ
|
devcb_write_line m_out_irq_cb; // IRQ
|
||||||
@ -85,20 +85,20 @@ private:
|
|||||||
|
|
||||||
emu_timer *m_timer;
|
emu_timer *m_timer;
|
||||||
|
|
||||||
uint8_t m_d_ram[16]; // display ram
|
u8 m_d_ram[16]; // display ram
|
||||||
uint8_t m_d_ram_ptr;
|
u8 m_d_ram_ptr;
|
||||||
uint8_t m_s_ram[8]; // might be same as fifo ram
|
u8 m_s_ram[8]; // might be same as fifo ram
|
||||||
uint8_t m_s_ram_ptr;
|
u8 m_s_ram_ptr;
|
||||||
uint8_t m_fifo[8]; // queued keystrokes
|
u8 m_fifo[8]; // queued keystrokes
|
||||||
uint8_t m_cmd[8]; // Device settings
|
u8 m_cmd[8]; // Device settings
|
||||||
uint8_t m_status; // Returned via status_r
|
u8 m_status; // Returned via status_r
|
||||||
uint32_t m_clock; // Internal scan clock
|
u32 m_scanclock; // Internal scan clock
|
||||||
uint8_t m_scanner; // next output on SL lines
|
u8 m_scanner; // next output on SL lines
|
||||||
|
|
||||||
bool m_autoinc; // auto-increment flag
|
bool m_autoinc; // auto-increment flag
|
||||||
bool m_read_flag; // read from where
|
bool m_read_flag; // read from where
|
||||||
bool m_ctrl_key; // previous state of strobe input
|
bool m_ctrl_key; // previous state of strobe input
|
||||||
uint16_t m_key_down;
|
u16 m_key_down;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user