summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/upd7810/upd7810.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/upd7810/upd7810.cpp')
-rw-r--r--src/devices/cpu/upd7810/upd7810.cpp661
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;