diff options
Diffstat (limited to 'src/devices/cpu/upd7810/upd7810.cpp')
-rw-r--r-- | src/devices/cpu/upd7810/upd7810.cpp | 661 |
1 files changed, 383 insertions, 278 deletions
diff --git a/src/devices/cpu/upd7810/upd7810.cpp b/src/devices/cpu/upd7810/upd7810.cpp index 54bc5e3757e..4f706c09a13 100644 --- a/src/devices/cpu/upd7810/upd7810.cpp +++ b/src/devices/cpu/upd7810/upd7810.cpp @@ -2,7 +2,7 @@ // copyright-holders:Juergen Buchmueller /***************************************************************************** * - * upd7810.c + * upd7810.cpp * Portable uPD7810/11, 7810H/11H, 78C10/C11/C14 emulator V0.3 * * This work is based on the @@ -12,20 +12,38 @@ * not to be confused with the later and incompatible 78K family, though * its architectural influence is acknowledged. * - * NS20030115: + * 2002-02-19 (PeT): + * - type selection/gamemaster support added + * - gamemaster init hack? added + * - ORAX added + * - jre negative fixed + * - prefixed opcodes skipping fixed + * - interrupts fixed and improved + * - sub(and related)/add/daa flags fixed + * - mvi ports,... fixed + * - rll, rlr, drll, drlr fixed + * - rets fixed + * - l0, l1 skipping fixed + * - calt fixed + * + * 2003-01-15 (NS): * - fixed INRW_wa() * - TODO: add 7807, differences are listed below. - * I only added support for these opcodes needed by homedata.c (yes, I am - * lazy): - * 4C CE (MOV A,PT) - * 48 AC (EXA) - * 48 AD (EXR) - * 48 AE (EXH) - * 48 AF (EXX) - * 50 xx (SKN bit) - * 58 xx (SETB) - * 5B xx (CLR) - * 5D xx (SK bit) + * I only added support for these opcodes needed by homedata.c (yes, I am lazy): + * - 4C CE (MOV A,PT) + * - 48 AC (EXA) + * - 48 AD (EXR) + * - 48 AE (EXH) + * - 48 AF (EXX) + * - 50 xx (SKN bit) + * - 58 xx (SETB) + * - 5B xx (CLR) + * - 5D xx (SK bit) + * + * 2004-05-23 (Hau): + * - gta, gti, dgt fixed + * - working reg opcodes fixed + * - sio input fixed * * 2008-02-24 (Wilbert Pol): * - Added preliminary support for uPD7801 @@ -38,32 +56,10 @@ * implementation has not been tested and is probably incorrect. * *****************************************************************************/ -/* Hau around 23 May 2004 - gta, gti, dgt fixed - working reg opcodes fixed - sio input fixed --- - PeT around 19 February 2002 - type selection/gamemaster support added - gamemaster init hack? added - ORAX added - jre negativ fixed - prefixed opcodes skipping fixed - interrupts fixed and improved - sub(and related)/add/daa flags fixed - mvi ports,... fixed - rll, rlr, drll, drlr fixed - rets fixed - l0, l1 skipping fixed - calt fixed -*/ - /* 7807 DESCRIPTION - - PA0 1 64 Vcc PA1 2 63 Vdd PA2 3 62 PD7/AD7 @@ -185,7 +181,6 @@ In asynchronous mode, you can - DIFFERENCES BETWEEN 7810 and 7807 -------------------------- @@ -375,13 +370,15 @@ STOP 01001000 10111011 12 stop #include "emu.h" #include "upd7810.h" -#include "debugger.h" - #include "upd7810_macros.h" #include "upd7810_dasm.h" DEFINE_DEVICE_TYPE(UPD7810, upd7810_device, "upd7810", "NEC uPD7810") +DEFINE_DEVICE_TYPE(UPD78C10, upd78c10_device, "upd78c10", "NEC uPD78C10") +DEFINE_DEVICE_TYPE(UPD7811, upd7811_device, "upd7811", "NEC uPD7811") +DEFINE_DEVICE_TYPE(UPD78C11, upd78c11_device, "upd78c11", "NEC uPD78C11") +DEFINE_DEVICE_TYPE(UPD78C14, upd78c14_device, "upd78c14", "NEC uPD78C14") DEFINE_DEVICE_TYPE(UPD7807, upd7807_device, "upd7807", "NEC uPD7807") DEFINE_DEVICE_TYPE(UPD7801, upd7801_device, "upd7801", "NEC uPD7801") DEFINE_DEVICE_TYPE(UPD78C05, upd78c05_device, "upd78c05", "NEC uPD78C05") @@ -395,7 +392,28 @@ void upd7810_device::upd_internal_128_ram_map(address_map &map) void upd7810_device::upd_internal_256_ram_map(address_map &map) { - map(0xff00, 0xffff).ram(); + map(0xff00, 0xffff).view(m_ram_view); + m_ram_view[0](0xff00, 0xffff).ram(); +} + +void upd7810_device::upd_internal_4096_rom_128_ram_map(address_map &map) +{ + map(0x0000, 0x0fff).rom(); + map(0xff80, 0xffff).ram(); +} + +void upd7810_device::upd_internal_4096_rom_256_ram_map(address_map &map) +{ + map(0x0000, 0x0fff).rom(); + map(0xff00, 0xffff).view(m_ram_view); + m_ram_view[0](0xff00, 0xffff).ram(); +} + +void upd7810_device::upd_internal_16k_rom_256_ram_map(address_map &map) +{ + map(0x0000, 0x3fff).rom(); + map(0xff00, 0xffff).view(m_ram_view); + m_ram_view[0](0xff00, 0xffff).ram(); } upd7810_device::upd7810_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal_map) @@ -404,27 +422,26 @@ upd7810_device::upd7810_device(const machine_config &mconfig, device_type type, , m_co0_func(*this) , m_co1_func(*this) , m_txd_func(*this) - , m_rxd_func(*this) - , m_an0_func(*this) - , m_an1_func(*this) - , m_an2_func(*this) - , m_an3_func(*this) - , m_an4_func(*this) - , m_an5_func(*this) - , m_an6_func(*this) - , m_an7_func(*this) - , m_pa_in_cb(*this) - , m_pb_in_cb(*this) - , m_pc_in_cb(*this) - , m_pd_in_cb(*this) - , m_pf_in_cb(*this) + , m_rxd_func(*this, 1) + , m_an_func(*this, 0) + , m_pa_in_cb(*this, 0xff) + , m_pb_in_cb(*this, 0xff) + , m_pc_in_cb(*this, 0xff) + , m_pd_in_cb(*this, 0xff) + , m_pf_in_cb(*this, 0xff) , m_pa_out_cb(*this) , m_pb_out_cb(*this) , m_pc_out_cb(*this) , m_pd_out_cb(*this) , m_pf_out_cb(*this) - , m_pt_in_cb(*this) + , m_pt_in_cb(*this, 0) // TODO: uPD7807 only , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0, internal_map) + , m_ram_view(*this, "ram_view") + , m_pa_pullups(0xff) + , m_pb_pullups(0xff) + , m_pc_pullups(0xff) + , m_pd_pullups(0xff) + , m_pf_pullups(0xff) { } @@ -445,6 +462,31 @@ upd7810_device::upd7810_device(const machine_config &mconfig, const char *tag, d { } +upd78c10_device::upd78c10_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal_map) + : upd7810_device(mconfig, type, tag, owner, clock, internal_map) +{ +} + +upd78c10_device::upd78c10_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : upd78c10_device(mconfig, UPD78C10, tag, owner, clock, address_map_constructor(FUNC(upd78c10_device::upd_internal_256_ram_map), this)) +{ +} + +upd7811_device::upd7811_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : upd7810_device(mconfig, UPD7811, tag, owner, clock, address_map_constructor(FUNC(upd7811_device::upd_internal_4096_rom_256_ram_map), this)) +{ +} + +upd78c11_device::upd78c11_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : upd78c10_device(mconfig, UPD78C11, tag, owner, clock, address_map_constructor(FUNC(upd78c11_device::upd_internal_4096_rom_256_ram_map), this)) +{ +} + +upd78c14_device::upd78c14_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : upd78c10_device(mconfig, UPD78C14, tag, owner, clock, address_map_constructor(FUNC(upd78c14_device::upd_internal_16k_rom_256_ram_map), this)) +{ +} + void upd7807_device::configure_ops() { m_opXX = s_opXX_7807; @@ -492,13 +534,13 @@ void upd78c05_device::configure_ops() m_opXX = s_opXX_78c05; } -upd78c05_device::upd78c05_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : upd78c05_device(mconfig, UPD78C05, tag, owner, clock) +upd78c05_device::upd78c05_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal_map) + : upd7810_device(mconfig, type, tag, owner, clock, internal_map) { } -upd78c05_device::upd78c05_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) - : upd7810_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(upd78c05_device::upd_internal_128_ram_map), this)) +upd78c05_device::upd78c05_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : upd78c05_device(mconfig, UPD78C05, tag, owner, clock, address_map_constructor(FUNC(upd78c05_device::upd_internal_128_ram_map), this)) { } @@ -515,7 +557,7 @@ void upd78c06_device::configure_ops() } upd78c06_device::upd78c06_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : upd78c05_device(mconfig, UPD78C06, tag, owner, clock) + : upd78c05_device(mconfig, UPD78C06, tag, owner, clock, address_map_constructor(FUNC(upd78c06_device::upd_internal_4096_rom_128_ram_map), this)) { } @@ -546,69 +588,58 @@ std::unique_ptr<util::disasm_interface> upd78c05_device::create_disassembler() return std::make_unique<upd78c05_disassembler>(); } -WRITE8_MEMBER(upd7810_device::pa_w) +void upd7810_device::pa_w(uint8_t data, uint8_t mem_mask) { COMBINE_DATA(&m_pa_in); } -WRITE8_MEMBER(upd7810_device::pb_w) +void upd7810_device::pb_w(uint8_t data, uint8_t mem_mask) { COMBINE_DATA(&m_pb_in); } -WRITE8_MEMBER(upd7810_device::pc_w) +void upd7810_device::pc_w(uint8_t data, uint8_t mem_mask) { COMBINE_DATA(&m_pc_in); } -WRITE8_MEMBER(upd7810_device::pd_w) +void upd7810_device::pd_w(uint8_t data, uint8_t mem_mask) { COMBINE_DATA(&m_pd_in); } -WRITE8_MEMBER(upd7810_device::pf_w) +void upd7810_device::pf_w(uint8_t data, uint8_t mem_mask) { COMBINE_DATA(&m_pf_in); } +void upd7810_device::sck_w(int state) +{ + if ((SMH & 0x03) == 0x03 && state != SCK) + update_sio(1); + SCK = state; +} + uint8_t upd7810_device::RP(offs_t port) { uint8_t data = 0xff; switch (port) { case UPD7810_PORTA: - if (m_ma && !m_pa_in_cb.isnull()) // NS20031301 no need to read if the port is set as output + if (m_ma && !m_pa_in_cb.isunset()) // NS20031301 no need to read if the port is set as output m_pa_in = m_pa_in_cb(0, m_ma); data = (m_pa_in & m_ma) | (m_pa_out & ~m_ma); break; case UPD7810_PORTB: - if (m_mb && !m_pb_in_cb.isnull()) // NS20031301 no need to read if the port is set as output + if (m_mb && !m_pb_in_cb.isunset()) // NS20031301 no need to read if the port is set as output m_pb_in = m_pb_in_cb(0, m_mb); data = (m_pb_in & m_mb) | (m_pb_out & ~m_mb); break; case UPD7810_PORTC: - if (m_mc && !m_pc_in_cb.isnull()) // NS20031301 no need to read if the port is set as output - m_pc_in = m_pc_in_cb(0, m_mc); - data = (m_pc_in & m_mc) | (m_pc_out & ~m_mc); - if (m_mcc & 0x01) /* PC0 = TxD output */ - data = (data & ~0x01) | (m_txd & 1 ? 0x01 : 0x00); - if (m_mcc & 0x02) /* PC1 = RxD input */ - data = (data & ~0x02) | (m_rxd & 1 ? 0x02 : 0x00); - if (m_mcc & 0x04) /* PC2 = SCK input/output */ - data = (data & ~0x04) | (m_sck & 1 ? 0x04 : 0x00); - if (m_mcc & 0x08) /* PC3 = TI/INT2 input */ - data = (data & ~0x08) | (m_int2 & 1 ? 0x08 : 0x00); - if (m_mcc & 0x10) /* PC4 = TO output */ - data = (data & ~0x10) | (m_to & 1 ? 0x10 : 0x00); - if (m_mcc & 0x20) /* PC5 = CI input */ - data = (data & ~0x20) | (m_ci & 1 ? 0x20 : 0x00); - if (m_mcc & 0x40) /* PC6 = CO0 output */ - data = (data & ~0x40) | (m_co0 & 1 ? 0x40 : 0x00); - if (m_mcc & 0x80) /* PC7 = CO1 output */ - data = (data & ~0x80) | (m_co1 & 1 ? 0x80 : 0x00); + data = read_pc(); break; case UPD7810_PORTD: - if (!m_pd_in_cb.isnull()) + if (!m_pd_in_cb.isunset()) m_pd_in = m_pd_in_cb(); switch (m_mm & 0x07) { @@ -624,7 +655,7 @@ uint8_t upd7810_device::RP(offs_t port) } break; case UPD7810_PORTF: - if (m_mf && !m_pf_in_cb.isnull()) + if (m_mf && !m_pf_in_cb.isunset()) m_pf_in = m_pf_in_cb(0, m_mf); switch (m_mm & 0x06) { @@ -653,50 +684,66 @@ uint8_t upd7810_device::RP(offs_t port) return data; } +uint8_t upd7810_device::read_pc() +{ + if (m_mc && !m_pc_in_cb.isunset()) // NS20031301 no need to read if the port is set as output + m_pc_in = m_pc_in_cb(0, m_mc); + uint8_t data = (m_pc_in & m_mc) | (m_pc_out & ~m_mc); + if (m_mcc & 0x01) /* PC0 = TxD output */ + data = (data & ~0x01) | (m_txd & 1 ? 0x01 : 0x00); + if (m_mcc & 0x02) /* PC1 = RxD input */ + data = (data & ~0x02) | (m_rxd & 1 ? 0x02 : 0x00); + if (m_mcc & 0x04) /* PC2 = SCK input/output */ + data = (data & ~0x04) | (m_sck & 1 ? 0x04 : 0x00); + if (m_mcc & 0x08) /* PC3 = TI/INT2 input */ + data = (data & ~0x08) | (m_int2 & 1 ? 0x08 : 0x00); + if (m_mcc & 0x10) /* PC4 = TO output */ + data = (data & ~0x10) | (m_to & 1 ? 0x10 : 0x00); + if (m_mcc & 0x20) /* PC5 = CI input */ + data = (data & ~0x20) | (m_ci & 1 ? 0x20 : 0x00); + if (m_mcc & 0x40) /* PC6 = CO0 output */ + data = (data & ~0x40) | (m_co0 & 1 ? 0x40 : 0x00); + if (m_mcc & 0x80) /* PC7 = CO1 output */ + data = (data & ~0x80) | (m_co1 & 1 ? 0x80 : 0x00); + return data; +} + +uint8_t upd7801_device::read_pc() +{ + if ((m_mc & 0x87) && !m_pc_in_cb.isunset()) // NS20031301 no need to read if the port is set as output + m_pc_in = m_pc_in_cb(0, 0x84 | (m_mc & 0x03)); + uint8_t data = (m_pc_in & 0x87) | (m_pc_out & ~0x87); + if (!BIT(m_mc, 2)) /* TODO PC2 = -SCS input */ + data = (data & ~0x04) | 0x04; + if (!BIT(m_mc, 7)) /* TODO PC7 = HOLD input */ + data = (data & ~0x80); + return data; +} + void upd7810_device::WP(offs_t port, uint8_t data) { switch (port) { case UPD7810_PORTA: m_pa_out = data; -// data = (data & ~m_ma) | (m_pa_in & m_ma); - data = (data & ~m_ma) | (m_ma); // NS20031401 + data = (data & ~m_ma) | (m_pa_pullups & m_ma); m_pa_out_cb(data); break; case UPD7810_PORTB: m_pb_out = data; -// data = (data & ~m_mb) | (m_pb_in & m_mb); - data = (data & ~m_mb) | (m_mb); // NS20031401 + data = (data & ~m_mb) | (m_pb_pullups & m_mb); m_pb_out_cb(data); break; case UPD7810_PORTC: m_pc_out = data; -// data = (data & ~m_mc) | (m_pc_in & m_mc); - data = (data & ~m_mc) | (m_mc); // NS20031401 - if (m_mcc & 0x01) /* PC0 = TxD output */ - data = (data & ~0x01) | (m_txd & 1 ? 0x01 : 0x00); - if (m_mcc & 0x02) /* PC1 = RxD input */ - data = (data & ~0x02) | (m_rxd & 1 ? 0x02 : 0x00); - if (m_mcc & 0x04) /* PC2 = SCK input/output */ - data = (data & ~0x04) | (m_sck & 1 ? 0x04 : 0x00); - if (m_mcc & 0x08) /* PC3 = TI/INT2 input */ - data = (data & ~0x08) | (m_int2 & 1 ? 0x08 : 0x00); - if (m_mcc & 0x10) /* PC4 = TO output */ - data = (data & ~0x10) | (m_to & 1 ? 0x10 : 0x00); - if (m_mcc & 0x20) /* PC5 = CI input */ - data = (data & ~0x20) | (m_ci & 1 ? 0x20 : 0x00); - if (m_mcc & 0x40) /* PC6 = CO0 output */ - data = (data & ~0x40) | (m_co0 & 1 ? 0x40 : 0x00); - if (m_mcc & 0x80) /* PC7 = CO1 output */ - data = (data & ~0x80) | (m_co1 & 1 ? 0x80 : 0x00); - m_pc_out_cb(data); + write_pc(data); break; case UPD7810_PORTD: m_pd_out = data; switch (m_mm & 0x07) { case 0x00: /* PD input mode, PF port mode */ - data = m_pd_in; + data = m_pd_pullups; break; case 0x01: /* PD output mode, PF port mode */ data = m_pd_out; @@ -708,7 +755,7 @@ void upd7810_device::WP(offs_t port, uint8_t data) break; case UPD7810_PORTF: m_pf_out = data; - data = (data & ~m_mf) | (m_pf_in & m_mf); + data = (data & ~m_mf) | (m_pf_pullups & m_mf); switch (m_mm & 0x06) { case 0x00: /* PD input/output mode, PF port mode */ @@ -730,42 +777,79 @@ void upd7810_device::WP(offs_t port, uint8_t data) } } +void upd7810_device::write_pc(uint8_t data) +{ + data = (data & ~m_mc) | (m_pc_pullups & m_mc); + if (m_mcc & 0x01) /* PC0 = TxD output */ + data = (data & ~0x01) | (m_txd & 1 ? 0x01 : 0x00); + if (m_mcc & 0x02) /* PC1 = RxD input */ + data = (data & ~0x02) | (m_rxd & 1 ? 0x02 : 0x00); + if (m_mcc & 0x04) /* PC2 = SCK input/output */ + data = (data & ~0x04) | (m_sck & 1 ? 0x04 : 0x00); + if (m_mcc & 0x08) /* PC3 = TI/INT2 input */ + data = (data & ~0x08) | (m_int2 & 1 ? 0x08 : 0x00); + if (m_mcc & 0x10) /* PC4 = TO output */ + data = (data & ~0x10) | (m_to & 1 ? 0x10 : 0x00); + if (m_mcc & 0x20) /* PC5 = CI input */ + data = (data & ~0x20) | (m_ci & 1 ? 0x20 : 0x00); + if (m_mcc & 0x40) /* PC6 = CO0 output */ + data = (data & ~0x40) | (m_co0 & 1 ? 0x40 : 0x00); + if (m_mcc & 0x80) /* PC7 = CO1 output */ + data = (data & ~0x80) | (m_co1 & 1 ? 0x80 : 0x00); + m_pc_out_cb(data); +} + +void upd7801_device::write_pc(uint8_t data) +{ + data = (data & 0x78) | (m_pc_pullups & ~0x78); + if (!BIT(m_mc, 3)) /* TODO PC3 = SAK output */ + data = (data & ~0x08); + if (!BIT(m_mc, 4)) /* PC4 = TO output */ + data = (data & ~0x10) | (m_to & 1 ? 0x10 : 0x00); + if (!BIT(m_mc, 5)) /* TODO PC5 = IO/-M input */ + data = (data & ~0x20); + if (!BIT(m_mc, 6)) /* TODO PC6 = HLDA output */ + data = (data & ~0x40); + m_pc_out_cb(data); +} + void upd7810_device::upd7810_take_irq() { uint16_t vector = 0; int irqline = 0; /* global interrupt disable? */ - if (0 == IFF) + if (0 == IFF && !(IRR & INTFNMI)) return; /* check the interrupts in priority sequence */ - if (IRR & INTNMI) + if (IRR & INTFNMI) { /* Nonmaskable interrupt */ irqline = INPUT_LINE_NMI; vector = 0x0004; - IRR &= ~INTNMI; + IRR &= ~INTFNMI; } else if ((IRR & INTFT0) && 0 == (MKL & 0x02)) { vector = 0x0008; - if (!((IRR & INTFT1) && 0 == (MKL & 0x04))) - IRR&=~INTFT0; + if (0 != (MKL & 0x04)) + IRR&=~INTFT0; } else if ((IRR & INTFT1) && 0 == (MKL & 0x04)) { vector = 0x0008; - IRR&=~INTFT1; + if (0 != (MKL & 0x02)) + IRR&=~INTFT1; } else if ((IRR & INTF1) && 0 == (MKL & 0x08)) { irqline = UPD7810_INTF1; vector = 0x0010; - if (!((IRR & INTF2) && 0 == (MKL & 0x10))) + if (0 != (MKL & 0x10)) IRR&=~INTF1; } else @@ -773,56 +857,64 @@ void upd7810_device::upd7810_take_irq() { irqline = UPD7810_INTF2; vector = 0x0010; - IRR&=~INTF2; + if (0 != (MKL & 0x08)) + IRR&=~INTF2; } else if ((IRR & INTFE0) && 0 == (MKL & 0x20)) { vector = 0x0018; - if (!((IRR & INTFE1) && 0 == (MKL & 0x40))) - IRR&=~INTFE0; + if (0 != (MKL & 0x40)) + IRR&=~INTFE0; } else if ((IRR & INTFE1) && 0 == (MKL & 0x40)) { vector = 0x0018; - IRR&=~INTFE1; + if (0 != (MKL & 0x20)) + IRR&=~INTFE1; } else if ((IRR & INTFEIN) && 0 == (MKL & 0x80)) { vector = 0x0020; + if (0 != (MKH & 0x01)) + IRR&=~INTFEIN; } else if ((IRR & INTFAD) && 0 == (MKH & 0x01)) { vector = 0x0020; + if (0 != (MKL & 0x80)) + IRR&=~INTFAD; } else if ((IRR & INTFSR) && 0 == (MKH & 0x02)) { vector = 0x0028; - IRR&=~INTFSR; + if (0 != (MKH & 0x04)) + IRR&=~INTFSR; } else if ((IRR & INTFST) && 0 == (MKH & 0x04)) { vector = 0x0028; - IRR&=~INTFST; + if (0 != (MKH & 0x02)) + IRR&=~INTFST; } if (vector) { /* acknowledge external IRQ */ if (irqline) - standard_irq_callback(irqline); + standard_irq_callback(irqline, PC); SP--; WM( SP, PSW ); SP--; WM( SP, PCH ); SP--; WM( SP, PCL ); - IFF = 0; + IFF = m_iff_pending = 0; PSW &= ~(SK|L0|L1); PC = vector; } @@ -876,19 +968,30 @@ void upd7801_device::upd7810_take_irq() { /* acknowledge external IRQ */ if (irqline) - standard_irq_callback(irqline); + standard_irq_callback(irqline, PC); SP--; WM( SP, PSW ); SP--; WM( SP, PCH ); SP--; WM( SP, PCL ); - IFF = 0; + IFF = m_iff_pending = 0; PSW &= ~(SK|L0|L1); PC = vector; } } +void upd7810_device::upd7810_to_output_change(int state) +{ + if ((SMH & 0x03) == 0x00 && state != TO) + update_sio(1); + TO = state; + m_to_func(TO); + + if (m_mcc & 0x10) + WP(UPD7810_PORTC, m_pc_out); +} + void upd7810_device::upd7810_co0_output_change() { /* Output LV0 Content to CO0 */ @@ -899,6 +1002,8 @@ void upd7810_device::upd7810_co0_output_change() LV0 ^= 1; m_co0_func(CO0); + if (m_mcc & 0x40) + WP(UPD7810_PORTC, m_pc_out); } void upd7810_device::upd7810_co1_output_change() { @@ -910,6 +1015,8 @@ void upd7810_device::upd7810_co1_output_change() LV1 ^= 1; m_co1_func(CO1); + if (m_mcc & 0x80) + WP(UPD7810_PORTC, m_pc_out); } void upd7810_device::upd7810_write_EOM() @@ -964,6 +1071,8 @@ void upd7810_device::upd7810_sio_output() { TXD = m_txs & 1; m_txd_func(TXD); + if (m_mcc & 0x01) + WP(UPD7810_PORTC, m_pc_out); m_txs >>= 1; m_txcnt--; if (0 == m_txcnt) @@ -1078,6 +1187,7 @@ void upd7810_device::upd7810_sio_input() case 0x48: /* 7bits, no parity, 1 stop bit */ case 0x68: /* 7bits, no parity, 1 stop bit (parity select = 1 but parity is off) */ m_rxs >>= 16 - 9; + m_rxs |= ~0U << 9; RXB = (m_rxs >> 1) & 0x7f; if ((1 << 8) != (m_rxs & (1 | (1 << 8)))) IRR |= INTER; /* framing error */ @@ -1085,12 +1195,14 @@ void upd7810_device::upd7810_sio_input() case 0x4c: /* 8bits, no parity, 1 stop bit */ case 0x6c: /* 8bits, no parity, 1 stop bit (parity select = 1 but parity is off) */ m_rxs >>= 16 - 10; + m_rxs |= ~0U << 10; RXB = (m_rxs >> 1) & 0xff; if ((1 << 9) != (m_rxs & (1 | (1 << 9)))) IRR |= INTER; /* framing error */ break; case 0x58: /* 7bits, odd parity, 1 stop bit */ m_rxs >>= 16 - 10; + m_rxs |= ~0U << 10; RXB = (m_rxs >> 1) & 0x7f; if ((1 << 9) != (m_rxs & (1 | (1 << 9)))) IRR |= INTER; /* framing error */ @@ -1099,6 +1211,7 @@ void upd7810_device::upd7810_sio_input() break; case 0x5c: /* 8bits, odd parity, 1 stop bit */ m_rxs >>= 16 - 11; + m_rxs |= ~0U << 11; RXB = (m_rxs >> 1) & 0xff; if ((1 << 10) != (m_rxs & (1 | (1 << 10)))) IRR |= INTER; /* framing error */ @@ -1107,6 +1220,7 @@ void upd7810_device::upd7810_sio_input() break; case 0x78: /* 7bits, even parity, 1 stop bit */ m_rxs >>= 16 - 10; + m_rxs |= ~0U << 10; RXB = (m_rxs >> 1) & 0x7f; if ((1 << 9) != (m_rxs & (1 | (1 << 9)))) IRR |= INTER; /* framing error */ @@ -1115,6 +1229,7 @@ void upd7810_device::upd7810_sio_input() break; case 0x7c: /* 8bits, even parity, 1 stop bit */ m_rxs >>= 16 - 11; + m_rxs |= ~0U << 11; RXB = (m_rxs >> 1) & 0xff; if ((1 << 10) != (m_rxs & (1 | (1 << 10)))) IRR |= INTER; /* framing error */ @@ -1124,6 +1239,7 @@ void upd7810_device::upd7810_sio_input() case 0xc8: /* 7bits, no parity, 2 stop bits */ case 0xe8: /* 7bits, no parity, 2 stop bits (parity select = 1 but parity is off) */ m_rxs >>= 16 - 10; + m_rxs |= ~0U << 10; RXB = (m_rxs >> 1) & 0x7f; if ((3 << 9) != (m_rxs & (1 | (3 << 9)))) IRR |= INTER; /* framing error */ @@ -1133,6 +1249,7 @@ void upd7810_device::upd7810_sio_input() case 0xcc: /* 8bits, no parity, 2 stop bits */ case 0xec: /* 8bits, no parity, 2 stop bits (parity select = 1 but parity is off) */ m_rxs >>= 16 - 11; + m_rxs |= ~0U << 11; RXB = (m_rxs >> 1) & 0xff; if ((3 << 10) != (m_rxs & (1 | (3 << 10)))) IRR |= INTER; /* framing error */ @@ -1141,6 +1258,7 @@ void upd7810_device::upd7810_sio_input() break; case 0xd8: /* 7bits, odd parity, 2 stop bits */ m_rxs >>= 16 - 11; + m_rxs |= ~0U << 11; RXB = (m_rxs >> 1) & 0x7f; if ((3 << 10) != (m_rxs & (1 | (3 << 10)))) IRR |= INTER; /* framing error */ @@ -1149,6 +1267,7 @@ void upd7810_device::upd7810_sio_input() break; case 0xdc: /* 8bits, odd parity, 2 stop bits */ m_rxs >>= 16 - 12; + m_rxs |= ~0U << 12; RXB = (m_rxs >> 1) & 0xff; if ((3 << 11) != (m_rxs & (1 | (3 << 11)))) IRR |= INTER; /* framing error */ @@ -1157,6 +1276,7 @@ void upd7810_device::upd7810_sio_input() break; case 0xf8: /* 7bits, even parity, 2 stop bits */ m_rxs >>= 16 - 11; + m_rxs |= ~0U << 11; RXB = (m_rxs >> 1) & 0x7f; if ((3 << 10) != (m_rxs & (1 | (3 << 10)))) IRR |= INTER; /* framing error */ @@ -1165,6 +1285,7 @@ void upd7810_device::upd7810_sio_input() break; case 0xfc: /* 8bits, even parity, 2 stop bits */ m_rxs >>= 16 - 12; + m_rxs |= ~0U << 12; RXB = (m_rxs >> 1) & 0xff; if ((3 << 11) != (m_rxs & (1 | (3 << 11)))) IRR |= INTER; /* framing error */ @@ -1176,6 +1297,7 @@ void upd7810_device::upd7810_sio_input() else { m_rxs >>= 16 - 8; + m_rxs |= ~0U << 8; RXB = m_rxs; // m_rxcnt = 8; } @@ -1186,6 +1308,12 @@ void upd7810_device::upd7810_sio_input() { if (SML & 0x03) /* asynchronous mode ? */ { + // start bit check + RXD = m_rxd_func(); + m_rxs = (m_rxs >> 1) | ((uint16_t)RXD << 15); + if ((m_rxs & 0xc000) != 0x4000) + return; + switch (SML & 0xfc) { case 0x48: /* 7bits, no parity, 1 stop bit */ @@ -1229,6 +1357,8 @@ void upd7810_device::upd7810_sio_input() m_rxcnt = 12; break; } + + m_rxcnt--; // reduce by one since we already received the start bit at this point } else /* TSK bit set ? */ @@ -1253,8 +1383,7 @@ void upd7810_device::upd7810_handle_timer0(int cycles, int clkdiv) /* timer F/F source is timer 0 ? */ if (0x00 == (TMM & 0x03)) { - TO ^= 1; - m_to_func(TO); + upd7810_to_output_change(TO ^ 1); } /* timer 1 chained with timer 0 ? */ if ((TMM & 0xe0) == 0x60) @@ -1267,8 +1396,7 @@ void upd7810_device::upd7810_handle_timer0(int cycles, int clkdiv) /* timer F/F source is timer 1 ? */ if (0x01 == (TMM & 0x03)) { - TO ^= 1; - m_to_func(TO); + upd7810_to_output_change(TO ^ 1); } } } @@ -1290,13 +1418,31 @@ void upd7810_device::upd7810_handle_timer1(int cycles, int clkdiv) /* timer F/F source is timer 1 ? */ if (0x01 == (TMM & 0x03)) { - TO ^= 1; - m_to_func(TO); + upd7810_to_output_change(TO ^ 1); } } } } +void upd7810_device::update_sio(int cycles) +{ + const int divider[] = { 2, 384 / 3, 24 / 3, 2 }; + const int prescale[] = { 1, 1, 16, 64 }; + const int interval = divider[SMH & 0x03] * prescale[SML & 0x03]; + + OVCS += cycles; + + while (OVCS >= interval / 2) + { + OVCS -= (interval / 2); + + if (0 == (EDGES ^= 1)) + upd7810_sio_input(); // rising edge + else + upd7810_sio_output(); // falling edge + } +} + void upd7810_device::handle_timers(int cycles) { /**** TIMER 0 ****/ @@ -1306,11 +1452,11 @@ void upd7810_device::handle_timers(int cycles) { switch (TMM & 0x0c) /* timer 0 clock source */ { - case 0x00: /* clock divided by 12 */ - upd7810_handle_timer0(cycles, 12); + case 0x00: /* clock divided by 12 (machine cycles divided by 4) */ + upd7810_handle_timer0(cycles, 4); break; - case 0x04: /* clock divided by 384 */ - upd7810_handle_timer0(cycles, 384); + case 0x04: /* clock divided by 384 (machine cycles divided by 128) */ + upd7810_handle_timer0(cycles, 128); break; case 0x08: /* external signal at TI */ break; @@ -1326,11 +1472,11 @@ void upd7810_device::handle_timers(int cycles) { switch (TMM & 0x60) /* timer 1 clock source */ { - case 0x00: /* clock divided by 12 */ - upd7810_handle_timer1(cycles, 12); + case 0x00: /* clock divided by 12 (machine cycles divided by 4) */ + upd7810_handle_timer1(cycles, 4); break; - case 0x20: /* clock divided by 384 */ - upd7810_handle_timer1(cycles, 384); + case 0x20: /* clock divided by 384 (machine cycles divided by 128) */ + upd7810_handle_timer1(cycles, 128); break; case 0x40: /* external signal at TI */ break; @@ -1344,11 +1490,10 @@ void upd7810_device::handle_timers(int cycles) if (0x02 == (TMM & 0x03)) { OVCF += cycles; - while (OVCF >= 3) + while (OVCF >= 1) { - TO ^= 1; - m_to_func(TO); - OVCF -= 3; + upd7810_to_output_change(TO ^ 1); + OVCF -= 1; } } @@ -1361,9 +1506,9 @@ void upd7810_device::handle_timers(int cycles) { OVCE += cycles; /* clock divided by 12 */ - while (OVCE >= 12) + while (OVCE >= 12/3) { - OVCE -= 12; + OVCE -= 12/3; ECNT++; /* Interrupt Control Circuit */ if (ETM0 == ECNT) @@ -1406,32 +1551,10 @@ void upd7810_device::handle_timers(int cycles) } /**** SIO ****/ - switch (SMH & 0x03) + // we only handle "internal clock" serial mode here + if (((SMH & 0x03) == 0x01) || ((SMH & 0x03) == 0x02)) { - case 0x00: /* interval timer F/F */ - break; - case 0x01: /* internal clock divided by 384 */ - OVCS += cycles; - while (OVCS >= 384) - { - OVCS -= 384; - if (0 == (EDGES ^= 1)) - upd7810_sio_input(); - else - upd7810_sio_output(); - } - break; - case 0x02: /* internal clock divided by 24 */ - OVCS += cycles; - while (OVCS >= 24) - { - OVCS -= 24; - if (0 == (EDGES ^= 1)) - upd7810_sio_input(); - else - upd7810_sio_output(); - } - break; + update_sio(cycles); } /**** ADC ****/ @@ -1464,30 +1587,13 @@ void upd7810_device::handle_timers(int cycles) /* select mode */ if (m_shdone == 0) { - switch (m_adin) - { - case 0: m_tmpcr = m_an0_func(); break; - case 1: m_tmpcr = m_an1_func(); break; - case 2: m_tmpcr = m_an2_func(); break; - case 3: m_tmpcr = m_an3_func(); break; - case 4: m_tmpcr = m_an4_func(); break; - case 5: m_tmpcr = m_an5_func(); break; - case 6: m_tmpcr = m_an6_func(); break; - case 7: m_tmpcr = m_an7_func(); break; - } + m_tmpcr = m_an_func[m_adin](); m_shdone = 1; } if (m_adcnt > m_adtot) { m_adcnt -= m_adtot; - switch (m_adout) - { - // volfied code checks bit 0x80, old code set bit 0x01, TODO: verify which bits are set on real hw - case 0: CR0 = m_tmpcr ? 0xff:0x00; break; - case 1: CR1 = m_tmpcr ? 0xff:0x00; break; - case 2: CR2 = m_tmpcr ? 0xff:0x00; break; - case 3: CR3 = m_tmpcr ? 0xff:0x00; break; - } + CR[m_adout] = m_tmpcr; m_adout = (m_adout + 1) & 0x03; if (m_adout == 0) IRR |= INTFAD; @@ -1499,34 +1605,19 @@ void upd7810_device::handle_timers(int cycles) /* scan mode */ if (m_shdone == 0) { - switch (m_adin | m_adrange) - { - case 0: m_tmpcr = m_an0_func(); break; - case 1: m_tmpcr = m_an1_func(); break; - case 2: m_tmpcr = m_an2_func(); break; - case 3: m_tmpcr = m_an3_func(); break; - case 4: m_tmpcr = m_an4_func(); break; - case 5: m_tmpcr = m_an5_func(); break; - case 6: m_tmpcr = m_an6_func(); break; - case 7: m_tmpcr = m_an7_func(); break; - } + m_tmpcr = m_an_func[m_adin | m_adrange](); m_shdone = 1; } if (m_adcnt > m_adtot) { m_adcnt -= m_adtot; - switch (m_adout) - { - case 0: CR0 = m_tmpcr ? 0xff:0x00; break; - case 1: CR1 = m_tmpcr ? 0xff:0x00; break; - case 2: CR2 = m_tmpcr ? 0xff:0x00; break; - case 3: CR3 = m_tmpcr ? 0xff:0x00; break; - } - m_adin = (m_adin + 1) & 0x07; + CR[m_adout] = m_tmpcr; + m_adin = (m_adin + 1) & 0x03; // should loop from 0 to 3 for AN0-AN3 or AN4-AN7 m_adout = (m_adout + 1) & 0x03; if (m_adout == 0) IRR |= INTFAD; m_shdone = 0; + } } @@ -1544,11 +1635,10 @@ void upd7801_device::handle_timers(int cycles) IRR |= INTFT0; /* Reset the timer flip/fliop */ - TO = 0; - m_to_func(TO); + upd7810_to_output_change(0); /* Reload the timer */ - m_ovc0 = 16 * ( TM0 + ( ( TM1 & 0x0f ) << 8 ) ); + m_ovc0 = 8 * ( TM0 + ( ( TM1 & 0x0f ) << 8 ) ); } } } @@ -1558,52 +1648,22 @@ void upd78c05_device::handle_timers(int cycles) if ( m_ovc0 ) { m_ovc0 -= cycles; - if ( m_ovc0 <= 0 ) { + if ( m_ovc0 <= 0 ) + { IRR |= INTFT0; - if (0x00 == (TMM & 0x03)) { - TO ^= 1; - m_to_func(TO); - } + if (0x00 == (TMM & 0x03)) + upd7810_to_output_change(TO ^ 1); - while ( m_ovc0 <= 0 ) { + while ( m_ovc0 <= 0 ) m_ovc0 += ( ( TMM & 0x04 ) ? 16 * 8 : 8 ) * TM0; - } } } } void upd7810_device::base_device_start() { - m_program = &space(AS_PROGRAM); - m_cache = m_program->cache<0, 0, ENDIANNESS_LITTLE>(); - - m_to_func.resolve_safe(); - m_co0_func.resolve_safe(); - m_co1_func.resolve_safe(); - m_txd_func.resolve_safe(); - m_rxd_func.resolve_safe(0); - m_an0_func.resolve_safe(0); - m_an1_func.resolve_safe(0); - m_an2_func.resolve_safe(0); - m_an3_func.resolve_safe(0); - m_an4_func.resolve_safe(0); - m_an5_func.resolve_safe(0); - m_an6_func.resolve_safe(0); - m_an7_func.resolve_safe(0); - - m_pa_in_cb.resolve(); - m_pb_in_cb.resolve(); - m_pc_in_cb.resolve(); - m_pd_in_cb.resolve(); - m_pf_in_cb.resolve(); - - m_pa_out_cb.resolve_safe(); - m_pb_out_cb.resolve_safe(); - m_pc_out_cb.resolve_safe(); - m_pd_out_cb.resolve_safe(); - m_pf_out_cb.resolve_safe(); - - m_pt_in_cb.resolve_safe(0); // TODO: uPD7807 only + space(AS_PROGRAM).specific(m_program); + space(AS_PROGRAM).cache(m_opcodes); configure_ops(); @@ -1614,6 +1674,7 @@ void upd7810_device::base_device_start() save_item(NAME(m_op)); save_item(NAME(m_op2)); save_item(NAME(m_iff)); + save_item(NAME(m_iff_pending)); save_item(NAME(m_ea.w.l)); save_item(NAME(m_va.w.l)); save_item(NAME(m_bc.w.l)); @@ -1640,19 +1701,22 @@ void upd7810_device::base_device_start() save_item(NAME(m_eom)); save_item(NAME(m_sml)); save_item(NAME(m_smh)); + save_item(NAME(m_panm)); save_item(NAME(m_anm)); save_item(NAME(m_mkl)); save_item(NAME(m_mkh)); save_item(NAME(m_zcm)); + save_item(NAME(m_pa_in)); + save_item(NAME(m_pb_in)); + save_item(NAME(m_pc_in)); + save_item(NAME(m_pd_in)); + save_item(NAME(m_pf_in)); save_item(NAME(m_pa_out)); save_item(NAME(m_pb_out)); save_item(NAME(m_pc_out)); save_item(NAME(m_pd_out)); save_item(NAME(m_pf_out)); - save_item(NAME(m_cr0)); - save_item(NAME(m_cr1)); - save_item(NAME(m_cr2)); - save_item(NAME(m_cr3)); + save_item(NAME(m_cr)); save_item(NAME(m_txb)); save_item(NAME(m_rxb)); save_item(NAME(m_txd)); @@ -1667,14 +1731,28 @@ void upd7810_device::base_device_start() save_item(NAME(m_co1)); save_item(NAME(m_irr)); save_item(NAME(m_itf)); + save_item(NAME(m_nmi)); + save_item(NAME(m_int1)); + save_item(NAME(m_int2)); + + save_item(NAME(m_txs)); + save_item(NAME(m_rxs)); + save_item(NAME(m_txcnt)); + save_item(NAME(m_rxcnt)); + save_item(NAME(m_txbuf)); save_item(NAME(m_ovc0)); save_item(NAME(m_ovc1)); + save_item(NAME(m_ovce)); save_item(NAME(m_ovcf)); save_item(NAME(m_ovcs)); save_item(NAME(m_edges)); - save_item(NAME(m_nmi)); - save_item(NAME(m_int1)); - save_item(NAME(m_int2)); + save_item(NAME(m_adcnt)); + save_item(NAME(m_adtot)); + save_item(NAME(m_tmpcr)); + save_item(NAME(m_shdone)); + save_item(NAME(m_adout)); + save_item(NAME(m_adin)); + save_item(NAME(m_adrange)); set_icountptr(m_icount); } @@ -1683,6 +1761,9 @@ void upd7810_device::device_start() { base_device_start(); + MM = 8; + m_ram_view.select(0); + state_add( UPD7810_PC, "PC", m_pc.w.l).formatstr("%04X"); state_add( UPD7810_SP, "SP", m_sp.w.l).formatstr("%04X"); state_add( UPD7810_PSW, "PSW", m_psw).formatstr("%02X"); @@ -1721,10 +1802,10 @@ void upd7810_device::device_start() state_add( UPD7810_MKL, "MKL", m_mkl).formatstr("%02X"); state_add( UPD7810_MKH, "MKH", m_mkh).formatstr("%02X"); state_add( UPD7810_ZCM, "ZCM", m_zcm).formatstr("%02X"); - state_add( UPD7810_CR0, "CR0", m_cr0).formatstr("%02X"); - state_add( UPD7810_CR1, "CR1", m_cr1).formatstr("%02X"); - state_add( UPD7810_CR2, "CR2", m_cr2).formatstr("%02X"); - state_add( UPD7810_CR3, "CR3", m_cr3).formatstr("%02X"); + state_add( UPD7810_CR0, "CR0", m_cr[0]).formatstr("%02X"); + state_add( UPD7810_CR1, "CR1", m_cr[1]).formatstr("%02X"); + state_add( UPD7810_CR2, "CR2", m_cr[2]).formatstr("%02X"); + state_add( UPD7810_CR3, "CR3", m_cr[3]).formatstr("%02X"); state_add( UPD7810_RXB, "RXB", m_rxb).formatstr("%02X"); state_add( UPD7810_TXB, "TXB", m_txb).formatstr("%02X"); state_add( UPD7810_TXD, "TXD", m_txd).formatstr("%3u"); @@ -1740,7 +1821,31 @@ void upd7810_device::device_start() state_add( STATE_GENPC, "GENPC", m_pc.w.l ).formatstr("%04X").noshow(); state_add( STATE_GENPCBASE, "CURPC", m_ppc.w.l ).formatstr("%04X").noshow(); - state_add( STATE_GENSP, "GENSP", m_sp.w.l ).formatstr("%04X").noshow(); + state_add( STATE_GENFLAGS, "GENFLAGS", m_psw ).formatstr("%17s").noshow(); +} + +void upd7801_device::device_start() +{ + base_device_start(); + + state_add( UPD7810_PC, "PC", m_pc.w.l).formatstr("%04X"); + state_add( UPD7810_SP, "SP", m_sp.w.l).formatstr("%04X"); + state_add( UPD7810_PSW, "PSW", m_psw).formatstr("%02X"); + state_add( UPD7810_A, "A", m_va.b.l).formatstr("%02X"); + state_add( UPD7810_V, "V", m_va.b.h).formatstr("%02X"); + state_add( UPD7810_EA, "EA", m_ea.w.l).formatstr("%04X"); + state_add( UPD7810_BC, "BC", m_bc.w.l).formatstr("%04X"); + state_add( UPD7810_DE, "DE", m_de.w.l).formatstr("%04X"); + state_add( UPD7810_HL, "HL", m_hl.w.l).formatstr("%04X"); + state_add( UPD7810_CNT0, "CNT0", m_cnt.b.l).formatstr("%02X"); + state_add( UPD7810_CNT1, "CNT1", m_cnt.b.h).formatstr("%02X"); + state_add( UPD7810_TM0, "TM0", m_tm.b.l).formatstr("%02X"); + state_add( UPD7810_TM1, "TM1", m_tm.b.h).formatstr("%02X"); + state_add( UPD7810_MB, "MB", m_mb).formatstr("%02X"); + state_add( UPD7810_MKL, "MKL", m_mkl).formatstr("%02X"); + + state_add( STATE_GENPC, "GENPC", m_pc.w.l ).formatstr("%04X").noshow(); + state_add( STATE_GENPCBASE, "CURPC", m_ppc.w.l ).formatstr("%04X").noshow(); state_add( STATE_GENFLAGS, "GENFLAGS", m_psw ).formatstr("%17s").noshow(); } @@ -1771,9 +1876,7 @@ void upd78c05_device::device_start() state_add( STATE_GENPC, "GENPC", m_pc.w.l ).formatstr("%04X").noshow(); state_add( STATE_GENPCBASE, "CURPC", m_ppc.w.l ).formatstr("%04X").noshow(); - state_add( STATE_GENSP, "GENSP", m_sp.w.l ).formatstr("%04X").noshow(); state_add( STATE_GENFLAGS, "GENFLAGS", m_psw ).formatstr("%17s").noshow(); - } void upd7810_device::state_string_export(const device_state_entry &entry, std::string &str) const @@ -1800,6 +1903,7 @@ void upd7810_device::device_reset() m_op = 0; m_op2 = 0; m_iff = 0; + m_iff_pending = 0; m_psw = 0; m_ea.d = 0; m_va.d = 0; @@ -1817,15 +1921,17 @@ void upd7810_device::device_reset() m_etm.d = 0; MA = 0xff; MB = 0xff; - m_mcc = 0; + MCC = 0; MC = 0xff; - m_mm = 0; + MM &= 8; MF = 0xff; + m_mt = 0; TMM = 0xff; ETMM = 0xff; m_eom = 0; m_sml = 0; m_smh = 0; + PANM = 0xff; m_anm = 0; MKL = 0xFF; MKH = 0xFF; // ?? @@ -1840,10 +1946,10 @@ void upd7810_device::device_reset() m_pc_out = 0; m_pd_out = 0; m_pf_out = 0; - m_cr0 = 0; - m_cr1 = 0; - m_cr2 = 0; - m_cr3 = 0; + m_cr[0] = 0; + m_cr[1] = 0; + m_cr[2] = 0; + m_cr[3] = 0; m_txb = 0; m_rxb = 0; m_txd = 0; @@ -1860,10 +1966,10 @@ void upd7810_device::device_reset() m_itf = 0; m_nmi = 0; m_int1 = 0; - m_int2 = 1; /* physical (inverted) INT2 line state */ + m_int2 = 1; // physical (inverted) INT2 line state m_txs = 0; - m_rxs = 0; + m_rxs = ~0; m_txcnt = 0; m_rxcnt = 0; m_txbuf = 0; @@ -1880,8 +1986,6 @@ void upd7810_device::device_reset() m_adout = 0; m_adin = 0; m_adrange = 0; - - PANM = 0xff; } void upd7801_device::device_reset() @@ -1889,6 +1993,7 @@ void upd7801_device::device_reset() upd7810_device::device_reset(); MA = 0; /* Port A is output port on the uPD7801 */ m_ovc0 = 0; + m_int2 = 0; } void upd78c05_device::device_reset() @@ -1975,7 +2080,7 @@ void upd7810_device::execute_run() } m_icount -= cc; upd7810_take_irq(); - + m_iff = m_iff_pending; } while (m_icount > 0); } @@ -2028,7 +2133,7 @@ void upd7810_device::execute_set_input(int irqline, int state) case INPUT_LINE_NMI: /* NMI is falling edge sensitive */ if ( m_nmi == CLEAR_LINE && state == ASSERT_LINE ) - IRR |= INTNMI; + IRR |= INTFNMI; m_nmi = state; break; |