i8x9x: Implement HSO CAM status flags in IOS0 (nw)

This commit is contained in:
AJR 2020-04-11 13:05:09 -04:00
parent 492402c924
commit b634a54e16
2 changed files with 33 additions and 26 deletions

View File

@ -20,18 +20,16 @@ i8x9x_device::i8x9x_device(const machine_config &mconfig, device_type type, cons
m_in_p0_cb(*this),
m_out_p1_cb(*this), m_in_p1_cb(*this),
m_out_p2_cb(*this), m_in_p2_cb(*this),
base_timer2(0), ad_done(0), hsi_mode(0), hsi_status(0), hso_command(0), ad_command(0), hso_time(0), ad_result(0), pwm_control(0),
base_timer2(0), ad_done(0), hsi_mode(0), hsi_status(0), hso_command(0), ad_command(0), hso_active(0), hso_time(0), ad_result(0), pwm_control(0),
port1(0), port2(0),
ios0(0), ios1(0), ioc0(0), ioc1(0), extint(false),
sbuf(0), sp_con(0), sp_stat(0), serial_send_buf(0), serial_send_timer(0), baud_reg(0), brh(false)
{
for (auto &hso : hso_info)
{
hso.active = false;
hso.command = 0;
hso.time = 0;
}
hso_cam_hold.active = false;
hso_cam_hold.command = 0;
hso_cam_hold.time = 0;
}
@ -77,16 +75,11 @@ void i8x9x_device::device_start()
state_add<u8>(I8X9X_PORT2, "PORT2", [this]() -> u8 { return port2; }, [this](u8 data) { port2_w(data); }).mask(i8x9x_p2_mask());
state_add(I8X9X_IOC0, "IOC0", ioc0).mask(0xfd);
state_add(I8X9X_IOC1, "IOC1", ioc1);
state_add(I8X9X_IOS0, "IOS0", ios0);
state_add<u8>(I8X9X_IOS0, "IOS0", [this]() -> u8 { return ios0; }, [this](u8 data) { ios0_w(data); });
state_add(I8X9X_IOS1, "IOS1", ios1);
for(int i = 0; i < 8; i++)
{
save_item(NAME(hso_info[i].active), i);
save_item(NAME(hso_info[i].command), i);
save_item(NAME(hso_info[i].time), i);
}
save_item(NAME(hso_cam_hold.active));
save_item(STRUCT_MEMBER(hso_info, command));
save_item(STRUCT_MEMBER(hso_info, time));
save_item(NAME(hso_cam_hold.command));
save_item(NAME(hso_cam_hold.time));
@ -96,6 +89,7 @@ void i8x9x_device::device_start()
save_item(NAME(hsi_status));
save_item(NAME(hso_command));
save_item(NAME(ad_command));
save_item(NAME(hso_active));
save_item(NAME(hso_time));
save_item(NAME(ad_result));
save_item(NAME(port1));
@ -118,9 +112,7 @@ void i8x9x_device::device_start()
void i8x9x_device::device_reset()
{
mcs96_device::device_reset();
for (auto &hso : hso_info)
hso.active = false;
hso_cam_hold.active = false;
hso_active = 0;
hso_command = 0;
hso_time = 0;
timer2_reset(total_cycles());
@ -144,15 +136,17 @@ void i8x9x_device::device_reset()
void i8x9x_device::commit_hso_cam()
{
for(int i=0; i<8; i++)
if(!hso_info[i].active) {
if(!BIT(hso_active, i)) {
//logerror("hso cam %02x %04x in slot %d (%04x)\n", hso_command, hso_time, i, PPC);
hso_info[i].active = true;
hso_active |= 1 << i;
if(hso_active == 0xff)
ios0 |= 0x40;
hso_info[i].command = hso_command;
hso_info[i].time = hso_time;
internal_update(total_cycles());
return;
}
hso_cam_hold.active = true;
ios0 |= 0xc0;
hso_cam_hold.command = hso_command;
hso_cam_hold.time = hso_time;
}
@ -271,7 +265,7 @@ void i8x9x_device::watchdog_w(u8 data)
u16 i8x9x_device::timer1_r()
{
u16 data = timer_value(1, total_cycles());
if (!machine().side_effects_disabled())
if (0 && !machine().side_effects_disabled())
logerror("read timer1 %04x (%04x)\n", data, PPC);
return data;
}
@ -366,6 +360,14 @@ u8 i8x9x_device::ios0_r()
return ios0;
}
void i8x9x_device::ios0_w(u8 data)
{
u8 mask = (data ^ ios0) & 0x3f;
ios0 = (data & 0x3f) | (ios0 & 0xc0);
if (mask != 0)
m_hso_cb(0, data & 0x3f, mask);
}
void i8x9x_device::ioc1_w(u8 data)
{
ioc1 = data;
@ -438,7 +440,9 @@ void i8x9x_device::set_hsi_state(int pin, bool state)
void i8x9x_device::trigger_cam(int id, u64 current_time)
{
hso_cam_entry &cam = hso_info[id];
cam.active = false;
if(hso_active == 0xff && !BIT(ios0, 7))
ios0 &= 0xbf;
hso_active &= ~(1 << id);
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));
@ -491,7 +495,7 @@ void i8x9x_device::internal_update(u64 current_time)
u16 current_timer2 = timer_value(2, current_time);
for(int i=0; i<8; i++)
if(hso_info[i].active) {
if(BIT(hso_active, i)) {
u8 cmd = hso_info[i].command;
u16 t = hso_info[i].time;
if(((cmd & 0x40) && t == current_timer2) ||
@ -514,12 +518,15 @@ void i8x9x_device::internal_update(u64 current_time)
u64 event_time = 0;
for(int i=0; i<8; i++) {
if(!hso_info[i].active && hso_cam_hold.active) {
if(!BIT(hso_active, i) && BIT(ios0, 7)) {
hso_info[i] = hso_cam_hold;
hso_cam_hold.active = false;
logerror("%s: hso cam %02x %04x in slot %d from hold\n", tag(), hso_cam_hold.command, hso_cam_hold.time, i);
hso_active |= 1 << i;
ios0 &= 0x7f;
if(hso_active == 0xff)
ios0 |= 0x40;
logerror("hso cam %02x %04x in slot %d from hold\n", hso_cam_hold.command, hso_cam_hold.time, i);
}
if(hso_info[i].active) {
if(BIT(hso_active, i)) {
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;

View File

@ -106,6 +106,7 @@ protected:
u8 sp_stat_r();
void ioc0_w(u8 data);
u8 ios0_r();
void ios0_w(u8 data);
void ioc1_w(u8 data);
u8 ios1_r();
void pwm_control_w(u8 data);
@ -123,7 +124,6 @@ private:
};
struct hso_cam_entry {
bool active;
u8 command;
u16 time;
};
@ -144,7 +144,7 @@ private:
hso_cam_entry hso_cam_hold;
u64 base_timer2, ad_done;
u8 hsi_mode, hsi_status, hso_command, ad_command;
u8 hsi_mode, hsi_status, hso_command, ad_command, hso_active;
u16 hso_time, ad_result;
u8 pwm_control;
u8 port1, port2;