diff --git a/src/devices/cpu/mcs96/i8x9x.cpp b/src/devices/cpu/mcs96/i8x9x.cpp index 0c986bdcd23..792cc1378bb 100644 --- a/src/devices/cpu/mcs96/i8x9x.cpp +++ b/src/devices/cpu/mcs96/i8x9x.cpp @@ -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(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(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; diff --git a/src/devices/cpu/mcs96/i8x9x.h b/src/devices/cpu/mcs96/i8x9x.h index bb0cc710b24..5f4ab03f8a5 100644 --- a/src/devices/cpu/mcs96/i8x9x.h +++ b/src/devices/cpu/mcs96/i8x9x.h @@ -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;