i8x9x: Preliminary HSO stuff (nw)

This commit is contained in:
AJR 2018-10-26 09:36:38 -04:00
parent 126d7b48e9
commit 2b8ab63d08
2 changed files with 68 additions and 43 deletions

View File

@ -12,9 +12,10 @@
#include "i8x9x.h"
#include "i8x9xd.h"
i8x9x_device::i8x9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
i8x9x_device::i8x9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) :
mcs96_device(mconfig, type, tag, owner, clock, 8, address_map_constructor(FUNC(i8x9x_device::internal_regs), this)),
m_ach_cb{{*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}},
m_hso_cb(*this),
m_serial_tx_cb(*this),
m_in_p0_cb(*this),
m_out_p1_cb(*this), m_in_p1_cb(*this),
@ -42,6 +43,7 @@ void i8x9x_device::device_resolve_objects()
{
for (auto &cb : m_ach_cb)
cb.resolve_safe(0);
m_hso_cb.resolve_safe();
m_serial_tx_cb.resolve_safe();
m_in_p0_cb.resolve_safe(0);
m_out_p1_cb.resolve_safe();
@ -89,6 +91,7 @@ void i8x9x_device::device_reset()
sp_con &= 0x17;
sp_stat &= 0x80;
serial_send_timer = 0;
m_hso_cb(0);
}
void i8x9x_device::commit_hso_cam()
@ -108,14 +111,14 @@ void i8x9x_device::commit_hso_cam()
hso_cam_hold.time = hso_time;
}
void i8x9x_device::ad_start(uint64_t current_time)
void i8x9x_device::ad_start(u64 current_time)
{
ad_result = (m_ach_cb[ad_command & 7]() << 6) | 8 | (ad_command & 7);
ad_done = current_time + 88;
internal_update(current_time);
}
void i8x9x_device::serial_send(uint8_t data)
void i8x9x_device::serial_send(u8 data)
{
serial_send_buf = data;
serial_send_timer = total_cycles() + 9600;
@ -276,7 +279,7 @@ void i8x9x_device::sp_con_w(u8 data)
u8 i8x9x_device::sp_stat_r()
{
uint8_t res = sp_stat;
u8 res = sp_stat;
if (!machine().side_effects_disabled())
{
sp_stat &= 0x80;
@ -292,8 +295,6 @@ void i8x9x_device::ioc0_w(u8 data)
u8 i8x9x_device::ios0_r()
{
if (!machine().side_effects_disabled())
logerror("read ios 0 %02x (%04x)\n", ios0, PPC);
return ios0;
}
@ -304,7 +305,7 @@ void i8x9x_device::ioc1_w(u8 data)
u8 i8x9x_device::ios1_r()
{
uint8_t res = ios1;
u8 res = ios1;
if (!machine().side_effects_disabled())
ios1 = ios1 & 0xc0;
return res;
@ -319,7 +320,7 @@ void i8x9x_device::do_exec_partial()
{
}
void i8x9x_device::serial_w(uint8_t val)
void i8x9x_device::serial_w(u8 val)
{
sbuf = val;
sp_stat |= 0x40;
@ -327,28 +328,40 @@ void i8x9x_device::serial_w(uint8_t val)
check_irq();
}
uint16_t i8x9x_device::timer_value(int timer, uint64_t current_time) const
u16 i8x9x_device::timer_value(int timer, u64 current_time) const
{
if(timer == 2)
current_time -= base_timer2;
return current_time >> 3;
}
uint64_t i8x9x_device::timer_time_until(int timer, uint64_t current_time, uint16_t timer_value) const
u64 i8x9x_device::timer_time_until(int timer, u64 current_time, u16 timer_value) const
{
uint64_t timer_base = timer == 2 ? base_timer2 : 0;
uint64_t delta = (current_time - timer_base) >> 3;
uint32_t tdelta = uint16_t(timer_value - delta);
u64 timer_base = timer == 2 ? base_timer2 : 0;
u64 delta = (current_time - timer_base) >> 3;
u32 tdelta = u16(timer_value - delta);
if(!tdelta)
tdelta = 0x10000;
return timer_base + ((delta + tdelta) << 3);
}
void i8x9x_device::trigger_cam(int id, uint64_t current_time)
void i8x9x_device::trigger_cam(int id, u64 current_time)
{
hso_cam_entry &cam = hso_info[id];
cam.active = false;
switch(cam.command & 0x0f) {
case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5:
set_hso(1 << (cam.command & 7), BIT(cam.command, 5));
break;
case 0x6:
set_hso(0x03, BIT(cam.command, 5));
break;
case 0x7:
set_hso(0x0c, BIT(cam.command, 5));
break;
case 0x8: case 0x9: case 0xa: case 0xb:
ios1 |= 1 << (cam.command & 3);
pending_irq |= IRQ_SOFT;
@ -361,15 +374,24 @@ void i8x9x_device::trigger_cam(int id, uint64_t current_time)
}
}
void i8x9x_device::internal_update(uint64_t current_time)
void i8x9x_device::set_hso(u8 mask, bool state)
{
uint16_t current_timer1 = timer_value(1, current_time);
uint16_t current_timer2 = timer_value(2, current_time);
if(state)
ios0 |= mask;
else
ios0 &= ~mask;
m_hso_cb(0, ios0 & 0x3f, mask);
}
void i8x9x_device::internal_update(u64 current_time)
{
u16 current_timer1 = timer_value(1, current_time);
u16 current_timer2 = timer_value(2, current_time);
for(int i=0; i<8; i++)
if(hso_info[i].active) {
uint8_t cmd = hso_info[i].command;
uint16_t t = hso_info[i].time;
u8 cmd = hso_info[i].command;
u16 t = hso_info[i].time;
if(((cmd & 0x40) && t == current_timer2) ||
(!(cmd & 0x40) && t == current_timer1)) {
if(cmd != 0x18 && cmd != 0x19)
@ -387,7 +409,7 @@ void i8x9x_device::internal_update(uint64_t current_time)
if(current_time == serial_send_timer)
serial_send_done();
uint64_t event_time = 0;
u64 event_time = 0;
for(int i=0; i<8; i++) {
if(!hso_info[i].active && hso_cam_hold.active) {
hso_info[i] = hso_cam_hold;
@ -395,7 +417,7 @@ void i8x9x_device::internal_update(uint64_t current_time)
logerror("%s: hso cam %02x %04x in slot %d from hold\n", tag(), hso_cam_hold.command, hso_cam_hold.time, i);
}
if(hso_info[i].active) {
uint64_t new_time = timer_time_until(hso_info[i].command & 0x40 ? 2 : 1, current_time, hso_info[i].time);
u64 new_time = timer_time_until(hso_info[i].command & 0x40 ? 2 : 1, current_time, hso_info[i].time);
if(!event_time || new_time < event_time)
event_time = new_time;
}
@ -410,12 +432,12 @@ void i8x9x_device::internal_update(uint64_t current_time)
recompute_bcount(event_time);
}
c8095_device::c8095_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
c8095_device::c8095_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
i8x9x_device(mconfig, C8095, tag, owner, clock)
{
}
p8098_device::p8098_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
p8098_device::p8098_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
i8x9x_device(mconfig, P8098, tag, owner, clock)
{
}

View File

@ -40,6 +40,7 @@ public:
auto ach5_cb() { return m_ach_cb[5].bind(); }
auto ach6_cb() { return m_ach_cb[6].bind(); }
auto ach7_cb() { return m_ach_cb[7].bind(); }
auto hso_cb() { return m_hso_cb.bind(); }
auto serial_tx_cb() { return m_serial_tx_cb.bind(); }
auto in_p0_cb() { return m_in_p0_cb.bind(); }
@ -48,10 +49,10 @@ public:
auto out_p2_cb() { return m_out_p2_cb.bind(); }
auto in_p2_cb() { return m_in_p2_cb.bind(); }
void serial_w(uint8_t val);
void serial_w(u8 val);
protected:
i8x9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
i8x9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
virtual void device_resolve_objects() override;
virtual void device_start() override;
@ -61,7 +62,7 @@ protected:
virtual void do_exec_full() override;
virtual void do_exec_partial() override;
virtual void internal_update(uint64_t current_time) override;
virtual void internal_update(u64 current_time) override;
void internal_regs(address_map &map);
void ad_command_w(u8 data);
@ -104,11 +105,12 @@ private:
struct hso_cam_entry {
bool active;
uint8_t command;
uint16_t time;
u8 command;
u16 time;
};
devcb_read16 m_ach_cb[8];
devcb_write8 m_hso_cb;
devcb_write8 m_serial_tx_cb;
devcb_read8 m_in_p0_cb;
@ -122,32 +124,33 @@ private:
hso_cam_entry hso_info[8];
hso_cam_entry hso_cam_hold;
uint64_t base_timer2, ad_done;
uint8_t hsi_mode, hso_command, ad_command;
uint16_t hso_time, ad_result;
uint8_t pwm_control;
uint8_t ios0, ios1, ioc0, ioc1;
uint8_t sbuf, sp_con, sp_stat;
uint8_t serial_send_buf;
uint64_t serial_send_timer;
u64 base_timer2, ad_done;
u8 hsi_mode, hso_command, ad_command;
u16 hso_time, ad_result;
u8 pwm_control;
u8 ios0, ios1, ioc0, ioc1;
u8 sbuf, sp_con, sp_stat;
u8 serial_send_buf;
u64 serial_send_timer;
uint16_t timer_value(int timer, uint64_t current_time) const;
uint64_t timer_time_until(int timer, uint64_t current_time, uint16_t timer_value) const;
u16 timer_value(int timer, u64 current_time) const;
u64 timer_time_until(int timer, u64 current_time, u16 timer_value) const;
void commit_hso_cam();
void trigger_cam(int id, uint64_t current_time);
void ad_start(uint64_t current_time);
void serial_send(uint8_t data);
void trigger_cam(int id, u64 current_time);
void set_hso(u8 mask, bool state);
void ad_start(u64 current_time);
void serial_send(u8 data);
void serial_send_done();
};
class c8095_device : public i8x9x_device {
public:
c8095_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
c8095_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class p8098_device : public i8x9x_device {
public:
p8098_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
p8098_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
DECLARE_DEVICE_TYPE(C8095, c8095_device)