summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/mcs48
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/mcs48')
-rw-r--r--src/devices/cpu/mcs48/mcs48.cpp1398
-rw-r--r--src/devices/cpu/mcs48/mcs48.h815
-rw-r--r--src/devices/cpu/mcs48/mcs48dsm.cpp63
-rw-r--r--src/devices/cpu/mcs48/mcs48dsm.h9
4 files changed, 1176 insertions, 1109 deletions
diff --git a/src/devices/cpu/mcs48/mcs48.cpp b/src/devices/cpu/mcs48/mcs48.cpp
index afc71fbf651..879c0f38b7c 100644
--- a/src/devices/cpu/mcs48/mcs48.cpp
+++ b/src/devices/cpu/mcs48/mcs48.cpp
@@ -1,37 +1,55 @@
// license:BSD-3-Clause
-// copyright-holders:Mirko Buffoni
-/*
+// copyright-holders:Dan Boris, Mirko Buffoni, Aaron Giles, Couriersud
+/*******************************************************************************
+
+ Intel MCS-48/UPI-41 Portable Emulator
+
+ Copyright Mirko Buffoni
+ Based on the original work Copyright Dan Boris, an 8048 emulator
+
TODO:
- - EA pin - defined by architecture, must implement:
- 1 means external access, bypassing internal ROM
- reimplement as a push, not a pull
- add CMOS devices, 1 new opcode (01 IDL)
- add special 8022 opcodes (RAD, SEL AN0, SEL AN1, RETI)
- - make timer update cleaner:
- timer is updated on S4 while I/O happens on S5
- due to very bad coding, Kaypro 10 keyboard depends on being able to see T=0 before interrupt is taken
- right now this is implemented with a hack in the mov_a_t handler
- in theory it should also be possible to see the timer flag before the interrupt is taken
- mov_t_a should also update the T register after it's incremented
- - IRQ timing is similarly hacked due to WY-100 needing to take JNI branch before servicing interrupt
-*/
+ - IRQ and/or timer increment timing is wrong? See test below. After IRQ,
+ A = 0x20 on MAME, A = 0x22 on the real 8048 as tested by bataais.
-/***************************************************************************
+ stop tcnt
+ mov a,0xff
+ mov t,a
+ inc a
- mcs48.c
+ en tcnti
+ strt t
- Intel MCS-48/UPI-41 Portable Emulator
+ inc a
+ inc a
+ inc a
+ (etc.)
- Copyright Mirko Buffoni
- Based on the original work Copyright Dan Boris, an 8048 emulator
+ With the following test, on MAME, A = 0xff after 30 NOPs, A = 0 after 31
+ NOPs. On the real 8048, A = 0xff after 31 NOPs, A = 0 after 32 NOPs.
+ It can mean that STRT T has a 1 cycle delay, or simply that MOV A,T gets
+ the timer value pre-increment.
-****************************************************************************
+ stop tcnt
+ mov a,0xff
+ mov t,a
+ strt t
+
+ nop
+ nop
+ nop
+ (etc.)
+ mov a,t
+
+ - IRQ timing is hacked due to WY-100 needing to take JNI branch before
+ servicing interrupt (see m_irq_polled), probably related to note above?
+
+********************************************************************************
Note that the default internal divisor for this chip is by 3 and
then again by 5, or by 15 total.
-****************************************************************************
-
Chip RAM ROM I/O
---- --- --- ---
8021 64 1k 21 (ROM, reduced instruction set)
@@ -42,36 +60,36 @@
8648 64 1k 27 (OTPROM)
8748 64 1k 27 (EPROM)
8884 64 1k
- N7751 128 2k
+ UPD7751 64 1k (8048, speech synthesizer in internal ROM)
8039 128 0 27 (external ROM)
8049 128 2k 27 (ROM)
8749 128 2k 27 (EPROM)
M58715 128 0 (external ROM)
- 8040 256 4k 27 (external ROM)
+ 8040 256 0 27 (external ROM)
8050 256 4k 27 (ROM)
-****************************************************************************
+********************************************************************************
UPI-41/42 chips are MCS-48 derived, with some opcode changes:
- MCS-48 opcode UPI-41/42 opcode
- ------------- ----------------
- 02: OUTL BUS,A OUT DBB,A
- 08: INS BUS,A <illegal>
- 22: <illegal> IN DBB,A
- 75: ENT0 CLK <illegal>
- 80: MOVX A,@R0 <illegal>
- 81: MOVX A,@R1 <illegal>
- 86: JNI <dest> JOBF <dest>
- 88: ORL BUS,#n <illegal>
- 90: MOVX @R0,A MOV STS,A
- 91: MOVX @R1,A <illegal>
- 98: ANL BUS,#n <illegal>
- D6: <illegal> JNIBF <dest>
- E5: SEL MB0 EN DMA
- F5: SEL MB1 EN FLAGS
+ MCS-48 opcode UPI-41/42 opcode
+ ------------- ----------------
+ 02: OUTL BUS,A OUT DBB,A
+ 08: INS BUS,A <illegal>
+ 22: <illegal> IN DBB,A
+ 75: ENT0 CLK <illegal>
+ 80: MOVX A,@R0 <illegal>
+ 81: MOVX A,@R1 <illegal>
+ 86: JNI <dest> JOBF <dest>
+ 88: ORL BUS,#n <illegal>
+ 90: MOVX @R0,A MOV STS,A
+ 91: MOVX @R1,A <illegal>
+ 98: ANL BUS,#n <illegal>
+ D6: <illegal> JNIBF <dest>
+ E5: SEL MB0 EN DMA
+ F5: SEL MB1 EN FLAGS
Chip numbers are similar to the MCS-48 series:
@@ -89,45 +107,42 @@
8742 128 2k (EPROM)
8742AH 256 2k (EPROM)
-***************************************************************************/
+*******************************************************************************/
#include "emu.h"
-#include "debugger.h"
#include "mcs48.h"
#include "mcs48dsm.h"
-/***************************************************************************
+/*******************************************************************************
CONSTANTS
-***************************************************************************/
+*******************************************************************************/
-/* timer/counter enable bits */
+// timer/counter enable bits
#define TIMER_ENABLED 0x01
#define COUNTER_ENABLED 0x02
-/* flag bits */
+// flag bits
#define C_FLAG 0x80
#define A_FLAG 0x40
#define F_FLAG 0x20
#define B_FLAG 0x10
-/* status bits (UPI-41) */
-#define STS_F1 0x08
-#define STS_F0 0x04
+// status bits (UPI-41)
#define STS_IBF 0x02
#define STS_OBF 0x01
-/* port 2 bits (UPI-41) */
+// port 2 bits (UPI-41)
#define P2_OBF 0x10
#define P2_NIBF 0x20
#define P2_DRQ 0x40
#define P2_NDACK 0x80
-/* enable bits (UPI-41) */
+// enable bits (UPI-41)
#define ENABLE_FLAGS 0x01
#define ENABLE_DMA 0x02
-/* feature masks */
+// feature masks
#define MB_FEATURE 0x01
#define EXT_BUS_FEATURE 0x02
#define UPI41_FEATURE 0x04
@@ -135,11 +150,11 @@
#define I8048_FEATURE (MB_FEATURE | EXT_BUS_FEATURE)
-/***************************************************************************
+/*******************************************************************************
MACROS
-***************************************************************************/
+*******************************************************************************/
-/* r0-r7 map to memory via the regptr */
+// r0-r7 map to memory via the regptr
#define R0 m_regptr[0]
#define R1 m_regptr[1]
#define R2 m_regptr[2]
@@ -150,6 +165,9 @@
#define R7 m_regptr[7]
+/*******************************************************************************
+ DEVICE TYPES
+*******************************************************************************/
DEFINE_DEVICE_TYPE(I8021, i8021_device, "i8021", "Intel 8021")
DEFINE_DEVICE_TYPE(I8022, i8022_device, "i8022", "Intel 8022")
@@ -162,6 +180,7 @@ DEFINE_DEVICE_TYPE(I8049, i8049_device, "i8049", "Intel 8049")
DEFINE_DEVICE_TYPE(I8749, i8749_device, "i8749", "Intel 8749")
DEFINE_DEVICE_TYPE(I8040, i8040_device, "i8040", "Intel 8040")
DEFINE_DEVICE_TYPE(I8050, i8050_device, "i8050", "Intel 8050")
+
DEFINE_DEVICE_TYPE(I8041A, i8041a_device, "i8041a", "Intel 8041A")
DEFINE_DEVICE_TYPE(I8741A, i8741a_device, "i8741a", "Intel 8741A")
DEFINE_DEVICE_TYPE(I8041AH, i8041ah_device, "i8041ah", "Intel 8041AH")
@@ -170,190 +189,161 @@ DEFINE_DEVICE_TYPE(I8042, i8042_device, "i8042", "Intel 8042")
DEFINE_DEVICE_TYPE(I8742, i8742_device, "i8742", "Intel 8742")
DEFINE_DEVICE_TYPE(I8042AH, i8042ah_device, "i8042ah", "Intel 8042AH")
DEFINE_DEVICE_TYPE(I8742AH, i8742ah_device, "i8742ah", "Intel 8742AH")
-DEFINE_DEVICE_TYPE(MB8884, mb8884_device, "mb8884", "MB8884")
-DEFINE_DEVICE_TYPE(N7751, n7751_device, "n7751", "N7751")
-DEFINE_DEVICE_TYPE(M58715, m58715_device, "m58715", "M58715")
-
-
-/***************************************************************************
- ADDRESS MAPS
-***************************************************************************/
-/* FIXME: the memory maps should probably support rom banking for EA */
-void mcs48_cpu_device::program_10bit(address_map &map)
-{
- map(0x000, 0x3ff).rom();
-}
+DEFINE_DEVICE_TYPE(MB8884, mb8884_device, "mb8884", "Fujitsu MB8884")
+DEFINE_DEVICE_TYPE(UPD7751, upd7751_device, "upd7751", "NEC uPD7751")
+DEFINE_DEVICE_TYPE(M58715, m58715_device, "m58715", "Mitsubishi M58715")
-void mcs48_cpu_device::program_11bit(address_map &map)
-{
- map(0x000, 0x7ff).rom();
-}
-void mcs48_cpu_device::program_12bit(address_map &map)
-{
- map(0x000, 0xfff).rom();
-}
-
-void mcs48_cpu_device::data_6bit(address_map &map)
-{
- map(0x00, 0x3f).ram().share("data");
-}
+/*******************************************************************************
+ CONSTRUCTOR
+*******************************************************************************/
-void mcs48_cpu_device::data_7bit(address_map &map)
-{
- map(0x00, 0x7f).ram().share("data");
-}
-
-void mcs48_cpu_device::data_8bit(address_map &map)
-{
- map(0x00, 0xff).ram().share("data");
-}
-
-
-mcs48_cpu_device::mcs48_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int rom_size, int ram_size, uint8_t feature_mask, const mcs48_cpu_device::mcs48_ophandler *opcode_table)
+mcs48_cpu_device::mcs48_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int rom_size, int ram_size, u8 feature_mask, const mcs48_cpu_device::mcs48_ophandler *opcode_table)
: cpu_device(mconfig, type, tag, owner, clock)
- , m_program_config("program", ENDIANNESS_LITTLE, 8, (feature_mask & MB_FEATURE) != 0 ? 12 : 11, 0
- , (rom_size == 1024) ? address_map_constructor(FUNC(mcs48_cpu_device::program_10bit), this) : (rom_size == 2048) ? address_map_constructor(FUNC(mcs48_cpu_device::program_11bit), this) : (rom_size == 4096) ? address_map_constructor(FUNC(mcs48_cpu_device::program_12bit), this) : address_map_constructor())
- , m_data_config("data", ENDIANNESS_LITTLE, 8, ( ( ram_size == 64 ) ? 6 : ( ( ram_size == 128 ) ? 7 : 8 ) ), 0
- , (ram_size == 64) ? address_map_constructor(FUNC(mcs48_cpu_device::data_6bit), this) : (ram_size == 128) ? address_map_constructor(FUNC(mcs48_cpu_device::data_7bit), this) : address_map_constructor(FUNC(mcs48_cpu_device::data_8bit), this))
+ , m_program_config("program", ENDIANNESS_LITTLE, 8, (feature_mask & MB_FEATURE) != 0 ? 12 : 11, 0,
+ rom_size ? address_map_constructor(FUNC(mcs48_cpu_device::program_map), this) : address_map_constructor())
+ , m_data_config("data", ENDIANNESS_LITTLE, 8, ((ram_size == 64) ? 6 : ((ram_size == 128) ? 7 : 8)), 0,
+ address_map_constructor(FUNC(mcs48_cpu_device::data_map), this))
, m_io_config("io", ENDIANNESS_LITTLE, 8, 8, 0)
- , m_port_in_cb{{*this}, {*this}}
- , m_port_out_cb{{*this}, {*this}}
- , m_bus_in_cb(*this)
+ , m_rom_view(*this, "rom_view")
+ , m_port_in_cb(*this, 0xff)
+ , m_port_out_cb(*this)
+ , m_bus_in_cb(*this, 0xff)
, m_bus_out_cb(*this)
- , m_test_in_cb{{*this}, {*this}}
- , m_t0_clk_func()
+ , m_test_in_cb(*this, 0)
+ , m_t0_clk_func(*this)
, m_prog_out_cb(*this)
, m_psw(0)
, m_dataptr(*this, "data")
, m_feature_mask(feature_mask)
- , m_int_rom_size(rom_size)
+ , m_rom_size(rom_size)
+ , m_ram_size(ram_size)
, m_opcode_table(opcode_table)
{
// Sanity checks
- if ( ram_size != 64 && ram_size != 128 && ram_size != 256 )
+ if (ram_size != 64 && ram_size != 128 && ram_size != 256)
{
fatalerror("mcs48: Invalid RAM size\n");
}
- if ( rom_size != 0 && rom_size != 1024 && rom_size != 2048 && rom_size != 4096 )
+ if (rom_size != 0 && rom_size != 1024 && rom_size != 2048 && rom_size != 4096)
{
fatalerror("mcs48: Invalid ROM size\n");
}
}
-i8021_device::i8021_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8021_device::i8021_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: mcs48_cpu_device(mconfig, I8021, tag, owner, clock, 1024, 64, I802X_FEATURE, s_i8021_opcodes)
{
}
-i8022_device::i8022_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8022_device::i8022_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: mcs48_cpu_device(mconfig, I8022, tag, owner, clock, 2048, 128, I802X_FEATURE, s_i8022_opcodes)
{
}
-i8035_device::i8035_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8035_device::i8035_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: mcs48_cpu_device(mconfig, I8035, tag, owner, clock, 0, 64, I8048_FEATURE, s_mcs48_opcodes)
{
}
-i8048_device::i8048_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8048_device::i8048_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: mcs48_cpu_device(mconfig, I8048, tag, owner, clock, 1024, 64, I8048_FEATURE, s_mcs48_opcodes)
{
}
-i8648_device::i8648_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8648_device::i8648_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: mcs48_cpu_device(mconfig, I8648, tag, owner, clock, 1024, 64, I8048_FEATURE, s_mcs48_opcodes)
{
}
-i8748_device::i8748_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8748_device::i8748_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: mcs48_cpu_device(mconfig, I8748, tag, owner, clock, 1024, 64, I8048_FEATURE, s_mcs48_opcodes)
{
}
-i8039_device::i8039_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8039_device::i8039_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: mcs48_cpu_device(mconfig, I8039, tag, owner, clock, 0, 128, I8048_FEATURE, s_mcs48_opcodes)
{
}
-i8049_device::i8049_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8049_device::i8049_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: mcs48_cpu_device(mconfig, I8049, tag, owner, clock, 2048, 128, I8048_FEATURE, s_mcs48_opcodes)
{
}
-i8749_device::i8749_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8749_device::i8749_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: mcs48_cpu_device(mconfig, I8749, tag, owner, clock, 2048, 128, I8048_FEATURE, s_mcs48_opcodes)
{
}
-i8040_device::i8040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8040_device::i8040_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: mcs48_cpu_device(mconfig, I8040, tag, owner, clock, 0, 256, I8048_FEATURE, s_mcs48_opcodes)
{
}
-i8050_device::i8050_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8050_device::i8050_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: mcs48_cpu_device(mconfig, I8050, tag, owner, clock, 4096, 256, I8048_FEATURE, s_mcs48_opcodes)
{
}
-mb8884_device::mb8884_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+mb8884_device::mb8884_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: mcs48_cpu_device(mconfig, MB8884, tag, owner, clock, 0, 64, I8048_FEATURE, s_mcs48_opcodes)
{
}
-n7751_device::n7751_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : mcs48_cpu_device(mconfig, N7751, tag, owner, clock, 1024, 64, I8048_FEATURE, s_mcs48_opcodes)
+upd7751_device::upd7751_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : mcs48_cpu_device(mconfig, UPD7751, tag, owner, clock, 1024, 64, I8048_FEATURE, s_mcs48_opcodes)
{
}
-m58715_device::m58715_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+m58715_device::m58715_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: mcs48_cpu_device(mconfig, M58715, tag, owner, clock, 2048, 128, I8048_FEATURE, s_mcs48_opcodes)
{
}
-upi41_cpu_device::upi41_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int rom_size, int ram_size)
+upi41_cpu_device::upi41_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int rom_size, int ram_size)
: mcs48_cpu_device(mconfig, type, tag, owner, clock, rom_size, ram_size, UPI41_FEATURE, s_upi41_opcodes)
{
}
-i8041a_device::i8041a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8041a_device::i8041a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: upi41_cpu_device(mconfig, I8041A, tag, owner, clock, 1024, 64)
{
}
-i8741a_device::i8741a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8741a_device::i8741a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: upi41_cpu_device(mconfig, I8741A, tag, owner, clock, 1024, 64)
{
}
-i8041ah_device::i8041ah_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8041ah_device::i8041ah_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: upi41_cpu_device(mconfig, I8041AH, tag, owner, clock, 1024, 128)
{
}
-i8741ah_device::i8741ah_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8741ah_device::i8741ah_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: upi41_cpu_device(mconfig, I8741AH, tag, owner, clock, 1024, 128)
{
}
-i8042_device::i8042_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8042_device::i8042_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: upi41_cpu_device(mconfig, I8042, tag, owner, clock, 2048, 128)
{
}
-i8742_device::i8742_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8742_device::i8742_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: upi41_cpu_device(mconfig, I8742, tag, owner, clock, 2048, 128)
{
}
-i8042ah_device::i8042ah_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8042ah_device::i8042ah_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: upi41_cpu_device(mconfig, I8042AH, tag, owner, clock, 2048, 256)
{
}
-i8742ah_device::i8742ah_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+i8742ah_device::i8742ah_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: upi41_cpu_device(mconfig, I8742AH, tag, owner, clock, 2048, 256)
{
}
@@ -378,19 +368,44 @@ std::unique_ptr<util::disasm_interface> mcs48_cpu_device::create_disassembler()
return std::make_unique<mcs48_disassembler>((m_feature_mask & UPI41_FEATURE) != 0, (m_feature_mask & I802X_FEATURE) != 0);
}
-/***************************************************************************
+
+/*******************************************************************************
+ ADDRESS MAPS
+*******************************************************************************/
+
+void mcs48_cpu_device::program_map(address_map &map)
+{
+ const u16 end = m_rom_size - 1;
+
+ // I802X does not have EA pin
+ if (m_feature_mask & I802X_FEATURE)
+ map(0, end).rom();
+ else
+ {
+ map(0, end).view(m_rom_view);
+ m_rom_view[0](0, end).rom();
+ }
+}
+
+void mcs48_cpu_device::data_map(address_map &map)
+{
+ map(0, m_ram_size - 1).ram().share("data");
+}
+
+
+/*******************************************************************************
INLINE FUNCTIONS
-***************************************************************************/
+*******************************************************************************/
/*-------------------------------------------------
opcode_fetch - fetch an opcode byte
-------------------------------------------------*/
-uint8_t mcs48_cpu_device::opcode_fetch()
+u8 mcs48_cpu_device::opcode_fetch()
{
- uint16_t address = m_pc;
+ u16 address = m_pc;
m_pc = ((m_pc + 1) & 0x7ff) | (m_pc & 0x800);
- return m_cache->read_byte(address);
+ return m_program.read_byte(address);
}
@@ -399,11 +414,11 @@ uint8_t mcs48_cpu_device::opcode_fetch()
byte
-------------------------------------------------*/
-uint8_t mcs48_cpu_device::argument_fetch()
+u8 mcs48_cpu_device::argument_fetch()
{
- uint16_t address = m_pc;
+ u16 address = m_pc;
m_pc = ((m_pc + 1) & 0x7ff) | (m_pc & 0x800);
- return m_cache->read_byte(address);
+ return m_program.read_byte(address);
}
@@ -419,16 +434,33 @@ void mcs48_cpu_device::update_regptr()
/*-------------------------------------------------
- push_pc_psw - push the m_pc and m_psw values onto
+ update_ea - apply EA pin (External Access input,
+ EA=1: external ROM, EA=0: internal ROM)
+-------------------------------------------------*/
+
+void mcs48_cpu_device::update_ea()
+{
+ if (m_rom_view.exists())
+ {
+ if (m_ea)
+ m_rom_view.disable();
+ else
+ m_rom_view.select(0);
+ }
+}
+
+
+/*-------------------------------------------------
+ push_pc_psw - push the PC and PSW values onto
the stack
-------------------------------------------------*/
void mcs48_cpu_device::push_pc_psw()
{
- uint8_t sp = m_psw & 0x07;
+ u8 sp = m_psw & 0x07;
ram_w(8 + 2*sp, m_pc);
ram_w(9 + 2*sp, ((m_pc >> 8) & 0x0f) | (m_psw & 0xf0));
- m_psw = (m_psw & 0xf8) | ((sp + 1) & 0x07);
+ m_psw = (m_psw & 0xf0) | ((sp + 1) & 0x07);
}
@@ -439,11 +471,11 @@ void mcs48_cpu_device::push_pc_psw()
void mcs48_cpu_device::pull_pc_psw()
{
- uint8_t sp = (m_psw - 1) & 0x07;
+ u8 sp = (m_psw - 1) & 0x07;
m_pc = ram_r(8 + 2*sp);
m_pc |= ram_r(9 + 2*sp) << 8;
- m_psw = ((m_pc >> 8) & 0xf0) | 0x08 | sp;
- m_pc &= 0xfff;
+ m_psw = ((m_pc >> 8) & 0xf0) | sp;
+ m_pc &= (m_irq_in_progress) ? 0x7ff : 0xfff;
update_regptr();
}
@@ -455,11 +487,11 @@ void mcs48_cpu_device::pull_pc_psw()
void mcs48_cpu_device::pull_pc()
{
- uint8_t sp = (m_psw - 1) & 0x07;
+ u8 sp = (m_psw - 1) & 0x07;
m_pc = ram_r(8 + 2*sp);
m_pc |= ram_r(9 + 2*sp) << 8;
- m_pc &= 0xfff;
- m_psw = (m_psw & 0xf0) | 0x08 | sp;
+ m_pc &= (m_irq_in_progress) ? 0x7ff : 0xfff;
+ m_psw = (m_psw & 0xf0) | sp;
}
@@ -468,10 +500,10 @@ void mcs48_cpu_device::pull_pc()
instruction
-------------------------------------------------*/
-void mcs48_cpu_device::execute_add(uint8_t dat)
+void mcs48_cpu_device::execute_add(u8 dat)
{
- uint16_t temp = m_a + dat;
- uint16_t temp4 = (m_a & 0x0f) + (dat & 0x0f);
+ u16 temp = m_a + dat;
+ u16 temp4 = (m_a & 0x0f) + (dat & 0x0f);
m_psw &= ~(C_FLAG | A_FLAG);
m_psw |= (temp4 << 2) & A_FLAG;
@@ -485,11 +517,11 @@ void mcs48_cpu_device::execute_add(uint8_t dat)
instruction
-------------------------------------------------*/
-void mcs48_cpu_device::execute_addc(uint8_t dat)
+void mcs48_cpu_device::execute_addc(u8 dat)
{
- uint8_t carryin = (m_psw & C_FLAG) >> 7;
- uint16_t temp = m_a + dat + carryin;
- uint16_t temp4 = (m_a & 0x0f) + (dat & 0x0f) + carryin;
+ u8 carryin = (m_psw & C_FLAG) >> 7;
+ u16 temp = m_a + dat + carryin;
+ u16 temp4 = (m_a & 0x0f) + (dat & 0x0f) + carryin;
m_psw &= ~(C_FLAG | A_FLAG);
m_psw |= (temp4 << 2) & A_FLAG;
@@ -503,9 +535,9 @@ void mcs48_cpu_device::execute_addc(uint8_t dat)
instruction
-------------------------------------------------*/
-void mcs48_cpu_device::execute_jmp(uint16_t address)
+void mcs48_cpu_device::execute_jmp(u16 address)
{
- uint16_t a11 = (m_irq_in_progress) ? 0 : m_a11;
+ u16 a11 = (m_irq_in_progress) ? 0 : m_a11;
m_pc = address | a11;
}
@@ -515,7 +547,7 @@ void mcs48_cpu_device::execute_jmp(uint16_t address)
instruction
-------------------------------------------------*/
-void mcs48_cpu_device::execute_call(uint16_t address)
+void mcs48_cpu_device::execute_call(u16 address)
{
push_pc_psw();
execute_jmp(address);
@@ -527,11 +559,12 @@ void mcs48_cpu_device::execute_call(uint16_t address)
conditional jump instruction
-------------------------------------------------*/
-void mcs48_cpu_device::execute_jcc(uint8_t result)
+void mcs48_cpu_device::execute_jcc(bool result)
{
- uint8_t offset = argument_fetch();
- if (result != 0)
- m_pc = ((m_pc - 1) & 0xf00) | offset;
+ u16 pch = m_pc & 0xf00;
+ u8 offset = argument_fetch();
+ if (result)
+ m_pc = pch | offset;
}
@@ -540,9 +573,9 @@ void mcs48_cpu_device::execute_jcc(uint8_t result)
code can directly affect
-------------------------------------------------*/
-uint8_t mcs48_cpu_device::p2_mask()
+u8 mcs48_cpu_device::p2_mask()
{
- uint8_t result = 0xff;
+ u8 result = 0xff;
if ((m_feature_mask & UPI41_FEATURE) == 0)
return result;
if (m_flags_enabled)
@@ -558,10 +591,10 @@ uint8_t mcs48_cpu_device::p2_mask()
the 8243 expander chip
-------------------------------------------------*/
-void mcs48_cpu_device::expander_operation(expander_op operation, uint8_t port)
+void mcs48_cpu_device::expander_operation(expander_op operation, u8 port)
{
// put opcode on low 4 bits of P2 (overwriting latch)
- port_w(2, m_p2 = (m_p2 & 0xf0) | (uint8_t(operation) << 2) | (port & 3));
+ port_w(2, m_p2 = (m_p2 & 0xf0) | (u8(operation) << 2) | (port & 3));
// generate high-to-low transition on PROG line
prog_w(0);
@@ -584,508 +617,513 @@ void mcs48_cpu_device::expander_operation(expander_op operation, uint8_t port)
-/***************************************************************************
+/*******************************************************************************
OPCODE HANDLERS
-***************************************************************************/
+*******************************************************************************/
-#define OPHANDLER(_name) int mcs48_cpu_device::_name()
+#define OPHANDLER(_name) void mcs48_cpu_device::_name()
OPHANDLER( illegal )
{
- logerror("MCS-48 PC:%04X - Illegal opcode = %02x\n", m_pc - 1, program_r(m_pc - 1));
- return 1;
-}
-
-OPHANDLER( add_a_r0 ) { execute_add(R0); return 1; }
-OPHANDLER( add_a_r1 ) { execute_add(R1); return 1; }
-OPHANDLER( add_a_r2 ) { execute_add(R2); return 1; }
-OPHANDLER( add_a_r3 ) { execute_add(R3); return 1; }
-OPHANDLER( add_a_r4 ) { execute_add(R4); return 1; }
-OPHANDLER( add_a_r5 ) { execute_add(R5); return 1; }
-OPHANDLER( add_a_r6 ) { execute_add(R6); return 1; }
-OPHANDLER( add_a_r7 ) { execute_add(R7); return 1; }
-OPHANDLER( add_a_xr0 ) { execute_add(ram_r(R0)); return 1; }
-OPHANDLER( add_a_xr1 ) { execute_add(ram_r(R1)); return 1; }
-OPHANDLER( add_a_n ) { execute_add(argument_fetch()); return 2; }
-
-OPHANDLER( adc_a_r0 ) { execute_addc(R0); return 1; }
-OPHANDLER( adc_a_r1 ) { execute_addc(R1); return 1; }
-OPHANDLER( adc_a_r2 ) { execute_addc(R2); return 1; }
-OPHANDLER( adc_a_r3 ) { execute_addc(R3); return 1; }
-OPHANDLER( adc_a_r4 ) { execute_addc(R4); return 1; }
-OPHANDLER( adc_a_r5 ) { execute_addc(R5); return 1; }
-OPHANDLER( adc_a_r6 ) { execute_addc(R6); return 1; }
-OPHANDLER( adc_a_r7 ) { execute_addc(R7); return 1; }
-OPHANDLER( adc_a_xr0 ) { execute_addc(ram_r(R0)); return 1; }
-OPHANDLER( adc_a_xr1 ) { execute_addc(ram_r(R1)); return 1; }
-OPHANDLER( adc_a_n ) { execute_addc(argument_fetch()); return 2; }
-
-OPHANDLER( anl_a_r0 ) { m_a &= R0; return 1; }
-OPHANDLER( anl_a_r1 ) { m_a &= R1; return 1; }
-OPHANDLER( anl_a_r2 ) { m_a &= R2; return 1; }
-OPHANDLER( anl_a_r3 ) { m_a &= R3; return 1; }
-OPHANDLER( anl_a_r4 ) { m_a &= R4; return 1; }
-OPHANDLER( anl_a_r5 ) { m_a &= R5; return 1; }
-OPHANDLER( anl_a_r6 ) { m_a &= R6; return 1; }
-OPHANDLER( anl_a_r7 ) { m_a &= R7; return 1; }
-OPHANDLER( anl_a_xr0 ) { m_a &= ram_r(R0); return 1; }
-OPHANDLER( anl_a_xr1 ) { m_a &= ram_r(R1); return 1; }
-OPHANDLER( anl_a_n ) { m_a &= argument_fetch(); return 2; }
-
-OPHANDLER( anl_bus_n ) { bus_w(bus_r() & argument_fetch()); return 2; }
-OPHANDLER( anl_p1_n ) { port_w(1, m_p1 &= argument_fetch()); return 2; }
-OPHANDLER( anl_p2_n ) { port_w(2, m_p2 &= argument_fetch() | ~p2_mask()); return 2; }
-OPHANDLER( anld_p4_a ) { expander_operation(EXPANDER_OP_AND, 4); return 2; }
-OPHANDLER( anld_p5_a ) { expander_operation(EXPANDER_OP_AND, 5); return 2; }
-OPHANDLER( anld_p6_a ) { expander_operation(EXPANDER_OP_AND, 6); return 2; }
-OPHANDLER( anld_p7_a ) { expander_operation(EXPANDER_OP_AND, 7); return 2; }
-
-OPHANDLER( call_0 ) { execute_call(argument_fetch() | 0x000); return 2; }
-OPHANDLER( call_1 ) { execute_call(argument_fetch() | 0x100); return 2; }
-OPHANDLER( call_2 ) { execute_call(argument_fetch() | 0x200); return 2; }
-OPHANDLER( call_3 ) { execute_call(argument_fetch() | 0x300); return 2; }
-OPHANDLER( call_4 ) { execute_call(argument_fetch() | 0x400); return 2; }
-OPHANDLER( call_5 ) { execute_call(argument_fetch() | 0x500); return 2; }
-OPHANDLER( call_6 ) { execute_call(argument_fetch() | 0x600); return 2; }
-OPHANDLER( call_7 ) { execute_call(argument_fetch() | 0x700); return 2; }
-
-OPHANDLER( clr_a ) { m_a = 0; return 1; }
-OPHANDLER( clr_c ) { m_psw &= ~C_FLAG; return 1; }
-OPHANDLER( clr_f0 ) { m_psw &= ~F_FLAG; m_sts &= ~STS_F0; return 1; }
-OPHANDLER( clr_f1 ) { m_sts &= ~STS_F1; return 1; }
-
-OPHANDLER( cpl_a ) { m_a ^= 0xff; return 1; }
-OPHANDLER( cpl_c ) { m_psw ^= C_FLAG; return 1; }
-OPHANDLER( cpl_f0 ) { m_psw ^= F_FLAG; m_sts ^= STS_F0; return 1; }
-OPHANDLER( cpl_f1 ) { m_sts ^= STS_F1; return 1; }
+ burn_cycles(1);
+ logerror("Illegal opcode = %02x @ %04X\n", program_r(m_prevpc), m_prevpc);
+}
+
+OPHANDLER( add_a_r0 ) { burn_cycles(1); execute_add(R0); }
+OPHANDLER( add_a_r1 ) { burn_cycles(1); execute_add(R1); }
+OPHANDLER( add_a_r2 ) { burn_cycles(1); execute_add(R2); }
+OPHANDLER( add_a_r3 ) { burn_cycles(1); execute_add(R3); }
+OPHANDLER( add_a_r4 ) { burn_cycles(1); execute_add(R4); }
+OPHANDLER( add_a_r5 ) { burn_cycles(1); execute_add(R5); }
+OPHANDLER( add_a_r6 ) { burn_cycles(1); execute_add(R6); }
+OPHANDLER( add_a_r7 ) { burn_cycles(1); execute_add(R7); }
+OPHANDLER( add_a_xr0 ) { burn_cycles(1); execute_add(ram_r(R0)); }
+OPHANDLER( add_a_xr1 ) { burn_cycles(1); execute_add(ram_r(R1)); }
+OPHANDLER( add_a_n ) { burn_cycles(2); execute_add(argument_fetch()); }
+
+OPHANDLER( adc_a_r0 ) { burn_cycles(1); execute_addc(R0); }
+OPHANDLER( adc_a_r1 ) { burn_cycles(1); execute_addc(R1); }
+OPHANDLER( adc_a_r2 ) { burn_cycles(1); execute_addc(R2); }
+OPHANDLER( adc_a_r3 ) { burn_cycles(1); execute_addc(R3); }
+OPHANDLER( adc_a_r4 ) { burn_cycles(1); execute_addc(R4); }
+OPHANDLER( adc_a_r5 ) { burn_cycles(1); execute_addc(R5); }
+OPHANDLER( adc_a_r6 ) { burn_cycles(1); execute_addc(R6); }
+OPHANDLER( adc_a_r7 ) { burn_cycles(1); execute_addc(R7); }
+OPHANDLER( adc_a_xr0 ) { burn_cycles(1); execute_addc(ram_r(R0)); }
+OPHANDLER( adc_a_xr1 ) { burn_cycles(1); execute_addc(ram_r(R1)); }
+OPHANDLER( adc_a_n ) { burn_cycles(2); execute_addc(argument_fetch()); }
+
+OPHANDLER( anl_a_r0 ) { burn_cycles(1); m_a &= R0; }
+OPHANDLER( anl_a_r1 ) { burn_cycles(1); m_a &= R1; }
+OPHANDLER( anl_a_r2 ) { burn_cycles(1); m_a &= R2; }
+OPHANDLER( anl_a_r3 ) { burn_cycles(1); m_a &= R3; }
+OPHANDLER( anl_a_r4 ) { burn_cycles(1); m_a &= R4; }
+OPHANDLER( anl_a_r5 ) { burn_cycles(1); m_a &= R5; }
+OPHANDLER( anl_a_r6 ) { burn_cycles(1); m_a &= R6; }
+OPHANDLER( anl_a_r7 ) { burn_cycles(1); m_a &= R7; }
+OPHANDLER( anl_a_xr0 ) { burn_cycles(1); m_a &= ram_r(R0); }
+OPHANDLER( anl_a_xr1 ) { burn_cycles(1); m_a &= ram_r(R1); }
+OPHANDLER( anl_a_n ) { burn_cycles(2); m_a &= argument_fetch(); }
+
+OPHANDLER( anl_bus_n ) { burn_cycles(2); bus_w(bus_r() & argument_fetch()); }
+OPHANDLER( anl_p1_n ) { burn_cycles(2); port_w(1, m_p1 &= argument_fetch()); }
+OPHANDLER( anl_p2_n ) { burn_cycles(2); port_w(2, m_p2 &= argument_fetch() | ~p2_mask()); }
+OPHANDLER( anld_p4_a ) { burn_cycles(2); expander_operation(EXPANDER_OP_AND, 4); }
+OPHANDLER( anld_p5_a ) { burn_cycles(2); expander_operation(EXPANDER_OP_AND, 5); }
+OPHANDLER( anld_p6_a ) { burn_cycles(2); expander_operation(EXPANDER_OP_AND, 6); }
+OPHANDLER( anld_p7_a ) { burn_cycles(2); expander_operation(EXPANDER_OP_AND, 7); }
+
+OPHANDLER( call_0 ) { burn_cycles(2); execute_call(argument_fetch() | 0x000); }
+OPHANDLER( call_1 ) { burn_cycles(2); execute_call(argument_fetch() | 0x100); }
+OPHANDLER( call_2 ) { burn_cycles(2); execute_call(argument_fetch() | 0x200); }
+OPHANDLER( call_3 ) { burn_cycles(2); execute_call(argument_fetch() | 0x300); }
+OPHANDLER( call_4 ) { burn_cycles(2); execute_call(argument_fetch() | 0x400); }
+OPHANDLER( call_5 ) { burn_cycles(2); execute_call(argument_fetch() | 0x500); }
+OPHANDLER( call_6 ) { burn_cycles(2); execute_call(argument_fetch() | 0x600); }
+OPHANDLER( call_7 ) { burn_cycles(2); execute_call(argument_fetch() | 0x700); }
+
+OPHANDLER( clr_a ) { burn_cycles(1); m_a = 0; }
+OPHANDLER( clr_c ) { burn_cycles(1); m_psw &= ~C_FLAG; }
+OPHANDLER( clr_f0 ) { burn_cycles(1); m_psw &= ~F_FLAG; }
+OPHANDLER( clr_f1 ) { burn_cycles(1); m_f1 = false; }
+
+OPHANDLER( cpl_a ) { burn_cycles(1); m_a ^= 0xff; }
+OPHANDLER( cpl_c ) { burn_cycles(1); m_psw ^= C_FLAG; }
+OPHANDLER( cpl_f0 ) { burn_cycles(1); m_psw ^= F_FLAG; }
+OPHANDLER( cpl_f1 ) { burn_cycles(1); m_f1 = !m_f1; }
OPHANDLER( da_a )
{
+ burn_cycles(1);
+
if ((m_a & 0x0f) > 0x09 || (m_psw & A_FLAG))
{
- m_a += 0x06;
- if ((m_a & 0xf0) == 0x00)
+ if (m_a > 0xf9)
m_psw |= C_FLAG;
+ m_a += 0x06;
}
if ((m_a & 0xf0) > 0x90 || (m_psw & C_FLAG))
{
m_a += 0x60;
m_psw |= C_FLAG;
}
- else
- m_psw &= ~C_FLAG;
- return 1;
}
-OPHANDLER( dec_a ) { m_a--; return 1; }
-OPHANDLER( dec_r0 ) { R0--; return 1; }
-OPHANDLER( dec_r1 ) { R1--; return 1; }
-OPHANDLER( dec_r2 ) { R2--; return 1; }
-OPHANDLER( dec_r3 ) { R3--; return 1; }
-OPHANDLER( dec_r4 ) { R4--; return 1; }
-OPHANDLER( dec_r5 ) { R5--; return 1; }
-OPHANDLER( dec_r6 ) { R6--; return 1; }
-OPHANDLER( dec_r7 ) { R7--; return 1; }
-
-OPHANDLER( dis_i ) { m_xirq_enabled = false; return 1; }
-OPHANDLER( dis_tcnti ) { m_tirq_enabled = false; m_timer_overflow = false; return 1; }
-
-OPHANDLER( djnz_r0 ) { execute_jcc(--R0 != 0); return 2; }
-OPHANDLER( djnz_r1 ) { execute_jcc(--R1 != 0); return 2; }
-OPHANDLER( djnz_r2 ) { execute_jcc(--R2 != 0); return 2; }
-OPHANDLER( djnz_r3 ) { execute_jcc(--R3 != 0); return 2; }
-OPHANDLER( djnz_r4 ) { execute_jcc(--R4 != 0); return 2; }
-OPHANDLER( djnz_r5 ) { execute_jcc(--R5 != 0); return 2; }
-OPHANDLER( djnz_r6 ) { execute_jcc(--R6 != 0); return 2; }
-OPHANDLER( djnz_r7 ) { execute_jcc(--R7 != 0); return 2; }
-
-OPHANDLER( en_i ) { m_xirq_enabled = true; return 1 + check_irqs(); }
-OPHANDLER( en_tcnti ) { m_tirq_enabled = true; return 1 + check_irqs(); }
-OPHANDLER( en_dma ) { m_dma_enabled = true; port_w(2, m_p2); return 1; }
-OPHANDLER( en_flags ) { m_flags_enabled = true; port_w(2, m_p2); return 1; }
+OPHANDLER( dec_a ) { burn_cycles(1); m_a--; }
+OPHANDLER( dec_r0 ) { burn_cycles(1); R0--; }
+OPHANDLER( dec_r1 ) { burn_cycles(1); R1--; }
+OPHANDLER( dec_r2 ) { burn_cycles(1); R2--; }
+OPHANDLER( dec_r3 ) { burn_cycles(1); R3--; }
+OPHANDLER( dec_r4 ) { burn_cycles(1); R4--; }
+OPHANDLER( dec_r5 ) { burn_cycles(1); R5--; }
+OPHANDLER( dec_r6 ) { burn_cycles(1); R6--; }
+OPHANDLER( dec_r7 ) { burn_cycles(1); R7--; }
+
+OPHANDLER( dis_i ) { burn_cycles(1); m_xirq_enabled = false; }
+OPHANDLER( dis_tcnti ) { burn_cycles(1); m_tirq_enabled = false; m_timer_overflow = false; }
+
+OPHANDLER( djnz_r0 ) { burn_cycles(2); execute_jcc(--R0 != 0); }
+OPHANDLER( djnz_r1 ) { burn_cycles(2); execute_jcc(--R1 != 0); }
+OPHANDLER( djnz_r2 ) { burn_cycles(2); execute_jcc(--R2 != 0); }
+OPHANDLER( djnz_r3 ) { burn_cycles(2); execute_jcc(--R3 != 0); }
+OPHANDLER( djnz_r4 ) { burn_cycles(2); execute_jcc(--R4 != 0); }
+OPHANDLER( djnz_r5 ) { burn_cycles(2); execute_jcc(--R5 != 0); }
+OPHANDLER( djnz_r6 ) { burn_cycles(2); execute_jcc(--R6 != 0); }
+OPHANDLER( djnz_r7 ) { burn_cycles(2); execute_jcc(--R7 != 0); }
+
+OPHANDLER( en_i ) { burn_cycles(1); m_xirq_enabled = true; }
+OPHANDLER( en_tcnti ) { burn_cycles(1); m_tirq_enabled = true; }
+OPHANDLER( en_dma ) { burn_cycles(1); m_dma_enabled = true; port_w(2, m_p2); }
+OPHANDLER( en_flags ) { burn_cycles(1); m_flags_enabled = true; port_w(2, m_p2); }
OPHANDLER( ent0_clk )
{
+ burn_cycles(1);
+
if (!m_t0_clk_func.isnull())
m_t0_clk_func(clock() / 3);
else
logerror("T0 clock enabled\n");
- return 1;
}
-OPHANDLER( in_a_p0 ) { m_a = bus_r() & m_dbbo; return 2; }
-OPHANDLER( in_a_p1 ) { m_a = port_r(1) & m_p1; return 2; }
-OPHANDLER( in_a_p2 ) { m_a = port_r(2) & m_p2; return 2; }
-OPHANDLER( ins_a_bus ) { m_a = bus_r(); return 2; }
+OPHANDLER( in_a_p0 ) { burn_cycles(2); m_a = bus_r() & m_dbbo; }
+OPHANDLER( in_a_p1 ) { burn_cycles(2); m_a = port_r(1) & m_p1; }
+OPHANDLER( in_a_p2 ) { burn_cycles(2); m_a = port_r(2) & m_p2; }
+OPHANDLER( ins_a_bus ) { burn_cycles(2); m_a = bus_r(); }
OPHANDLER( in_a_dbb )
{
- /* acknowledge the IBF IRQ and clear the bit in STS */
- if ((m_sts & STS_IBF) != 0)
- standard_irq_callback(UPI41_INPUT_IBF);
+ burn_cycles(1);
+
+ // acknowledge the IBF IRQ and clear the bit in STS
m_sts &= ~STS_IBF;
- /* if P2 flags are enabled, update the state of P2 */
+ // if P2 flags are enabled, update the state of P2
if (m_flags_enabled && (m_p2 & P2_NIBF) == 0)
port_w(2, m_p2 |= P2_NIBF);
m_a = m_dbbi;
- return 2;
}
-OPHANDLER( inc_a ) { m_a++; return 1; }
-OPHANDLER( inc_r0 ) { R0++; return 1; }
-OPHANDLER( inc_r1 ) { R1++; return 1; }
-OPHANDLER( inc_r2 ) { R2++; return 1; }
-OPHANDLER( inc_r3 ) { R3++; return 1; }
-OPHANDLER( inc_r4 ) { R4++; return 1; }
-OPHANDLER( inc_r5 ) { R5++; return 1; }
-OPHANDLER( inc_r6 ) { R6++; return 1; }
-OPHANDLER( inc_r7 ) { R7++; return 1; }
-OPHANDLER( inc_xr0 ) { ram_w(R0, ram_r(R0) + 1); return 1; }
-OPHANDLER( inc_xr1 ) { ram_w(R1, ram_r(R1) + 1); return 1; }
-
-OPHANDLER( jb_0 ) { execute_jcc((m_a & 0x01) != 0); return 2; }
-OPHANDLER( jb_1 ) { execute_jcc((m_a & 0x02) != 0); return 2; }
-OPHANDLER( jb_2 ) { execute_jcc((m_a & 0x04) != 0); return 2; }
-OPHANDLER( jb_3 ) { execute_jcc((m_a & 0x08) != 0); return 2; }
-OPHANDLER( jb_4 ) { execute_jcc((m_a & 0x10) != 0); return 2; }
-OPHANDLER( jb_5 ) { execute_jcc((m_a & 0x20) != 0); return 2; }
-OPHANDLER( jb_6 ) { execute_jcc((m_a & 0x40) != 0); return 2; }
-OPHANDLER( jb_7 ) { execute_jcc((m_a & 0x80) != 0); return 2; }
-OPHANDLER( jc ) { execute_jcc((m_psw & C_FLAG) != 0); return 2; }
-OPHANDLER( jf0 ) { execute_jcc((m_psw & F_FLAG) != 0); return 2; }
-OPHANDLER( jf1 ) { execute_jcc((m_sts & STS_F1) != 0); return 2; }
-OPHANDLER( jnc ) { execute_jcc((m_psw & C_FLAG) == 0); return 2; }
-OPHANDLER( jni ) { m_irq_polled = (m_irq_state == 0); execute_jcc(m_irq_state != 0); return 2; }
-OPHANDLER( jnibf ) { m_irq_polled = (m_sts & STS_IBF) != 0; execute_jcc((m_sts & STS_IBF) == 0); return 2; }
-OPHANDLER( jnt_0 ) { execute_jcc(test_r(0) == 0); return 2; }
-OPHANDLER( jnt_1 ) { execute_jcc(test_r(1) == 0); return 2; }
-OPHANDLER( jnz ) { execute_jcc(m_a != 0); return 2; }
-OPHANDLER( jobf ) { execute_jcc((m_sts & STS_OBF) != 0); return 2; }
-OPHANDLER( jtf ) { execute_jcc(m_timer_flag); m_timer_flag = false; return 2; }
-OPHANDLER( jt_0 ) { execute_jcc(test_r(0) != 0); return 2; }
-OPHANDLER( jt_1 ) { execute_jcc(test_r(1) != 0); return 2; }
-OPHANDLER( jz ) { execute_jcc(m_a == 0); return 2; }
-
-OPHANDLER( jmp_0 ) { execute_jmp(argument_fetch() | 0x000); return 2; }
-OPHANDLER( jmp_1 ) { execute_jmp(argument_fetch() | 0x100); return 2; }
-OPHANDLER( jmp_2 ) { execute_jmp(argument_fetch() | 0x200); return 2; }
-OPHANDLER( jmp_3 ) { execute_jmp(argument_fetch() | 0x300); return 2; }
-OPHANDLER( jmp_4 ) { execute_jmp(argument_fetch() | 0x400); return 2; }
-OPHANDLER( jmp_5 ) { execute_jmp(argument_fetch() | 0x500); return 2; }
-OPHANDLER( jmp_6 ) { execute_jmp(argument_fetch() | 0x600); return 2; }
-OPHANDLER( jmp_7 ) { execute_jmp(argument_fetch() | 0x700); return 2; }
-OPHANDLER( jmpp_xa ) { m_pc &= 0xf00; m_pc |= program_r(m_pc | m_a); return 2; }
-
-OPHANDLER( mov_a_n ) { m_a = argument_fetch(); return 2; }
-OPHANDLER( mov_a_psw ) { m_a = m_psw; return 1; }
-OPHANDLER( mov_a_r0 ) { m_a = R0; return 1; }
-OPHANDLER( mov_a_r1 ) { m_a = R1; return 1; }
-OPHANDLER( mov_a_r2 ) { m_a = R2; return 1; }
-OPHANDLER( mov_a_r3 ) { m_a = R3; return 1; }
-OPHANDLER( mov_a_r4 ) { m_a = R4; return 1; }
-OPHANDLER( mov_a_r5 ) { m_a = R5; return 1; }
-OPHANDLER( mov_a_r6 ) { m_a = R6; return 1; }
-OPHANDLER( mov_a_r7 ) { m_a = R7; return 1; }
-OPHANDLER( mov_a_xr0 ) { m_a = ram_r(R0); return 1; }
-OPHANDLER( mov_a_xr1 ) { m_a = ram_r(R1); return 1; }
-OPHANDLER( mov_a_t ) { m_a = m_timer + ((m_timecount_enabled & TIMER_ENABLED) ? 1 : 0); return 1; }
-
-OPHANDLER( mov_psw_a ) { m_psw = m_a; update_regptr(); return 1; }
-OPHANDLER( mov_sts_a ) { m_sts = (m_sts & 0x0f) | (m_a & 0xf0); return 1; }
-OPHANDLER( mov_r0_a ) { R0 = m_a; return 1; }
-OPHANDLER( mov_r1_a ) { R1 = m_a; return 1; }
-OPHANDLER( mov_r2_a ) { R2 = m_a; return 1; }
-OPHANDLER( mov_r3_a ) { R3 = m_a; return 1; }
-OPHANDLER( mov_r4_a ) { R4 = m_a; return 1; }
-OPHANDLER( mov_r5_a ) { R5 = m_a; return 1; }
-OPHANDLER( mov_r6_a ) { R6 = m_a; return 1; }
-OPHANDLER( mov_r7_a ) { R7 = m_a; return 1; }
-OPHANDLER( mov_r0_n ) { R0 = argument_fetch(); return 2; }
-OPHANDLER( mov_r1_n ) { R1 = argument_fetch(); return 2; }
-OPHANDLER( mov_r2_n ) { R2 = argument_fetch(); return 2; }
-OPHANDLER( mov_r3_n ) { R3 = argument_fetch(); return 2; }
-OPHANDLER( mov_r4_n ) { R4 = argument_fetch(); return 2; }
-OPHANDLER( mov_r5_n ) { R5 = argument_fetch(); return 2; }
-OPHANDLER( mov_r6_n ) { R6 = argument_fetch(); return 2; }
-OPHANDLER( mov_r7_n ) { R7 = argument_fetch(); return 2; }
-OPHANDLER( mov_t_a ) { m_timer = m_a; return 1; }
-OPHANDLER( mov_xr0_a ) { ram_w(R0, m_a); return 1; }
-OPHANDLER( mov_xr1_a ) { ram_w(R1, m_a); return 1; }
-OPHANDLER( mov_xr0_n ) { ram_w(R0, argument_fetch()); return 2; }
-OPHANDLER( mov_xr1_n ) { ram_w(R1, argument_fetch()); return 2; }
-
-OPHANDLER( movd_a_p4 ) { expander_operation(EXPANDER_OP_READ, 4); return 2; }
-OPHANDLER( movd_a_p5 ) { expander_operation(EXPANDER_OP_READ, 5); return 2; }
-OPHANDLER( movd_a_p6 ) { expander_operation(EXPANDER_OP_READ, 6); return 2; }
-OPHANDLER( movd_a_p7 ) { expander_operation(EXPANDER_OP_READ, 7); return 2; }
-OPHANDLER( movd_p4_a ) { expander_operation(EXPANDER_OP_WRITE, 4); return 2; }
-OPHANDLER( movd_p5_a ) { expander_operation(EXPANDER_OP_WRITE, 5); return 2; }
-OPHANDLER( movd_p6_a ) { expander_operation(EXPANDER_OP_WRITE, 6); return 2; }
-OPHANDLER( movd_p7_a ) { expander_operation(EXPANDER_OP_WRITE, 7); return 2; }
-
-OPHANDLER( movp_a_xa ) { m_a = program_r((m_pc & 0xf00) | m_a); return 2; }
-OPHANDLER( movp3_a_xa ) { m_a = program_r(0x300 | m_a); return 2; }
-
-OPHANDLER( movx_a_xr0 ) { m_a = ext_r(R0); return 2; }
-OPHANDLER( movx_a_xr1 ) { m_a = ext_r(R1); return 2; }
-OPHANDLER( movx_xr0_a ) { ext_w(R0, m_a); return 2; }
-OPHANDLER( movx_xr1_a ) { ext_w(R1, m_a); return 2; }
-
-OPHANDLER( nop ) { return 1; }
-
-OPHANDLER( orl_a_r0 ) { m_a |= R0; return 1; }
-OPHANDLER( orl_a_r1 ) { m_a |= R1; return 1; }
-OPHANDLER( orl_a_r2 ) { m_a |= R2; return 1; }
-OPHANDLER( orl_a_r3 ) { m_a |= R3; return 1; }
-OPHANDLER( orl_a_r4 ) { m_a |= R4; return 1; }
-OPHANDLER( orl_a_r5 ) { m_a |= R5; return 1; }
-OPHANDLER( orl_a_r6 ) { m_a |= R6; return 1; }
-OPHANDLER( orl_a_r7 ) { m_a |= R7; return 1; }
-OPHANDLER( orl_a_xr0 ) { m_a |= ram_r(R0); return 1; }
-OPHANDLER( orl_a_xr1 ) { m_a |= ram_r(R1); return 1; }
-OPHANDLER( orl_a_n ) { m_a |= argument_fetch(); return 2; }
-
-OPHANDLER( orl_bus_n ) { bus_w(bus_r() | argument_fetch()); return 2; }
-OPHANDLER( orl_p1_n ) { port_w(1, m_p1 |= argument_fetch()); return 2; }
-OPHANDLER( orl_p2_n ) { port_w(2, m_p2 |= argument_fetch() & p2_mask()); return 2; }
-OPHANDLER( orld_p4_a ) { expander_operation(EXPANDER_OP_OR, 4); return 2; }
-OPHANDLER( orld_p5_a ) { expander_operation(EXPANDER_OP_OR, 5); return 2; }
-OPHANDLER( orld_p6_a ) { expander_operation(EXPANDER_OP_OR, 6); return 2; }
-OPHANDLER( orld_p7_a ) { expander_operation(EXPANDER_OP_OR, 7); return 2; }
-
-OPHANDLER( outl_bus_a ) { bus_w(m_a); return 2; }
-OPHANDLER( outl_p0_a ) { bus_w(m_dbbo = m_a); return 2; }
-OPHANDLER( outl_p1_a ) { port_w(1, m_p1 = m_a); return 2; }
-OPHANDLER( outl_p2_a ) { uint8_t mask = p2_mask(); port_w(2, m_p2 = (m_p2 & ~mask) | (m_a & mask)); return 2; }
+OPHANDLER( inc_a ) { burn_cycles(1); m_a++; }
+OPHANDLER( inc_r0 ) { burn_cycles(1); R0++; }
+OPHANDLER( inc_r1 ) { burn_cycles(1); R1++; }
+OPHANDLER( inc_r2 ) { burn_cycles(1); R2++; }
+OPHANDLER( inc_r3 ) { burn_cycles(1); R3++; }
+OPHANDLER( inc_r4 ) { burn_cycles(1); R4++; }
+OPHANDLER( inc_r5 ) { burn_cycles(1); R5++; }
+OPHANDLER( inc_r6 ) { burn_cycles(1); R6++; }
+OPHANDLER( inc_r7 ) { burn_cycles(1); R7++; }
+OPHANDLER( inc_xr0 ) { burn_cycles(1); ram_w(R0, ram_r(R0) + 1); }
+OPHANDLER( inc_xr1 ) { burn_cycles(1); ram_w(R1, ram_r(R1) + 1); }
+
+OPHANDLER( jb_0 ) { burn_cycles(2); execute_jcc((m_a & 0x01) != 0); }
+OPHANDLER( jb_1 ) { burn_cycles(2); execute_jcc((m_a & 0x02) != 0); }
+OPHANDLER( jb_2 ) { burn_cycles(2); execute_jcc((m_a & 0x04) != 0); }
+OPHANDLER( jb_3 ) { burn_cycles(2); execute_jcc((m_a & 0x08) != 0); }
+OPHANDLER( jb_4 ) { burn_cycles(2); execute_jcc((m_a & 0x10) != 0); }
+OPHANDLER( jb_5 ) { burn_cycles(2); execute_jcc((m_a & 0x20) != 0); }
+OPHANDLER( jb_6 ) { burn_cycles(2); execute_jcc((m_a & 0x40) != 0); }
+OPHANDLER( jb_7 ) { burn_cycles(2); execute_jcc((m_a & 0x80) != 0); }
+OPHANDLER( jc ) { burn_cycles(2); execute_jcc((m_psw & C_FLAG) != 0); }
+OPHANDLER( jf0 ) { burn_cycles(2); execute_jcc((m_psw & F_FLAG) != 0); }
+OPHANDLER( jf1 ) { burn_cycles(2); execute_jcc(m_f1); }
+OPHANDLER( jnc ) { burn_cycles(2); execute_jcc((m_psw & C_FLAG) == 0); }
+OPHANDLER( jni ) { burn_cycles(2); m_irq_polled = (m_irq_state == 0); execute_jcc(m_irq_state != 0); }
+OPHANDLER( jnibf ) { burn_cycles(2); m_irq_polled = (m_sts & STS_IBF) != 0; execute_jcc((m_sts & STS_IBF) == 0); }
+OPHANDLER( jnt_0 ) { burn_cycles(2); execute_jcc(test_r(0) == 0); }
+OPHANDLER( jnt_1 ) { burn_cycles(2); execute_jcc(test_r(1) == 0); }
+OPHANDLER( jnz ) { burn_cycles(2); execute_jcc(m_a != 0); }
+OPHANDLER( jobf ) { burn_cycles(2); execute_jcc((m_sts & STS_OBF) != 0); }
+OPHANDLER( jtf ) { burn_cycles(2); execute_jcc(m_timer_flag); m_timer_flag = false; }
+OPHANDLER( jt_0 ) { burn_cycles(2); execute_jcc(test_r(0) != 0); }
+OPHANDLER( jt_1 ) { burn_cycles(2); execute_jcc(test_r(1) != 0); }
+OPHANDLER( jz ) { burn_cycles(2); execute_jcc(m_a == 0); }
+
+OPHANDLER( jmp_0 ) { burn_cycles(2); execute_jmp(argument_fetch() | 0x000); }
+OPHANDLER( jmp_1 ) { burn_cycles(2); execute_jmp(argument_fetch() | 0x100); }
+OPHANDLER( jmp_2 ) { burn_cycles(2); execute_jmp(argument_fetch() | 0x200); }
+OPHANDLER( jmp_3 ) { burn_cycles(2); execute_jmp(argument_fetch() | 0x300); }
+OPHANDLER( jmp_4 ) { burn_cycles(2); execute_jmp(argument_fetch() | 0x400); }
+OPHANDLER( jmp_5 ) { burn_cycles(2); execute_jmp(argument_fetch() | 0x500); }
+OPHANDLER( jmp_6 ) { burn_cycles(2); execute_jmp(argument_fetch() | 0x600); }
+OPHANDLER( jmp_7 ) { burn_cycles(2); execute_jmp(argument_fetch() | 0x700); }
+OPHANDLER( jmpp_xa ) { burn_cycles(2); m_pc &= 0xf00; m_pc |= program_r(m_pc | m_a); }
+
+OPHANDLER( mov_a_n ) { burn_cycles(2); m_a = argument_fetch(); }
+OPHANDLER( mov_a_psw ) { burn_cycles(1); m_a = m_psw | 0x08; }
+OPHANDLER( mov_a_r0 ) { burn_cycles(1); m_a = R0; }
+OPHANDLER( mov_a_r1 ) { burn_cycles(1); m_a = R1; }
+OPHANDLER( mov_a_r2 ) { burn_cycles(1); m_a = R2; }
+OPHANDLER( mov_a_r3 ) { burn_cycles(1); m_a = R3; }
+OPHANDLER( mov_a_r4 ) { burn_cycles(1); m_a = R4; }
+OPHANDLER( mov_a_r5 ) { burn_cycles(1); m_a = R5; }
+OPHANDLER( mov_a_r6 ) { burn_cycles(1); m_a = R6; }
+OPHANDLER( mov_a_r7 ) { burn_cycles(1); m_a = R7; }
+OPHANDLER( mov_a_xr0 ) { burn_cycles(1); m_a = ram_r(R0); }
+OPHANDLER( mov_a_xr1 ) { burn_cycles(1); m_a = ram_r(R1); }
+OPHANDLER( mov_a_t ) { burn_cycles(1); m_a = m_timer; }
+
+OPHANDLER( mov_psw_a ) { burn_cycles(1); m_psw = m_a & ~0x08; update_regptr(); }
+OPHANDLER( mov_sts_a ) { burn_cycles(1); m_sts = (m_sts & 0x0f) | (m_a & 0xf0); }
+OPHANDLER( mov_r0_a ) { burn_cycles(1); R0 = m_a; }
+OPHANDLER( mov_r1_a ) { burn_cycles(1); R1 = m_a; }
+OPHANDLER( mov_r2_a ) { burn_cycles(1); R2 = m_a; }
+OPHANDLER( mov_r3_a ) { burn_cycles(1); R3 = m_a; }
+OPHANDLER( mov_r4_a ) { burn_cycles(1); R4 = m_a; }
+OPHANDLER( mov_r5_a ) { burn_cycles(1); R5 = m_a; }
+OPHANDLER( mov_r6_a ) { burn_cycles(1); R6 = m_a; }
+OPHANDLER( mov_r7_a ) { burn_cycles(1); R7 = m_a; }
+OPHANDLER( mov_r0_n ) { burn_cycles(2); R0 = argument_fetch(); }
+OPHANDLER( mov_r1_n ) { burn_cycles(2); R1 = argument_fetch(); }
+OPHANDLER( mov_r2_n ) { burn_cycles(2); R2 = argument_fetch(); }
+OPHANDLER( mov_r3_n ) { burn_cycles(2); R3 = argument_fetch(); }
+OPHANDLER( mov_r4_n ) { burn_cycles(2); R4 = argument_fetch(); }
+OPHANDLER( mov_r5_n ) { burn_cycles(2); R5 = argument_fetch(); }
+OPHANDLER( mov_r6_n ) { burn_cycles(2); R6 = argument_fetch(); }
+OPHANDLER( mov_r7_n ) { burn_cycles(2); R7 = argument_fetch(); }
+OPHANDLER( mov_t_a ) { burn_cycles(1); m_timer = m_a; }
+OPHANDLER( mov_xr0_a ) { burn_cycles(1); ram_w(R0, m_a); }
+OPHANDLER( mov_xr1_a ) { burn_cycles(1); ram_w(R1, m_a); }
+OPHANDLER( mov_xr0_n ) { burn_cycles(2); ram_w(R0, argument_fetch()); }
+OPHANDLER( mov_xr1_n ) { burn_cycles(2); ram_w(R1, argument_fetch()); }
+
+OPHANDLER( movd_a_p4 ) { burn_cycles(2); expander_operation(EXPANDER_OP_READ, 4); }
+OPHANDLER( movd_a_p5 ) { burn_cycles(2); expander_operation(EXPANDER_OP_READ, 5); }
+OPHANDLER( movd_a_p6 ) { burn_cycles(2); expander_operation(EXPANDER_OP_READ, 6); }
+OPHANDLER( movd_a_p7 ) { burn_cycles(2); expander_operation(EXPANDER_OP_READ, 7); }
+OPHANDLER( movd_p4_a ) { burn_cycles(2); expander_operation(EXPANDER_OP_WRITE, 4); }
+OPHANDLER( movd_p5_a ) { burn_cycles(2); expander_operation(EXPANDER_OP_WRITE, 5); }
+OPHANDLER( movd_p6_a ) { burn_cycles(2); expander_operation(EXPANDER_OP_WRITE, 6); }
+OPHANDLER( movd_p7_a ) { burn_cycles(2); expander_operation(EXPANDER_OP_WRITE, 7); }
+
+OPHANDLER( movp_a_xa ) { burn_cycles(2); m_a = program_r((m_pc & 0xf00) | m_a); }
+OPHANDLER( movp3_a_xa ) { burn_cycles(2); m_a = program_r(0x300 | m_a); }
+
+OPHANDLER( movx_a_xr0 ) { burn_cycles(2); m_a = ext_r(R0); }
+OPHANDLER( movx_a_xr1 ) { burn_cycles(2); m_a = ext_r(R1); }
+OPHANDLER( movx_xr0_a ) { burn_cycles(2); ext_w(R0, m_a); }
+OPHANDLER( movx_xr1_a ) { burn_cycles(2); ext_w(R1, m_a); }
+
+OPHANDLER( nop ) { burn_cycles(1); }
+
+OPHANDLER( orl_a_r0 ) { burn_cycles(1); m_a |= R0; }
+OPHANDLER( orl_a_r1 ) { burn_cycles(1); m_a |= R1; }
+OPHANDLER( orl_a_r2 ) { burn_cycles(1); m_a |= R2; }
+OPHANDLER( orl_a_r3 ) { burn_cycles(1); m_a |= R3; }
+OPHANDLER( orl_a_r4 ) { burn_cycles(1); m_a |= R4; }
+OPHANDLER( orl_a_r5 ) { burn_cycles(1); m_a |= R5; }
+OPHANDLER( orl_a_r6 ) { burn_cycles(1); m_a |= R6; }
+OPHANDLER( orl_a_r7 ) { burn_cycles(1); m_a |= R7; }
+OPHANDLER( orl_a_xr0 ) { burn_cycles(1); m_a |= ram_r(R0); }
+OPHANDLER( orl_a_xr1 ) { burn_cycles(1); m_a |= ram_r(R1); }
+OPHANDLER( orl_a_n ) { burn_cycles(2); m_a |= argument_fetch(); }
+
+OPHANDLER( orl_bus_n ) { burn_cycles(2); bus_w(bus_r() | argument_fetch()); }
+OPHANDLER( orl_p1_n ) { burn_cycles(2); port_w(1, m_p1 |= argument_fetch()); }
+OPHANDLER( orl_p2_n ) { burn_cycles(2); port_w(2, m_p2 |= argument_fetch() & p2_mask()); }
+OPHANDLER( orld_p4_a ) { burn_cycles(2); expander_operation(EXPANDER_OP_OR, 4); }
+OPHANDLER( orld_p5_a ) { burn_cycles(2); expander_operation(EXPANDER_OP_OR, 5); }
+OPHANDLER( orld_p6_a ) { burn_cycles(2); expander_operation(EXPANDER_OP_OR, 6); }
+OPHANDLER( orld_p7_a ) { burn_cycles(2); expander_operation(EXPANDER_OP_OR, 7); }
+
+OPHANDLER( outl_bus_a ) { burn_cycles(2); bus_w(m_a); }
+OPHANDLER( outl_p0_a ) { burn_cycles(2); bus_w(m_dbbo = m_a); }
+OPHANDLER( outl_p1_a ) { burn_cycles(2); port_w(1, m_p1 = m_a); }
+OPHANDLER( outl_p2_a ) { burn_cycles(2); u8 mask = p2_mask(); port_w(2, m_p2 = (m_p2 & ~mask) | (m_a & mask)); }
OPHANDLER( out_dbb_a )
{
- /* copy to the DBBO and update the bit in STS */
+ burn_cycles(1);
+
+ // copy to the DBBO and update the bit in STS
m_dbbo = m_a;
m_sts |= STS_OBF;
- /* if P2 flags are enabled, update the state of P2 */
+ // if P2 flags are enabled, update the state of P2
if (m_flags_enabled && (m_p2 & P2_OBF) == 0)
port_w(2, m_p2 |= P2_OBF);
- return 2;
}
-
-OPHANDLER( ret ) { pull_pc(); return 2; }
+OPHANDLER( ret ) { burn_cycles(2); pull_pc(); }
OPHANDLER( retr )
{
- pull_pc_psw();
+ burn_cycles(2);
- /* implicitly clear the IRQ in progress flip flop and re-check interrupts */
+ // implicitly clear the IRQ in progress flip flop
m_irq_in_progress = false;
- return 2 + check_irqs();
+ pull_pc_psw();
}
-OPHANDLER( rl_a ) { m_a = (m_a << 1) | (m_a >> 7); return 1; }
-OPHANDLER( rlc_a ) { uint8_t newc = m_a & C_FLAG; m_a = (m_a << 1) | (m_psw >> 7); m_psw = (m_psw & ~C_FLAG) | newc; return 1; }
+OPHANDLER( rl_a ) { burn_cycles(1); m_a = (m_a << 1) | (m_a >> 7); }
+OPHANDLER( rlc_a ) { burn_cycles(1); u8 newc = m_a & C_FLAG; m_a = (m_a << 1) | (m_psw >> 7); m_psw = (m_psw & ~C_FLAG) | newc; }
-OPHANDLER( rr_a ) { m_a = (m_a >> 1) | (m_a << 7); return 1; }
-OPHANDLER( rrc_a ) { uint8_t newc = (m_a << 7) & C_FLAG; m_a = (m_a >> 1) | (m_psw & C_FLAG); m_psw = (m_psw & ~C_FLAG) | newc; return 1; }
+OPHANDLER( rr_a ) { burn_cycles(1); m_a = (m_a >> 1) | (m_a << 7); }
+OPHANDLER( rrc_a ) { burn_cycles(1); u8 newc = (m_a << 7) & C_FLAG; m_a = (m_a >> 1) | (m_psw & C_FLAG); m_psw = (m_psw & ~C_FLAG) | newc; }
-OPHANDLER( sel_mb0 ) { m_a11 = 0x000; return 1; }
-OPHANDLER( sel_mb1 ) { m_a11 = 0x800; return 1; }
+OPHANDLER( sel_mb0 ) { burn_cycles(1); m_a11 = 0x000; }
+OPHANDLER( sel_mb1 ) { burn_cycles(1); m_a11 = 0x800; }
-OPHANDLER( sel_rb0 ) { m_psw &= ~B_FLAG; update_regptr(); return 1; }
-OPHANDLER( sel_rb1 ) { m_psw |= B_FLAG; update_regptr(); return 1; }
+OPHANDLER( sel_rb0 ) { burn_cycles(1); m_psw &= ~B_FLAG; update_regptr(); }
+OPHANDLER( sel_rb1 ) { burn_cycles(1); m_psw |= B_FLAG; update_regptr(); }
-OPHANDLER( stop_tcnt ) { m_timecount_enabled = 0; return 1; }
+OPHANDLER( stop_tcnt ) { burn_cycles(1); m_timecount_enabled = 0; }
+OPHANDLER( strt_t ) { burn_cycles(1); m_timecount_enabled = TIMER_ENABLED; m_prescaler = 0; }
+OPHANDLER( strt_cnt )
+{
+ burn_cycles(1);
+ if (!(m_timecount_enabled & COUNTER_ENABLED))
+ m_t1_history = test_r(1);
-OPHANDLER( strt_cnt ) { m_timecount_enabled = COUNTER_ENABLED; m_t1_history = test_r(1); return 1; }
-OPHANDLER( strt_t ) { m_timecount_enabled = TIMER_ENABLED; m_prescaler = 0; return 1; }
+ m_timecount_enabled = COUNTER_ENABLED;
+}
-OPHANDLER( swap_a ) { m_a = (m_a << 4) | (m_a >> 4); return 1; }
+OPHANDLER( swap_a ) { burn_cycles(1); m_a = (m_a << 4) | (m_a >> 4); }
-OPHANDLER( xch_a_r0 ) { uint8_t tmp = m_a; m_a = R0; R0 = tmp; return 1; }
-OPHANDLER( xch_a_r1 ) { uint8_t tmp = m_a; m_a = R1; R1 = tmp; return 1; }
-OPHANDLER( xch_a_r2 ) { uint8_t tmp = m_a; m_a = R2; R2 = tmp; return 1; }
-OPHANDLER( xch_a_r3 ) { uint8_t tmp = m_a; m_a = R3; R3 = tmp; return 1; }
-OPHANDLER( xch_a_r4 ) { uint8_t tmp = m_a; m_a = R4; R4 = tmp; return 1; }
-OPHANDLER( xch_a_r5 ) { uint8_t tmp = m_a; m_a = R5; R5 = tmp; return 1; }
-OPHANDLER( xch_a_r6 ) { uint8_t tmp = m_a; m_a = R6; R6 = tmp; return 1; }
-OPHANDLER( xch_a_r7 ) { uint8_t tmp = m_a; m_a = R7; R7 = tmp; return 1; }
-OPHANDLER( xch_a_xr0 ) { uint8_t tmp = m_a; m_a = ram_r(R0); ram_w(R0, tmp); return 1; }
-OPHANDLER( xch_a_xr1 ) { uint8_t tmp = m_a; m_a = ram_r(R1); ram_w(R1, tmp); return 1; }
+OPHANDLER( xch_a_r0 ) { burn_cycles(1); u8 tmp = m_a; m_a = R0; R0 = tmp; }
+OPHANDLER( xch_a_r1 ) { burn_cycles(1); u8 tmp = m_a; m_a = R1; R1 = tmp; }
+OPHANDLER( xch_a_r2 ) { burn_cycles(1); u8 tmp = m_a; m_a = R2; R2 = tmp; }
+OPHANDLER( xch_a_r3 ) { burn_cycles(1); u8 tmp = m_a; m_a = R3; R3 = tmp; }
+OPHANDLER( xch_a_r4 ) { burn_cycles(1); u8 tmp = m_a; m_a = R4; R4 = tmp; }
+OPHANDLER( xch_a_r5 ) { burn_cycles(1); u8 tmp = m_a; m_a = R5; R5 = tmp; }
+OPHANDLER( xch_a_r6 ) { burn_cycles(1); u8 tmp = m_a; m_a = R6; R6 = tmp; }
+OPHANDLER( xch_a_r7 ) { burn_cycles(1); u8 tmp = m_a; m_a = R7; R7 = tmp; }
+OPHANDLER( xch_a_xr0 ) { burn_cycles(1); u8 tmp = m_a; m_a = ram_r(R0); ram_w(R0, tmp); }
+OPHANDLER( xch_a_xr1 ) { burn_cycles(1); u8 tmp = m_a; m_a = ram_r(R1); ram_w(R1, tmp); }
-OPHANDLER( xchd_a_xr0 ) { uint8_t oldram = ram_r(R0); ram_w(R0, (oldram & 0xf0) | (m_a & 0x0f)); m_a = (m_a & 0xf0) | (oldram & 0x0f); return 1; }
-OPHANDLER( xchd_a_xr1 ) { uint8_t oldram = ram_r(R1); ram_w(R1, (oldram & 0xf0) | (m_a & 0x0f)); m_a = (m_a & 0xf0) | (oldram & 0x0f); return 1; }
+OPHANDLER( xchd_a_xr0 ) { burn_cycles(1); u8 oldram = ram_r(R0); ram_w(R0, (oldram & 0xf0) | (m_a & 0x0f)); m_a = (m_a & 0xf0) | (oldram & 0x0f); }
+OPHANDLER( xchd_a_xr1 ) { burn_cycles(1); u8 oldram = ram_r(R1); ram_w(R1, (oldram & 0xf0) | (m_a & 0x0f)); m_a = (m_a & 0xf0) | (oldram & 0x0f); }
-OPHANDLER( xrl_a_r0 ) { m_a ^= R0; return 1; }
-OPHANDLER( xrl_a_r1 ) { m_a ^= R1; return 1; }
-OPHANDLER( xrl_a_r2 ) { m_a ^= R2; return 1; }
-OPHANDLER( xrl_a_r3 ) { m_a ^= R3; return 1; }
-OPHANDLER( xrl_a_r4 ) { m_a ^= R4; return 1; }
-OPHANDLER( xrl_a_r5 ) { m_a ^= R5; return 1; }
-OPHANDLER( xrl_a_r6 ) { m_a ^= R6; return 1; }
-OPHANDLER( xrl_a_r7 ) { m_a ^= R7; return 1; }
-OPHANDLER( xrl_a_xr0 ) { m_a ^= ram_r(R0); return 1; }
-OPHANDLER( xrl_a_xr1 ) { m_a ^= ram_r(R1); return 1; }
-OPHANDLER( xrl_a_n ) { m_a ^= argument_fetch(); return 2; }
+OPHANDLER( xrl_a_r0 ) { burn_cycles(1); m_a ^= R0; }
+OPHANDLER( xrl_a_r1 ) { burn_cycles(1); m_a ^= R1; }
+OPHANDLER( xrl_a_r2 ) { burn_cycles(1); m_a ^= R2; }
+OPHANDLER( xrl_a_r3 ) { burn_cycles(1); m_a ^= R3; }
+OPHANDLER( xrl_a_r4 ) { burn_cycles(1); m_a ^= R4; }
+OPHANDLER( xrl_a_r5 ) { burn_cycles(1); m_a ^= R5; }
+OPHANDLER( xrl_a_r6 ) { burn_cycles(1); m_a ^= R6; }
+OPHANDLER( xrl_a_r7 ) { burn_cycles(1); m_a ^= R7; }
+OPHANDLER( xrl_a_xr0 ) { burn_cycles(1); m_a ^= ram_r(R0); }
+OPHANDLER( xrl_a_xr1 ) { burn_cycles(1); m_a ^= ram_r(R1); }
+OPHANDLER( xrl_a_n ) { burn_cycles(2); m_a ^= argument_fetch(); }
-/***************************************************************************
+/*******************************************************************************
OPCODE TABLES
-***************************************************************************/
+*******************************************************************************/
#define OP(_a) &mcs48_cpu_device::_a
const mcs48_cpu_device::mcs48_ophandler mcs48_cpu_device::s_mcs48_opcodes[256] =
{
- OP(nop), OP(illegal), OP(outl_bus_a),OP(add_a_n), OP(jmp_0), OP(en_i), OP(illegal), OP(dec_a), /* 00 */
+ OP(nop), OP(illegal), OP(outl_bus_a),OP(add_a_n), OP(jmp_0), OP(en_i), OP(illegal), OP(dec_a), // 00
OP(ins_a_bus), OP(in_a_p1), OP(in_a_p2), OP(illegal), OP(movd_a_p4), OP(movd_a_p5), OP(movd_a_p6), OP(movd_a_p7),
- OP(inc_xr0), OP(inc_xr1), OP(jb_0), OP(adc_a_n), OP(call_0), OP(dis_i), OP(jtf), OP(inc_a), /* 10 */
+ OP(inc_xr0), OP(inc_xr1), OP(jb_0), OP(adc_a_n), OP(call_0), OP(dis_i), OP(jtf), OP(inc_a), // 10
OP(inc_r0), OP(inc_r1), OP(inc_r2), OP(inc_r3), OP(inc_r4), OP(inc_r5), OP(inc_r6), OP(inc_r7),
- OP(xch_a_xr0), OP(xch_a_xr1), OP(illegal), OP(mov_a_n), OP(jmp_1), OP(en_tcnti), OP(jnt_0), OP(clr_a), /* 20 */
+ OP(xch_a_xr0), OP(xch_a_xr1), OP(illegal), OP(mov_a_n), OP(jmp_1), OP(en_tcnti), OP(jnt_0), OP(clr_a), // 20
OP(xch_a_r0), OP(xch_a_r1), OP(xch_a_r2), OP(xch_a_r3), OP(xch_a_r4), OP(xch_a_r5), OP(xch_a_r6), OP(xch_a_r7),
- OP(xchd_a_xr0), OP(xchd_a_xr1), OP(jb_1), OP(illegal), OP(call_1), OP(dis_tcnti), OP(jt_0), OP(cpl_a), /* 30 */
+ OP(xchd_a_xr0), OP(xchd_a_xr1), OP(jb_1), OP(illegal), OP(call_1), OP(dis_tcnti), OP(jt_0), OP(cpl_a), // 30
OP(illegal), OP(outl_p1_a), OP(outl_p2_a), OP(illegal), OP(movd_p4_a), OP(movd_p5_a), OP(movd_p6_a), OP(movd_p7_a),
- OP(orl_a_xr0), OP(orl_a_xr1), OP(mov_a_t), OP(orl_a_n), OP(jmp_2), OP(strt_cnt), OP(jnt_1), OP(swap_a), /* 40 */
+ OP(orl_a_xr0), OP(orl_a_xr1), OP(mov_a_t), OP(orl_a_n), OP(jmp_2), OP(strt_cnt), OP(jnt_1), OP(swap_a), // 40
OP(orl_a_r0), OP(orl_a_r1), OP(orl_a_r2), OP(orl_a_r3), OP(orl_a_r4), OP(orl_a_r5), OP(orl_a_r6), OP(orl_a_r7),
- OP(anl_a_xr0), OP(anl_a_xr1), OP(jb_2), OP(anl_a_n), OP(call_2), OP(strt_t), OP(jt_1), OP(da_a), /* 50 */
+ OP(anl_a_xr0), OP(anl_a_xr1), OP(jb_2), OP(anl_a_n), OP(call_2), OP(strt_t), OP(jt_1), OP(da_a), // 50
OP(anl_a_r0), OP(anl_a_r1), OP(anl_a_r2), OP(anl_a_r3), OP(anl_a_r4), OP(anl_a_r5), OP(anl_a_r6), OP(anl_a_r7),
- OP(add_a_xr0), OP(add_a_xr1), OP(mov_t_a), OP(illegal), OP(jmp_3), OP(stop_tcnt), OP(illegal), OP(rrc_a), /* 60 */
+ OP(add_a_xr0), OP(add_a_xr1), OP(mov_t_a), OP(illegal), OP(jmp_3), OP(stop_tcnt), OP(illegal), OP(rrc_a), // 60
OP(add_a_r0), OP(add_a_r1), OP(add_a_r2), OP(add_a_r3), OP(add_a_r4), OP(add_a_r5), OP(add_a_r6), OP(add_a_r7),
- OP(adc_a_xr0), OP(adc_a_xr1), OP(jb_3), OP(illegal), OP(call_3), OP(ent0_clk), OP(jf1), OP(rr_a), /* 70 */
+ OP(adc_a_xr0), OP(adc_a_xr1), OP(jb_3), OP(illegal), OP(call_3), OP(ent0_clk), OP(jf1), OP(rr_a), // 70
OP(adc_a_r0), OP(adc_a_r1), OP(adc_a_r2), OP(adc_a_r3), OP(adc_a_r4), OP(adc_a_r5), OP(adc_a_r6), OP(adc_a_r7),
- OP(movx_a_xr0), OP(movx_a_xr1), OP(illegal), OP(ret), OP(jmp_4), OP(clr_f0), OP(jni), OP(illegal), /* 80 */
+ OP(movx_a_xr0), OP(movx_a_xr1), OP(illegal), OP(ret), OP(jmp_4), OP(clr_f0), OP(jni), OP(illegal), // 80
OP(orl_bus_n), OP(orl_p1_n), OP(orl_p2_n), OP(illegal), OP(orld_p4_a), OP(orld_p5_a), OP(orld_p6_a), OP(orld_p7_a),
- OP(movx_xr0_a), OP(movx_xr1_a), OP(jb_4), OP(retr), OP(call_4), OP(cpl_f0), OP(jnz), OP(clr_c), /* 90 */
+ OP(movx_xr0_a), OP(movx_xr1_a), OP(jb_4), OP(retr), OP(call_4), OP(cpl_f0), OP(jnz), OP(clr_c), // 90
OP(anl_bus_n), OP(anl_p1_n), OP(anl_p2_n), OP(illegal), OP(anld_p4_a), OP(anld_p5_a), OP(anld_p6_a), OP(anld_p7_a),
- OP(mov_xr0_a), OP(mov_xr1_a), OP(illegal), OP(movp_a_xa), OP(jmp_5), OP(clr_f1), OP(illegal), OP(cpl_c), /* A0 */
+ OP(mov_xr0_a), OP(mov_xr1_a), OP(illegal), OP(movp_a_xa), OP(jmp_5), OP(clr_f1), OP(illegal), OP(cpl_c), // A0
OP(mov_r0_a), OP(mov_r1_a), OP(mov_r2_a), OP(mov_r3_a), OP(mov_r4_a), OP(mov_r5_a), OP(mov_r6_a), OP(mov_r7_a),
- OP(mov_xr0_n), OP(mov_xr1_n), OP(jb_5), OP(jmpp_xa), OP(call_5), OP(cpl_f1), OP(jf0), OP(illegal), /* B0 */
+ OP(mov_xr0_n), OP(mov_xr1_n), OP(jb_5), OP(jmpp_xa), OP(call_5), OP(cpl_f1), OP(jf0), OP(illegal), // B0
OP(mov_r0_n), OP(mov_r1_n), OP(mov_r2_n), OP(mov_r3_n), OP(mov_r4_n), OP(mov_r5_n), OP(mov_r6_n), OP(mov_r7_n),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(jmp_6), OP(sel_rb0), OP(jz), OP(mov_a_psw), /* C0 */
+ OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(jmp_6), OP(sel_rb0), OP(jz), OP(mov_a_psw), // C0
OP(dec_r0), OP(dec_r1), OP(dec_r2), OP(dec_r3), OP(dec_r4), OP(dec_r5), OP(dec_r6), OP(dec_r7),
- OP(xrl_a_xr0), OP(xrl_a_xr1), OP(jb_6), OP(xrl_a_n), OP(call_6), OP(sel_rb1), OP(illegal), OP(mov_psw_a), /* D0 */
+ OP(xrl_a_xr0), OP(xrl_a_xr1), OP(jb_6), OP(xrl_a_n), OP(call_6), OP(sel_rb1), OP(illegal), OP(mov_psw_a), // D0
OP(xrl_a_r0), OP(xrl_a_r1), OP(xrl_a_r2), OP(xrl_a_r3), OP(xrl_a_r4), OP(xrl_a_r5), OP(xrl_a_r6), OP(xrl_a_r7),
- OP(illegal), OP(illegal), OP(illegal), OP(movp3_a_xa),OP(jmp_7), OP(sel_mb0), OP(jnc), OP(rl_a), /* E0 */
+ OP(illegal), OP(illegal), OP(illegal), OP(movp3_a_xa),OP(jmp_7), OP(sel_mb0), OP(jnc), OP(rl_a), // E0
OP(djnz_r0), OP(djnz_r1), OP(djnz_r2), OP(djnz_r3), OP(djnz_r4), OP(djnz_r5), OP(djnz_r6), OP(djnz_r7),
- OP(mov_a_xr0), OP(mov_a_xr1), OP(jb_7), OP(illegal), OP(call_7), OP(sel_mb1), OP(jc), OP(rlc_a), /* F0 */
+ OP(mov_a_xr0), OP(mov_a_xr1), OP(jb_7), OP(illegal), OP(call_7), OP(sel_mb1), OP(jc), OP(rlc_a), // F0
OP(mov_a_r0), OP(mov_a_r1), OP(mov_a_r2), OP(mov_a_r3), OP(mov_a_r4), OP(mov_a_r5), OP(mov_a_r6), OP(mov_a_r7)
};
const mcs48_cpu_device::mcs48_ophandler mcs48_cpu_device::s_upi41_opcodes[256] =
{
- OP(nop), OP(illegal), OP(out_dbb_a), OP(add_a_n), OP(jmp_0), OP(en_i), OP(illegal), OP(dec_a), /* 00 */
+ OP(nop), OP(illegal), OP(out_dbb_a), OP(add_a_n), OP(jmp_0), OP(en_i), OP(illegal), OP(dec_a), // 00
OP(illegal), OP(in_a_p1), OP(in_a_p2), OP(illegal), OP(movd_a_p4), OP(movd_a_p5), OP(movd_a_p6), OP(movd_a_p7),
- OP(inc_xr0), OP(inc_xr1), OP(jb_0), OP(adc_a_n), OP(call_0), OP(dis_i), OP(jtf), OP(inc_a), /* 10 */
+ OP(inc_xr0), OP(inc_xr1), OP(jb_0), OP(adc_a_n), OP(call_0), OP(dis_i), OP(jtf), OP(inc_a), // 10
OP(inc_r0), OP(inc_r1), OP(inc_r2), OP(inc_r3), OP(inc_r4), OP(inc_r5), OP(inc_r6), OP(inc_r7),
- OP(xch_a_xr0), OP(xch_a_xr1), OP(in_a_dbb), OP(mov_a_n), OP(jmp_1), OP(en_tcnti), OP(jnt_0), OP(clr_a), /* 20 */
+ OP(xch_a_xr0), OP(xch_a_xr1), OP(in_a_dbb), OP(mov_a_n), OP(jmp_1), OP(en_tcnti), OP(jnt_0), OP(clr_a), // 20
OP(xch_a_r0), OP(xch_a_r1), OP(xch_a_r2), OP(xch_a_r3), OP(xch_a_r4), OP(xch_a_r5), OP(xch_a_r6), OP(xch_a_r7),
- OP(xchd_a_xr0), OP(xchd_a_xr1), OP(jb_1), OP(illegal), OP(call_1), OP(dis_tcnti), OP(jt_0), OP(cpl_a), /* 30 */
+ OP(xchd_a_xr0), OP(xchd_a_xr1), OP(jb_1), OP(illegal), OP(call_1), OP(dis_tcnti), OP(jt_0), OP(cpl_a), // 30
OP(illegal), OP(outl_p1_a), OP(outl_p2_a), OP(illegal), OP(movd_p4_a), OP(movd_p5_a), OP(movd_p6_a), OP(movd_p7_a),
- OP(orl_a_xr0), OP(orl_a_xr1), OP(mov_a_t), OP(orl_a_n), OP(jmp_2), OP(strt_cnt), OP(jnt_1), OP(swap_a), /* 40 */
+ OP(orl_a_xr0), OP(orl_a_xr1), OP(mov_a_t), OP(orl_a_n), OP(jmp_2), OP(strt_cnt), OP(jnt_1), OP(swap_a), // 40
OP(orl_a_r0), OP(orl_a_r1), OP(orl_a_r2), OP(orl_a_r3), OP(orl_a_r4), OP(orl_a_r5), OP(orl_a_r6), OP(orl_a_r7),
- OP(anl_a_xr0), OP(anl_a_xr1), OP(jb_2), OP(anl_a_n), OP(call_2), OP(strt_t), OP(jt_1), OP(da_a), /* 50 */
+ OP(anl_a_xr0), OP(anl_a_xr1), OP(jb_2), OP(anl_a_n), OP(call_2), OP(strt_t), OP(jt_1), OP(da_a), // 50
OP(anl_a_r0), OP(anl_a_r1), OP(anl_a_r2), OP(anl_a_r3), OP(anl_a_r4), OP(anl_a_r5), OP(anl_a_r6), OP(anl_a_r7),
- OP(add_a_xr0), OP(add_a_xr1), OP(mov_t_a), OP(illegal), OP(jmp_3), OP(stop_tcnt), OP(illegal), OP(rrc_a), /* 60 */
+ OP(add_a_xr0), OP(add_a_xr1), OP(mov_t_a), OP(illegal), OP(jmp_3), OP(stop_tcnt), OP(illegal), OP(rrc_a), // 60
OP(add_a_r0), OP(add_a_r1), OP(add_a_r2), OP(add_a_r3), OP(add_a_r4), OP(add_a_r5), OP(add_a_r6), OP(add_a_r7),
- OP(adc_a_xr0), OP(adc_a_xr1), OP(jb_3), OP(illegal), OP(call_3), OP(illegal), OP(jf1), OP(rr_a), /* 70 */
+ OP(adc_a_xr0), OP(adc_a_xr1), OP(jb_3), OP(illegal), OP(call_3), OP(illegal), OP(jf1), OP(rr_a), // 70
OP(adc_a_r0), OP(adc_a_r1), OP(adc_a_r2), OP(adc_a_r3), OP(adc_a_r4), OP(adc_a_r5), OP(adc_a_r6), OP(adc_a_r7),
- OP(illegal), OP(illegal), OP(illegal), OP(ret), OP(jmp_4), OP(clr_f0), OP(jobf), OP(illegal), /* 80 */
+ OP(illegal), OP(illegal), OP(illegal), OP(ret), OP(jmp_4), OP(clr_f0), OP(jobf), OP(illegal), // 80
OP(illegal), OP(orl_p1_n), OP(orl_p2_n), OP(illegal), OP(orld_p4_a), OP(orld_p5_a), OP(orld_p6_a), OP(orld_p7_a),
- OP(mov_sts_a), OP(illegal), OP(jb_4), OP(retr), OP(call_4), OP(cpl_f0), OP(jnz), OP(clr_c), /* 90 */
+ OP(mov_sts_a), OP(illegal), OP(jb_4), OP(retr), OP(call_4), OP(cpl_f0), OP(jnz), OP(clr_c), // 90
OP(illegal), OP(anl_p1_n), OP(anl_p2_n), OP(illegal), OP(anld_p4_a), OP(anld_p5_a), OP(anld_p6_a), OP(anld_p7_a),
- OP(mov_xr0_a), OP(mov_xr1_a), OP(illegal), OP(movp_a_xa), OP(jmp_5), OP(clr_f1), OP(illegal), OP(cpl_c), /* A0 */
+ OP(mov_xr0_a), OP(mov_xr1_a), OP(illegal), OP(movp_a_xa), OP(jmp_5), OP(clr_f1), OP(illegal), OP(cpl_c), // A0
OP(mov_r0_a), OP(mov_r1_a), OP(mov_r2_a), OP(mov_r3_a), OP(mov_r4_a), OP(mov_r5_a), OP(mov_r6_a), OP(mov_r7_a),
- OP(mov_xr0_n), OP(mov_xr1_n), OP(jb_5), OP(jmpp_xa), OP(call_5), OP(cpl_f1), OP(jf0), OP(illegal), /* B0 */
+ OP(mov_xr0_n), OP(mov_xr1_n), OP(jb_5), OP(jmpp_xa), OP(call_5), OP(cpl_f1), OP(jf0), OP(illegal), // B0
OP(mov_r0_n), OP(mov_r1_n), OP(mov_r2_n), OP(mov_r3_n), OP(mov_r4_n), OP(mov_r5_n), OP(mov_r6_n), OP(mov_r7_n),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(jmp_6), OP(sel_rb0), OP(jz), OP(mov_a_psw), /* C0 */
+ OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(jmp_6), OP(sel_rb0), OP(jz), OP(mov_a_psw), // C0
OP(dec_r0), OP(dec_r1), OP(dec_r2), OP(dec_r3), OP(dec_r4), OP(dec_r5), OP(dec_r6), OP(dec_r7),
- OP(xrl_a_xr0), OP(xrl_a_xr1), OP(jb_6), OP(xrl_a_n), OP(call_6), OP(sel_rb1), OP(jnibf), OP(mov_psw_a), /* D0 */
+ OP(xrl_a_xr0), OP(xrl_a_xr1), OP(jb_6), OP(xrl_a_n), OP(call_6), OP(sel_rb1), OP(jnibf), OP(mov_psw_a), // D0
OP(xrl_a_r0), OP(xrl_a_r1), OP(xrl_a_r2), OP(xrl_a_r3), OP(xrl_a_r4), OP(xrl_a_r5), OP(xrl_a_r6), OP(xrl_a_r7),
- OP(illegal), OP(illegal), OP(illegal), OP(movp3_a_xa),OP(jmp_7), OP(en_dma), OP(jnc), OP(rl_a), /* E0 */
+ OP(illegal), OP(illegal), OP(illegal), OP(movp3_a_xa),OP(jmp_7), OP(en_dma), OP(jnc), OP(rl_a), // E0
OP(djnz_r0), OP(djnz_r1), OP(djnz_r2), OP(djnz_r3), OP(djnz_r4), OP(djnz_r5), OP(djnz_r6), OP(djnz_r7),
- OP(mov_a_xr0), OP(mov_a_xr1), OP(jb_7), OP(illegal), OP(call_7), OP(en_flags), OP(jc), OP(rlc_a), /* F0 */
+ OP(mov_a_xr0), OP(mov_a_xr1), OP(jb_7), OP(illegal), OP(call_7), OP(en_flags), OP(jc), OP(rlc_a), // F0
OP(mov_a_r0), OP(mov_a_r1), OP(mov_a_r2), OP(mov_a_r3), OP(mov_a_r4), OP(mov_a_r5), OP(mov_a_r6), OP(mov_a_r7)
};
const mcs48_cpu_device::mcs48_ophandler mcs48_cpu_device::s_i8021_opcodes[256] =
{
- OP(nop), OP(illegal), OP(illegal), OP(add_a_n), OP(jmp_0), OP(illegal), OP(illegal), OP(dec_a), /* 00 */
+ OP(nop), OP(illegal), OP(illegal), OP(add_a_n), OP(jmp_0), OP(illegal), OP(illegal), OP(dec_a), // 00
OP(in_a_p0), OP(in_a_p1), OP(in_a_p2), OP(illegal), OP(movd_a_p4), OP(movd_a_p5), OP(movd_a_p6), OP(movd_a_p7),
- OP(inc_xr0), OP(inc_xr1), OP(illegal), OP(adc_a_n), OP(call_0), OP(illegal), OP(jtf), OP(inc_a), /* 10 */
+ OP(inc_xr0), OP(inc_xr1), OP(illegal), OP(adc_a_n), OP(call_0), OP(illegal), OP(jtf), OP(inc_a), // 10
OP(inc_r0), OP(inc_r1), OP(inc_r2), OP(inc_r3), OP(inc_r4), OP(inc_r5), OP(inc_r6), OP(inc_r7),
- OP(xch_a_xr0), OP(xch_a_xr1), OP(illegal), OP(mov_a_n), OP(jmp_1), OP(illegal), OP(illegal), OP(clr_a), /* 20 */
+ OP(xch_a_xr0), OP(xch_a_xr1), OP(illegal), OP(mov_a_n), OP(jmp_1), OP(illegal), OP(illegal), OP(clr_a), // 20
OP(xch_a_r0), OP(xch_a_r1), OP(xch_a_r2), OP(xch_a_r3), OP(xch_a_r4), OP(xch_a_r5), OP(xch_a_r6), OP(xch_a_r7),
- OP(xchd_a_xr0), OP(xchd_a_xr1), OP(illegal), OP(illegal), OP(call_1), OP(illegal), OP(illegal), OP(cpl_a), /* 30 */
+ OP(xchd_a_xr0), OP(xchd_a_xr1), OP(illegal), OP(illegal), OP(call_1), OP(illegal), OP(illegal), OP(cpl_a), // 30
OP(illegal), OP(outl_p1_a), OP(outl_p2_a), OP(illegal), OP(movd_p4_a), OP(movd_p5_a), OP(movd_p6_a), OP(movd_p7_a),
- OP(orl_a_xr0), OP(orl_a_xr1), OP(mov_a_t), OP(orl_a_n), OP(jmp_2), OP(strt_cnt), OP(jnt_1), OP(swap_a), /* 40 */
+ OP(orl_a_xr0), OP(orl_a_xr1), OP(mov_a_t), OP(orl_a_n), OP(jmp_2), OP(strt_cnt), OP(jnt_1), OP(swap_a), // 40
OP(orl_a_r0), OP(orl_a_r1), OP(orl_a_r2), OP(orl_a_r3), OP(orl_a_r4), OP(orl_a_r5), OP(orl_a_r6), OP(orl_a_r7),
- OP(anl_a_xr0), OP(anl_a_xr1), OP(illegal), OP(anl_a_n), OP(call_2), OP(strt_t), OP(jt_1), OP(da_a), /* 50 */
+ OP(anl_a_xr0), OP(anl_a_xr1), OP(illegal), OP(anl_a_n), OP(call_2), OP(strt_t), OP(jt_1), OP(da_a), // 50
OP(anl_a_r0), OP(anl_a_r1), OP(anl_a_r2), OP(anl_a_r3), OP(anl_a_r4), OP(anl_a_r5), OP(anl_a_r6), OP(anl_a_r7),
- OP(add_a_xr0), OP(add_a_xr1), OP(mov_t_a), OP(illegal), OP(jmp_3), OP(stop_tcnt), OP(illegal), OP(rrc_a), /* 60 */
+ OP(add_a_xr0), OP(add_a_xr1), OP(mov_t_a), OP(illegal), OP(jmp_3), OP(stop_tcnt), OP(illegal), OP(rrc_a), // 60
OP(add_a_r0), OP(add_a_r1), OP(add_a_r2), OP(add_a_r3), OP(add_a_r4), OP(add_a_r5), OP(add_a_r6), OP(add_a_r7),
- OP(adc_a_xr0), OP(adc_a_xr1), OP(illegal), OP(illegal), OP(call_3), OP(illegal), OP(illegal), OP(rr_a), /* 70 */
+ OP(adc_a_xr0), OP(adc_a_xr1), OP(illegal), OP(illegal), OP(call_3), OP(illegal), OP(illegal), OP(rr_a), // 70
OP(adc_a_r0), OP(adc_a_r1), OP(adc_a_r2), OP(adc_a_r3), OP(adc_a_r4), OP(adc_a_r5), OP(adc_a_r6), OP(adc_a_r7),
- OP(illegal), OP(illegal), OP(illegal), OP(ret), OP(jmp_4), OP(illegal), OP(illegal), OP(illegal), /* 80 */
+ OP(illegal), OP(illegal), OP(illegal), OP(ret), OP(jmp_4), OP(illegal), OP(illegal), OP(illegal), // 80
OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(orld_p4_a), OP(orld_p5_a), OP(orld_p6_a), OP(orld_p7_a),
- OP(outl_p0_a), OP(illegal), OP(illegal), OP(illegal), OP(call_4), OP(illegal), OP(jnz), OP(clr_c), /* 90 */
+ OP(outl_p0_a), OP(illegal), OP(illegal), OP(illegal), OP(call_4), OP(illegal), OP(jnz), OP(clr_c), // 90
OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(anld_p4_a), OP(anld_p5_a), OP(anld_p6_a), OP(anld_p7_a),
- OP(mov_xr0_a), OP(mov_xr1_a), OP(illegal), OP(movp_a_xa), OP(jmp_5), OP(illegal), OP(illegal), OP(cpl_c), /* A0 */
+ OP(mov_xr0_a), OP(mov_xr1_a), OP(illegal), OP(movp_a_xa), OP(jmp_5), OP(illegal), OP(illegal), OP(cpl_c), // A0
OP(mov_r0_a), OP(mov_r1_a), OP(mov_r2_a), OP(mov_r3_a), OP(mov_r4_a), OP(mov_r5_a), OP(mov_r6_a), OP(mov_r7_a),
- OP(mov_xr0_n), OP(mov_xr1_n), OP(illegal), OP(jmpp_xa), OP(call_5), OP(illegal), OP(illegal), OP(illegal), /* B0 */
+ OP(mov_xr0_n), OP(mov_xr1_n), OP(illegal), OP(jmpp_xa), OP(call_5), OP(illegal), OP(illegal), OP(illegal), // B0
OP(mov_r0_n), OP(mov_r1_n), OP(mov_r2_n), OP(mov_r3_n), OP(mov_r4_n), OP(mov_r5_n), OP(mov_r6_n), OP(mov_r7_n),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(jmp_6), OP(illegal), OP(jz), OP(illegal), /* C0 */
+ OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(jmp_6), OP(illegal), OP(jz), OP(illegal), // C0
OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(xrl_a_xr0), OP(xrl_a_xr1), OP(illegal), OP(xrl_a_n), OP(call_6), OP(illegal), OP(illegal), OP(illegal), /* D0 */
+ OP(xrl_a_xr0), OP(xrl_a_xr1), OP(illegal), OP(xrl_a_n), OP(call_6), OP(illegal), OP(illegal), OP(illegal), // D0
OP(xrl_a_r0), OP(xrl_a_r1), OP(xrl_a_r2), OP(xrl_a_r3), OP(xrl_a_r4), OP(xrl_a_r5), OP(xrl_a_r6), OP(xrl_a_r7),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(jmp_7), OP(illegal), OP(jnc), OP(rl_a), /* E0 */
+ OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(jmp_7), OP(illegal), OP(jnc), OP(rl_a), // E0
OP(djnz_r0), OP(djnz_r1), OP(djnz_r2), OP(djnz_r3), OP(djnz_r4), OP(djnz_r5), OP(djnz_r6), OP(djnz_r7),
- OP(mov_a_xr0), OP(mov_a_xr1), OP(illegal), OP(illegal), OP(call_7), OP(illegal), OP(jc), OP(rlc_a), /* F0 */
+ OP(mov_a_xr0), OP(mov_a_xr1), OP(illegal), OP(illegal), OP(call_7), OP(illegal), OP(jc), OP(rlc_a), // F0
OP(mov_a_r0), OP(mov_a_r1), OP(mov_a_r2), OP(mov_a_r3), OP(mov_a_r4), OP(mov_a_r5), OP(mov_a_r6), OP(mov_a_r7)
};
const mcs48_cpu_device::mcs48_ophandler mcs48_cpu_device::s_i8022_opcodes[256] =
{
- OP(nop), OP(illegal), OP(illegal), OP(add_a_n), OP(jmp_0), OP(en_i), OP(illegal), OP(dec_a), /* 00 */
+ OP(nop), OP(illegal), OP(illegal), OP(add_a_n), OP(jmp_0), OP(en_i), OP(illegal), OP(dec_a), // 00
OP(in_a_p0), OP(in_a_p1), OP(in_a_p2), OP(illegal), OP(movd_a_p4), OP(movd_a_p5), OP(movd_a_p6), OP(movd_a_p7),
- OP(inc_xr0), OP(inc_xr1), OP(illegal), OP(adc_a_n), OP(call_0), OP(dis_i), OP(jtf), OP(inc_a), /* 10 */
+ OP(inc_xr0), OP(inc_xr1), OP(illegal), OP(adc_a_n), OP(call_0), OP(dis_i), OP(jtf), OP(inc_a), // 10
OP(inc_r0), OP(inc_r1), OP(inc_r2), OP(inc_r3), OP(inc_r4), OP(inc_r5), OP(inc_r6), OP(inc_r7),
- OP(xch_a_xr0), OP(xch_a_xr1), OP(illegal), OP(mov_a_n), OP(jmp_1), OP(en_tcnti), OP(jnt_0), OP(clr_a), /* 20 */
+ OP(xch_a_xr0), OP(xch_a_xr1), OP(illegal), OP(mov_a_n), OP(jmp_1), OP(en_tcnti), OP(jnt_0), OP(clr_a), // 20
OP(xch_a_r0), OP(xch_a_r1), OP(xch_a_r2), OP(xch_a_r3), OP(xch_a_r4), OP(xch_a_r5), OP(xch_a_r6), OP(xch_a_r7),
- OP(xchd_a_xr0), OP(xchd_a_xr1), OP(illegal), OP(illegal), OP(call_1), OP(dis_tcnti), OP(jt_0), OP(cpl_a), /* 30 */
+ OP(xchd_a_xr0), OP(xchd_a_xr1), OP(illegal), OP(illegal), OP(call_1), OP(dis_tcnti), OP(jt_0), OP(cpl_a), // 30
OP(illegal), OP(outl_p1_a), OP(outl_p2_a), OP(illegal), OP(movd_p4_a), OP(movd_p5_a), OP(movd_p6_a), OP(movd_p7_a),
- OP(orl_a_xr0), OP(orl_a_xr1), OP(mov_a_t), OP(orl_a_n), OP(jmp_2), OP(strt_cnt), OP(jnt_1), OP(swap_a), /* 40 */
+ OP(orl_a_xr0), OP(orl_a_xr1), OP(mov_a_t), OP(orl_a_n), OP(jmp_2), OP(strt_cnt), OP(jnt_1), OP(swap_a), // 40
OP(orl_a_r0), OP(orl_a_r1), OP(orl_a_r2), OP(orl_a_r3), OP(orl_a_r4), OP(orl_a_r5), OP(orl_a_r6), OP(orl_a_r7),
- OP(anl_a_xr0), OP(anl_a_xr1), OP(illegal), OP(anl_a_n), OP(call_2), OP(strt_t), OP(jt_1), OP(da_a), /* 50 */
+ OP(anl_a_xr0), OP(anl_a_xr1), OP(illegal), OP(anl_a_n), OP(call_2), OP(strt_t), OP(jt_1), OP(da_a), // 50
OP(anl_a_r0), OP(anl_a_r1), OP(anl_a_r2), OP(anl_a_r3), OP(anl_a_r4), OP(anl_a_r5), OP(anl_a_r6), OP(anl_a_r7),
- OP(add_a_xr0), OP(add_a_xr1), OP(mov_t_a), OP(illegal), OP(jmp_3), OP(stop_tcnt), OP(illegal), OP(rrc_a), /* 60 */
+ OP(add_a_xr0), OP(add_a_xr1), OP(mov_t_a), OP(illegal), OP(jmp_3), OP(stop_tcnt), OP(illegal), OP(rrc_a), // 60
OP(add_a_r0), OP(add_a_r1), OP(add_a_r2), OP(add_a_r3), OP(add_a_r4), OP(add_a_r5), OP(add_a_r6), OP(add_a_r7),
- OP(adc_a_xr0), OP(adc_a_xr1), OP(illegal), OP(illegal), OP(call_3), OP(illegal), OP(illegal), OP(rr_a), /* 70 */
+ OP(adc_a_xr0), OP(adc_a_xr1), OP(illegal), OP(illegal), OP(call_3), OP(illegal), OP(illegal), OP(rr_a), // 70
OP(adc_a_r0), OP(adc_a_r1), OP(adc_a_r2), OP(adc_a_r3), OP(adc_a_r4), OP(adc_a_r5), OP(adc_a_r6), OP(adc_a_r7),
- OP(illegal), OP(illegal), OP(illegal), OP(ret), OP(jmp_4), OP(illegal), OP(illegal), OP(illegal), /* 80 */
+ OP(illegal), OP(illegal), OP(illegal), OP(ret), OP(jmp_4), OP(illegal), OP(illegal), OP(illegal), // 80
OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(orld_p4_a), OP(orld_p5_a), OP(orld_p6_a), OP(orld_p7_a),
- OP(outl_p0_a), OP(illegal), OP(illegal), OP(retr), OP(call_4), OP(illegal), OP(jnz), OP(clr_c), /* 90 */
+ OP(outl_p0_a), OP(illegal), OP(illegal), OP(retr), OP(call_4), OP(illegal), OP(jnz), OP(clr_c), // 90
OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(anld_p4_a), OP(anld_p5_a), OP(anld_p6_a), OP(anld_p7_a),
- OP(mov_xr0_a), OP(mov_xr1_a), OP(illegal), OP(movp_a_xa), OP(jmp_5), OP(illegal), OP(illegal), OP(cpl_c), /* A0 */
+ OP(mov_xr0_a), OP(mov_xr1_a), OP(illegal), OP(movp_a_xa), OP(jmp_5), OP(illegal), OP(illegal), OP(cpl_c), // A0
OP(mov_r0_a), OP(mov_r1_a), OP(mov_r2_a), OP(mov_r3_a), OP(mov_r4_a), OP(mov_r5_a), OP(mov_r6_a), OP(mov_r7_a),
- OP(mov_xr0_n), OP(mov_xr1_n), OP(illegal), OP(jmpp_xa), OP(call_5), OP(illegal), OP(illegal), OP(illegal), /* B0 */
+ OP(mov_xr0_n), OP(mov_xr1_n), OP(illegal), OP(jmpp_xa), OP(call_5), OP(illegal), OP(illegal), OP(illegal), // B0
OP(mov_r0_n), OP(mov_r1_n), OP(mov_r2_n), OP(mov_r3_n), OP(mov_r4_n), OP(mov_r5_n), OP(mov_r6_n), OP(mov_r7_n),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(jmp_6), OP(illegal), OP(jz), OP(illegal), /* C0 */
+ OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(jmp_6), OP(illegal), OP(jz), OP(illegal), // C0
OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(illegal),
- OP(xrl_a_xr0), OP(xrl_a_xr1), OP(illegal), OP(xrl_a_n), OP(call_6), OP(illegal), OP(illegal), OP(illegal), /* D0 */
+ OP(xrl_a_xr0), OP(xrl_a_xr1), OP(illegal), OP(xrl_a_n), OP(call_6), OP(illegal), OP(illegal), OP(illegal), // D0
OP(xrl_a_r0), OP(xrl_a_r1), OP(xrl_a_r2), OP(xrl_a_r3), OP(xrl_a_r4), OP(xrl_a_r5), OP(xrl_a_r6), OP(xrl_a_r7),
- OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(jmp_7), OP(illegal), OP(jnc), OP(rl_a), /* E0 */
+ OP(illegal), OP(illegal), OP(illegal), OP(illegal), OP(jmp_7), OP(illegal), OP(jnc), OP(rl_a), // E0
OP(djnz_r0), OP(djnz_r1), OP(djnz_r2), OP(djnz_r3), OP(djnz_r4), OP(djnz_r5), OP(djnz_r6), OP(djnz_r7),
- OP(mov_a_xr0), OP(mov_a_xr1), OP(illegal), OP(illegal), OP(call_7), OP(illegal), OP(jc), OP(rlc_a), /* F0 */
+ OP(mov_a_xr0), OP(mov_a_xr1), OP(illegal), OP(illegal), OP(call_7), OP(illegal), OP(jc), OP(rlc_a), // F0
OP(mov_a_r0), OP(mov_a_r1), OP(mov_a_r2), OP(mov_a_r3), OP(mov_a_r4), OP(mov_a_r5), OP(mov_a_r6), OP(mov_a_r7)
};
-/***************************************************************************
+/*******************************************************************************
INITIALIZATION/RESET
-***************************************************************************/
+*******************************************************************************/
void mcs48_cpu_device::device_config_complete()
{
- m_t0_clk_func.bind_relative_to(*owner());
+ m_t0_clk_func.resolve();
if (!m_t0_clk_func.isnull())
m_t0_clk_func(clock() / 3);
}
@@ -1096,79 +1134,81 @@ void mcs48_cpu_device::device_config_complete()
void mcs48_cpu_device::device_start()
{
- /* External access line
- * EA=1 : read from external rom
- * EA=0 : read from internal rom
- */
+ // zerofill
+ m_prevpc = 0;
+ m_pc = 0;
m_a = 0;
+ m_psw = 0;
+ m_f1 = false;
+ m_a11 = 0;
+ m_p1 = 0;
+ m_p2 = 0;
m_timer = 0;
m_prescaler = 0;
m_t1_history = 0;
m_dbbi = 0;
m_dbbo = 0;
- m_irq_state = 0;
- m_irq_polled = 0;
-
- /* FIXME: Current implementation suboptimal */
- m_ea = (m_int_rom_size ? 0 : 1);
-
- m_program = &space(AS_PROGRAM);
- m_cache = m_program->cache<0, 0, ENDIANNESS_LITTLE>();
- m_data = &space(AS_DATA);
- m_io = (m_feature_mask & EXT_BUS_FEATURE) != 0 ? &space(AS_IO) : nullptr;
-
- // resolve callbacks
- for (auto &cb : m_port_in_cb)
- cb.resolve_safe(0xff);
- for (auto &cb : m_port_out_cb)
- cb.resolve_safe();
- m_bus_in_cb.resolve_safe(0xff);
- m_bus_out_cb.resolve_safe();
- for (auto &cb : m_test_in_cb)
- cb.resolve_safe(0);
- m_prog_out_cb.resolve_safe();
-
- /* set up the state table */
- {
- state_add(MCS48_PC, "PC", m_pc).mask(0xfff);
- state_add(STATE_GENPC, "GENPC", m_pc).mask(0xfff).noshow();
- state_add(STATE_GENPCBASE, "CURPC", m_prevpc).mask(0xfff).noshow();
- state_add(STATE_GENSP, "GENSP", m_psw).mask(0x7).noshow();
- state_add(STATE_GENFLAGS, "GENFLAGS", m_psw).noshow().formatstr("%11s");
- state_add(MCS48_A, "A", m_a);
- state_add(MCS48_TC, "TC", m_timer);
- state_add(MCS48_TPRE, "TPRE", m_prescaler).mask(0x1f);
-
- if (m_feature_mask & I802X_FEATURE)
- state_add(MCS48_P0, "P0", m_dbbo);
- state_add(MCS48_P1, "P1", m_p1);
- state_add(MCS48_P2, "P2", m_p2);
-
- for (int regnum = 0; regnum < 8; regnum++) {
- state_add(MCS48_R0 + regnum, string_format("R%d", regnum).c_str(), m_rtemp).callimport().callexport();
- }
- if (m_feature_mask & EXT_BUS_FEATURE)
- state_add(MCS48_EA, "EA", m_ea).mask(0x1);
+ m_irq_state = false;
+ m_irq_polled = false;
+ m_irq_in_progress = false;
+ m_timer_overflow = false;
+ m_timer_flag = false;
+ m_tirq_enabled = false;
+ m_xirq_enabled = false;
+ m_timecount_enabled = 0;
+ m_flags_enabled = false;
+ m_dma_enabled = false;
- if (m_feature_mask & UPI41_FEATURE)
- {
- state_add(MCS48_STS, "STS", m_sts);
- state_add(MCS48_DBBI, "DBBI", m_dbbi);
- state_add(MCS48_DBBO, "DBBO", m_dbbo);
- }
+ space(AS_PROGRAM).cache(m_program);
+ space(AS_DATA).specific(m_data);
+ if (m_feature_mask & EXT_BUS_FEATURE)
+ space(AS_IO).specific(m_io);
- }
+ // default EA pin state
+ m_ea = m_rom_size ? 0 : 1;
+ update_ea();
- /* ensure that regptr is valid before get_info gets called */
+ // ensure that regptr is valid before get_info gets called
update_regptr();
+ // set up the state table
+ state_add(MCS48_PC, "PC", m_pc).mask(0xfff);
+ state_add(STATE_GENPC, "GENPC", m_pc).mask(0xfff).noshow();
+ state_add(STATE_GENPCBASE, "CURPC", m_prevpc).mask(0xfff).noshow();
+ state_add(MCS48_SP, "SP", m_psw).mask(0x7).noshow();
+ state_add(STATE_GENFLAGS, "GENFLAGS", m_psw).noshow().formatstr("%11s");
+ state_add(MCS48_A, "A", m_a);
+ state_add(MCS48_TC, "TC", m_timer);
+ state_add(MCS48_TPRE, "TPRE", m_prescaler).mask(0x1f);
+
+ if (m_feature_mask & I802X_FEATURE)
+ state_add(MCS48_P0, "P0", m_dbbo);
+ state_add(MCS48_P1, "P1", m_p1);
+ state_add(MCS48_P2, "P2", m_p2);
+
+ for (int regnum = 0; regnum < 8; regnum++)
+ state_add(MCS48_R0 + regnum, string_format("R%d", regnum).c_str(), m_rtemp).callimport().callexport();
+
+ if (!(m_feature_mask & I802X_FEATURE))
+ state_add(MCS48_EA, "EA", m_ea).mask(0x1);
+
+ if (m_feature_mask & UPI41_FEATURE)
+ {
+ state_add(MCS48_STS, "STS", m_sts).mask(0xf3);
+ state_add(MCS48_DBBI, "DBBI", m_dbbi);
+ state_add(MCS48_DBBO, "DBBO", m_dbbo);
+ }
+
+ // register for savestates
save_item(NAME(m_prevpc));
save_item(NAME(m_pc));
save_item(NAME(m_a));
save_item(NAME(m_psw));
+ save_item(NAME(m_f1));
+ save_item(NAME(m_a11));
save_item(NAME(m_p1));
save_item(NAME(m_p2));
save_item(NAME(m_ea));
@@ -1190,24 +1230,19 @@ void mcs48_cpu_device::device_start()
save_item(NAME(m_flags_enabled));
save_item(NAME(m_dma_enabled));
- save_item(NAME(m_a11));
-
set_icountptr(m_icount);
}
void mcs48_cpu_device::device_reset()
{
- /* confirmed from reset description */
+ // confirmed from reset description
m_pc = 0;
- m_psw = (m_psw & (C_FLAG | A_FLAG)) | 0x08;
- m_a11 = 0x000;
- m_dbbo = 0xff;
- bus_w(0xff);
- m_p1 = 0xff;
- m_p2 = 0xff;
- port_w(1, m_p1);
- port_w(2, m_p2);
+ m_psw = m_psw & (C_FLAG | A_FLAG);
+ update_regptr();
+ m_f1 = false;
+ m_a11 = 0;
+
m_tirq_enabled = false;
m_xirq_enabled = false;
m_timecount_enabled = 0;
@@ -1215,61 +1250,76 @@ void mcs48_cpu_device::device_reset()
m_sts = 0;
m_flags_enabled = false;
m_dma_enabled = false;
- if (!m_t0_clk_func.isnull())
- m_t0_clk_func(0);
- /* confirmed from interrupt logic description */
+ // confirmed from interrupt logic description
m_irq_in_progress = false;
m_timer_overflow = false;
+
+ m_irq_polled = false;
+
+ // BUS is set to high-impedance (except when EA=1)
+ m_dbbo = 0xff;
+ m_bus_out_cb(0, 0xff, m_ea ? 0xff : 0); // bus_w
+
+ // port 1 and port 2 are set to input mode
+ m_p1 = 0xff;
+ m_p2 = 0xff;
+ port_w(1, m_p1);
+ port_w(2, m_p2);
+
+ if (!m_t0_clk_func.isnull())
+ m_t0_clk_func(0);
}
-/***************************************************************************
+/*******************************************************************************
EXECUTION
-***************************************************************************/
+*******************************************************************************/
/*-------------------------------------------------
check_irqs - check for and process IRQs
-------------------------------------------------*/
-int mcs48_cpu_device::check_irqs()
+void mcs48_cpu_device::check_irqs()
{
- /* if something is in progress, we do nothing */
+ // if something is in progress, we do nothing
if (m_irq_in_progress)
- return 0;
+ return;
- /* external interrupts take priority */
- if ((m_irq_state || (m_sts & STS_IBF) != 0) && m_xirq_enabled)
+ // external interrupts take priority
+ else if ((m_irq_state || (m_sts & STS_IBF) != 0) && m_xirq_enabled)
{
+ // indicate we took the external IRQ
+ standard_irq_callback(0, m_pc);
+
+ burn_cycles(2);
m_irq_in_progress = true;
// force JNI to be taken (hack)
if (m_irq_polled)
- m_pc = ((m_pc - 1) & 0xf00) | m_cache->read_byte(m_pc - 1);
-
- /* transfer to location 0x03 */
- push_pc_psw();
- m_pc = 0x03;
+ {
+ m_pc = ((m_prevpc + 1) & 0x7ff) | (m_prevpc & 0x800);
+ execute_jcc(true);
+ }
- /* indicate we took the external IRQ */
- standard_irq_callback(0);
- return 2;
+ // transfer to location 0x03
+ execute_call(0x03);
}
- /* timer overflow interrupts follow */
- if (m_timer_overflow && m_tirq_enabled)
+ // timer overflow interrupts follow
+ else if (m_timer_overflow && m_tirq_enabled)
{
+ standard_irq_callback(1, m_pc);
+
+ burn_cycles(2);
m_irq_in_progress = true;
- /* transfer to location 0x07 */
- push_pc_psw();
- m_pc = 0x07;
+ // transfer to location 0x07
+ execute_call(0x07);
- /* timer overflow flip-flop is reset once taken */
+ // timer overflow flip-flop is reset once taken
m_timer_overflow = false;
- return 2;
}
- return 0;
}
@@ -1280,39 +1330,47 @@ int mcs48_cpu_device::check_irqs()
void mcs48_cpu_device::burn_cycles(int count)
{
- int timerover = false;
-
- /* if the timer is enabled, accumulate prescaler cycles */
- if (m_timecount_enabled & TIMER_ENABLED)
+ if (m_timecount_enabled)
{
- uint8_t oldtimer = m_timer;
- m_prescaler += count;
- m_timer += m_prescaler >> 5;
- m_prescaler &= 0x1f;
- timerover = (oldtimer != 0 && m_timer == 0);
- }
+ bool timerover = false;
- /* if the counter is enabled, poll the T1 test input once for each cycle */
- else if (m_timecount_enabled & COUNTER_ENABLED)
- for ( ; count > 0; count--)
+ // if the timer is enabled, accumulate prescaler cycles
+ if (m_timecount_enabled & TIMER_ENABLED)
{
- m_t1_history = (m_t1_history << 1) | (test_r(1) & 1);
- if ((m_t1_history & 3) == 2)
- timerover = (++m_timer == 0);
+ u8 oldtimer = m_timer;
+ m_prescaler += count;
+ m_timer += m_prescaler >> 5;
+ m_prescaler &= 0x1f;
+ timerover = m_timer < oldtimer;
}
- /* if either source caused a timer overflow, set the flags and check IRQs */
- if (timerover)
- {
- m_timer_flag = true;
+ // if the counter is enabled, poll the T1 test input once for each cycle
+ else if (m_timecount_enabled & COUNTER_ENABLED)
+ {
+ for ( ; count > 0; count--, m_icount--)
+ {
+ m_t1_history = (m_t1_history << 1) | (test_r(1) & 1);
+ if ((m_t1_history & 3) == 2)
+ {
+ if (++m_timer == 0)
+ timerover = true;
+ }
+ }
+ }
- /* according to the docs, if an overflow occurs with interrupts disabled, the overflow is not stored */
- if (m_tirq_enabled)
+ // if either source caused a timer overflow, set the flags
+ if (timerover)
{
- m_timer_overflow = true;
- check_irqs();
+ m_timer_flag = true;
+
+ // according to the docs, if an overflow occurs with interrupts disabled, the overflow is not stored
+ if (m_tirq_enabled)
+ m_timer_overflow = true;
}
}
+
+ // (note: if timer counter is enabled, count was already reduced to 0)
+ m_icount -= count;
}
@@ -1323,56 +1381,43 @@ void mcs48_cpu_device::burn_cycles(int count)
void mcs48_cpu_device::execute_run()
{
- int curcycles;
-
update_regptr();
- /* external interrupts may have been set since we last checked */
- curcycles = check_irqs();
- m_icount -= curcycles;
- if (m_timecount_enabled != 0)
- burn_cycles(curcycles);
-
- /* iterate over remaining cycles, guaranteeing at least one instruction */
+ // iterate over remaining cycles, guaranteeing at least one instruction
do
{
- unsigned opcode;
+ // check interrupts
+ check_irqs();
+ m_irq_polled = false;
- /* fetch next opcode */
m_prevpc = m_pc;
- m_irq_polled = false;
debugger_instruction_hook(m_pc);
- opcode = opcode_fetch();
-
- /* process opcode and count cycles */
- curcycles = (this->*m_opcode_table[opcode])();
- /* burn the cycles */
- m_icount -= curcycles;
- if (m_timecount_enabled != 0)
- burn_cycles(curcycles);
+ // fetch and process opcode
+ unsigned opcode = opcode_fetch();
+ (this->*m_opcode_table[opcode])();
} while (m_icount > 0);
}
-/***************************************************************************
+/*******************************************************************************
DATA ACCESS HELPERS
-***************************************************************************/
+*******************************************************************************/
/*-------------------------------------------------
upi41_master_r - master CPU data/status
read
-------------------------------------------------*/
-READ8_MEMBER( upi41_cpu_device::upi41_master_r )
+u8 upi41_cpu_device::upi41_master_r(offs_t offset)
{
- /* if just reading the status, return it */
- if ((offset & 1) != 0)
- return m_sts;
+ // if just reading the status, return it
+ if (offset & 1)
+ return (m_sts & 0xf3) | (m_f1 ? 8 : 0) | ((m_psw & F_FLAG) ? 4 : 0);
- /* if the output buffer was full, it gets cleared now */
+ // if the output buffer was full, it gets cleared now
if (m_sts & STS_OBF)
{
m_sts &= ~STS_OBF;
@@ -1388,15 +1433,12 @@ READ8_MEMBER( upi41_cpu_device::upi41_master_r )
write
-------------------------------------------------*/
-TIMER_CALLBACK_MEMBER( upi41_cpu_device::master_callback )
+TIMER_CALLBACK_MEMBER(upi41_cpu_device::master_callback)
{
- uint8_t a0 = (param >> 8) & 1;
- uint8_t data = param;
+ // data always goes to the input buffer
+ m_dbbi = param & 0xff;
- /* data always goes to the input buffer */
- m_dbbi = data;
-
- /* set the appropriate flags */
+ // set the appropriate flags
if ((m_sts & STS_IBF) == 0)
{
m_sts |= STS_IBF;
@@ -1404,22 +1446,20 @@ TIMER_CALLBACK_MEMBER( upi41_cpu_device::master_callback )
port_w(2, m_p2 &= ~P2_NIBF);
}
- /* set F1 accordingly */
- if (a0 == 0)
- m_sts &= ~STS_F1;
- else
- m_sts |= STS_F1;
+ // set F1 accordingly
+ bool a0 = bool(param & 0x100);
+ m_f1 = a0;
}
-WRITE8_MEMBER( upi41_cpu_device::upi41_master_w )
+void upi41_cpu_device::upi41_master_w(offs_t offset, u8 data)
{
machine().scheduler().synchronize(timer_expired_delegate(FUNC(upi41_cpu_device::master_callback), this), (offset << 8) | data);
}
-/***************************************************************************
+/*******************************************************************************
GENERAL CONTEXT ACCESS
-***************************************************************************/
+*******************************************************************************/
/*-------------------------------------------------
mcs48_import_state - import state from the
@@ -1477,17 +1517,18 @@ void mcs48_cpu_device::state_string_export(const device_state_entry &entry, std:
switch (entry.index())
{
case STATE_GENFLAGS:
- str = string_format("%c%c %c%c%c%c%c%c%c%c",
- m_irq_state ? 'I':'.',
- m_a11 ? 'M':'.',
+ str = string_format("%c%c%c %c%c%c%c%c%c%c%c",
+ m_irq_state ? 'I':'.',
+ m_a11 ? 'M':'.',
+ m_f1 ? '1':'.',
m_psw & 0x80 ? 'C':'.',
m_psw & 0x40 ? 'A':'.',
- m_psw & 0x20 ? 'F':'.',
+ m_psw & 0x20 ? '0':'.',
m_psw & 0x10 ? 'B':'.',
m_psw & 0x08 ? '?':'.',
- m_psw & 0x04 ? '4':'.',
- m_psw & 0x02 ? '2':'.',
- m_psw & 0x01 ? '1':'.');
+ m_psw & 0x04 ? 's':'.',
+ m_psw & 0x02 ? 's':'.',
+ m_psw & 0x01 ? 's':'.');
break;
}
}
@@ -1495,7 +1536,7 @@ void mcs48_cpu_device::state_string_export(const device_state_entry &entry, std:
void mcs48_cpu_device::execute_set_input(int inputnum, int state)
{
- switch( inputnum )
+ switch (inputnum)
{
case MCS48_INPUT_IRQ:
m_irq_state = (state != CLEAR_LINE);
@@ -1503,6 +1544,7 @@ void mcs48_cpu_device::execute_set_input(int inputnum, int state)
case MCS48_INPUT_EA:
m_ea = (state != CLEAR_LINE);
+ update_ea();
break;
}
}
diff --git a/src/devices/cpu/mcs48/mcs48.h b/src/devices/cpu/mcs48/mcs48.h
index dc3749f99b0..72d2d36ef0e 100644
--- a/src/devices/cpu/mcs48/mcs48.h
+++ b/src/devices/cpu/mcs48/mcs48.h
@@ -1,9 +1,7 @@
// license:BSD-3-Clause
-// copyright-holders:Mirko Buffoni
+// copyright-holders:Dan Boris, Mirko Buffoni, Aaron Giles, Couriersud
/***************************************************************************
- mcs48.c
-
Intel MCS-48/UPI-41 Portable Emulator
Copyright Mirko Buffoni
@@ -17,16 +15,16 @@
#pragma once
-
/***************************************************************************
CONSTANTS
***************************************************************************/
-/* register access indexes */
+// register access indexes
enum
{
MCS48_PC,
MCS48_PSW,
+ MCS48_SP,
MCS48_A,
MCS48_TC,
MCS48_TPRE,
@@ -48,11 +46,10 @@ enum
};
-/* I/O port access indexes */
+// I/O port access indexes
enum
{
MCS48_INPUT_IRQ = 0,
- UPI41_INPUT_IBF = 0,
MCS48_INPUT_EA
};
@@ -62,7 +59,7 @@ enum
***************************************************************************/
#define MCS48_LC_CLOCK(_L, _C) \
- (1 / (2 * 3.14159265358979323846 * sqrt(_L * _C)))
+ (1 / (2 * M_PI * sqrt(_L * _C)))
#define MCS48_ALE_CLOCK(_clock) \
attotime::from_hz(_clock/(3*5))
@@ -72,34 +69,33 @@ enum
TYPES
***************************************************************************/
-/* Official Intel MCS-48 parts */
-DECLARE_DEVICE_TYPE(I8021, i8021_device) /* 1k internal ROM, 64 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8022, i8022_device) /* 2k internal ROM, 128 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8035, i8035_device) /* external ROM, 64 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8048, i8048_device) /* 1k internal ROM, 64 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8648, i8648_device) /* 1k internal OTP ROM, 64 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8748, i8748_device) /* 1k internal EEPROM, 64 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8039, i8039_device) /* external ROM, 128 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8049, i8049_device) /* 2k internal ROM, 128 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8749, i8749_device) /* 2k internal EEPROM, 128 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8040, i8040_device) /* external ROM, 256 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8050, i8050_device) /* 4k internal ROM, 256 bytes internal RAM */
-
-/* Official Intel UPI-41 parts */
-DECLARE_DEVICE_TYPE(I8041A, i8041a_device) /* 1k internal ROM, 64 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8741A, i8741a_device) /* 1k internal EEPROM, 64 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8041AH, i8041ah_device) /* 1k internal ROM, 128 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8741AH, i8741ah_device) /* 1k internal EEPROM, 128 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8042, i8042_device) /* 2k internal ROM, 128 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8742, i8742_device) /* 2k internal EEPROM, 128 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8042AH, i8042ah_device) /* 2k internal ROM, 256 bytes internal RAM */
-DECLARE_DEVICE_TYPE(I8742AH, i8742ah_device) /* 2k internal EEPROM, 256 bytes internal RAM */
-
-/* Clones */
-DECLARE_DEVICE_TYPE(MB8884, mb8884_device) /* 8035 clone */
-DECLARE_DEVICE_TYPE(N7751, n7751_device) /* 8048 clone */
-DECLARE_DEVICE_TYPE(M58715, m58715_device) /* 8049 clone */
-
+// Official Intel MCS-48 parts
+DECLARE_DEVICE_TYPE(I8021, i8021_device) // 1k internal ROM, 64 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8022, i8022_device) // 2k internal ROM, 128 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8035, i8035_device) // external ROM, 64 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8048, i8048_device) // 1k internal ROM, 64 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8648, i8648_device) // 1k internal OTP ROM, 64 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8748, i8748_device) // 1k internal UV EPROM, 64 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8039, i8039_device) // external ROM, 128 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8049, i8049_device) // 2k internal ROM, 128 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8749, i8749_device) // 2k internal UV EPROM, 128 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8040, i8040_device) // external ROM, 256 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8050, i8050_device) // 4k internal ROM, 256 bytes internal RAM
+
+// Official Intel UPI-41 parts
+DECLARE_DEVICE_TYPE(I8041A, i8041a_device) // 1k internal ROM, 64 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8741A, i8741a_device) // 1k internal UV EPROM, 64 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8041AH, i8041ah_device) // 1k internal ROM, 128 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8741AH, i8741ah_device) // 1k internal UV EPROM, 128 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8042, i8042_device) // 2k internal ROM, 128 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8742, i8742_device) // 2k internal UV EPROM, 128 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8042AH, i8042ah_device) // 2k internal ROM, 256 bytes internal RAM
+DECLARE_DEVICE_TYPE(I8742AH, i8742ah_device) // 2k internal UV EPROM, 256 bytes internal RAM
+
+// Clones
+DECLARE_DEVICE_TYPE(MB8884, mb8884_device) // 8035 clone
+DECLARE_DEVICE_TYPE(UPD7751, upd7751_device) // 8048 clone
+DECLARE_DEVICE_TYPE(M58715, m58715_device) // 8049 clone
class mcs48_cpu_device : public cpu_device
@@ -127,42 +123,31 @@ public:
// PROG line to 8243 expander
auto prog_out_cb() { return m_prog_out_cb.bind(); }
- uint8_t p1_r() { return m_p1; }
- uint8_t p2_r() { return m_p2; }
+ u8 p1_r() { return m_p1; }
+ u8 p2_r() { return m_p2; }
- void data_6bit(address_map &map);
- void data_7bit(address_map &map);
- void data_8bit(address_map &map);
- void program_10bit(address_map &map);
- void program_11bit(address_map &map);
- void program_12bit(address_map &map);
+ template <typename... T> void set_t0_clk_cb(T &&... args) { m_t0_clk_func.set(std::forward<T>(args)...); }
+
+ u32 get_ale_clock() { return m_clock / 3 / 5; }
+ u32 get_t0_clock() { return m_clock / 3; }
- void set_t0_clk_cb(clock_update_delegate callback) { m_t0_clk_func = callback; }
- template <class FunctionClass> void set_t0_clk_cb(const char *devname, void (FunctionClass::*callback)(uint32_t), const char *name)
- {
- set_t0_clk_cb(clock_update_delegate(callback, name, devname, static_cast<FunctionClass *>(nullptr)));
- }
- template <class FunctionClass> void set_t0_clk_cb(void (FunctionClass::*callback)(uint32_t), const char *name)
- {
- set_t0_clk_cb(clock_update_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)));
- }
protected:
- typedef int (mcs48_cpu_device::*mcs48_ophandler)();
+ typedef void (mcs48_cpu_device::*mcs48_ophandler)();
// construction/destruction
- mcs48_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int rom_size, int ram_size, uint8_t feature_mask, const mcs48_ophandler *opcode_table);
+ mcs48_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int rom_size, int ram_size, u8 feature_mask, const mcs48_ophandler *opcode_table);
// device-level overrides
- virtual void device_start() override;
+ virtual void device_start() override ATTR_COLD;
virtual void device_config_complete() override;
- virtual void device_reset() override;
+ virtual void device_reset() override ATTR_COLD;
+ virtual void device_post_load() override { update_regptr(); }
// device_execute_interface overrides
- virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 15 - 1) / 15; }
- virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 15); }
- virtual uint32_t execute_min_cycles() const override { return 1; }
- virtual uint32_t execute_max_cycles() const override { return 3; }
- virtual uint32_t execute_input_lines() const override { return 2; }
+ virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept override { return (clocks + 15 - 1) / 15; }
+ virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override { return (cycles * 15); }
+ virtual u32 execute_min_cycles() const noexcept override { return 1; }
+ virtual u32 execute_max_cycles() const noexcept override { return 2+2; } // opcode+irq
virtual void execute_run() override;
virtual void execute_set_input(int inputnum, int state) override;
@@ -177,63 +162,63 @@ protected:
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
-protected:
address_space_config m_program_config;
address_space_config m_data_config;
address_space_config m_io_config;
+ memory_view m_rom_view;
- devcb_read8 m_port_in_cb[2];
- devcb_write8 m_port_out_cb[2];
- devcb_read8 m_bus_in_cb;
- devcb_write8 m_bus_out_cb;
+ devcb_read8::array<2> m_port_in_cb;
+ devcb_write8::array<2> m_port_out_cb;
+ devcb_read8 m_bus_in_cb;
+ devcb_write8 m_bus_out_cb;
- devcb_read_line m_test_in_cb[2];
+ devcb_read_line::array<2> m_test_in_cb;
clock_update_delegate m_t0_clk_func;
devcb_write_line m_prog_out_cb;
- uint16_t m_prevpc; /* 16-bit previous program counter */
- uint16_t m_pc; /* 16-bit program counter */
-
- uint8_t m_a; /* 8-bit accumulator */
- uint8_t * m_regptr; /* pointer to r0-r7 */
- uint8_t m_psw; /* 8-bit psw */
- uint8_t m_p1; /* 8-bit latched port 1 */
- uint8_t m_p2; /* 8-bit latched port 2 */
- uint8_t m_ea; /* 1-bit latched ea input */
- uint8_t m_timer; /* 8-bit timer */
- uint8_t m_prescaler; /* 5-bit timer prescaler */
- uint8_t m_t1_history; /* 8-bit history of the T1 input */
- uint8_t m_sts; /* 8-bit status register (UPI-41 only, except for F1) */
- uint8_t m_dbbi; /* 8-bit input data buffer (UPI-41 only) */
- uint8_t m_dbbo; /* 8-bit output data buffer (UPI-41 only) */
-
- bool m_irq_state; /* true if the IRQ line is active */
- bool m_irq_polled; /* true if last instruction was JNI (and not taken) */
- bool m_irq_in_progress; /* true if an IRQ is in progress */
- bool m_timer_overflow; /* true on a timer overflow; cleared by taking interrupt */
- bool m_timer_flag; /* true on a timer overflow; cleared on JTF */
- bool m_tirq_enabled; /* true if the timer IRQ is enabled */
- bool m_xirq_enabled; /* true if the external IRQ is enabled */
- uint8_t m_timecount_enabled; /* bitmask of timer/counter enabled */
- bool m_flags_enabled; /* true if I/O flags have been enabled (UPI-41 only) */
- bool m_dma_enabled; /* true if DMA has been enabled (UPI-41 only) */
-
- uint16_t m_a11; /* A11 value, either 0x000 or 0x800 */
-
- int m_icount;
-
- /* Memory spaces */
- address_space *m_program;
- memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_cache;
- address_space *m_data;
- address_space *m_io;
-
- required_shared_ptr<uint8_t> m_dataptr;
-
- uint8_t m_feature_mask; /* processor feature flags */
- uint16_t m_int_rom_size; /* internal rom size */
-
- uint8_t m_rtemp; /* temporary for import/export */
+ u16 m_prevpc; // 16-bit previous program counter
+ u16 m_pc; // 16-bit program counter
+
+ u8 m_a; // 8-bit accumulator
+ u8 *m_regptr; // pointer to r0-r7
+ u8 m_psw; // 8-bit PSW
+ bool m_f1; // F1 flag (F0 is in PSW)
+ u16 m_a11; // A11 value, either 0x000 or 0x800
+ u8 m_p1; // 8-bit latched port 1
+ u8 m_p2; // 8-bit latched port 2
+ u8 m_ea; // 1-bit latched ea input
+ u8 m_timer; // 8-bit timer
+ u8 m_prescaler; // 5-bit timer prescaler
+ u8 m_t1_history; // 8-bit history of the T1 input
+ u8 m_sts; // 4-bit status register + OBF/IBF flags (UPI-41 only)
+ u8 m_dbbi; // 8-bit input data buffer (UPI-41 only)
+ u8 m_dbbo; // 8-bit output data buffer (UPI-41 only)
+
+ bool m_irq_state; // true if the IRQ line is active
+ bool m_irq_polled; // true if last instruction was JNI (and not taken)
+ bool m_irq_in_progress; // true if an IRQ is in progress
+ bool m_timer_overflow; // true on a timer overflow; cleared by taking interrupt
+ bool m_timer_flag; // true on a timer overflow; cleared on JTF
+ bool m_tirq_enabled; // true if the timer IRQ is enabled
+ bool m_xirq_enabled; // true if the external IRQ is enabled
+ u8 m_timecount_enabled; // bitmask of timer/counter enabled
+ bool m_flags_enabled; // true if I/O flags have been enabled (UPI-41 only)
+ bool m_dma_enabled; // true if DMA has been enabled (UPI-41 only)
+
+ int m_icount;
+
+ // Memory spaces
+ memory_access<12, 0, 0, ENDIANNESS_LITTLE>::cache m_program;
+ memory_access<8, 0, 0, ENDIANNESS_LITTLE>::specific m_data;
+ memory_access<8, 0, 0, ENDIANNESS_LITTLE>::specific m_io;
+
+ required_shared_ptr<u8> m_dataptr;
+
+ u8 m_feature_mask; // processor feature flags
+ u16 m_rom_size; // internal rom size
+ u16 m_ram_size; // internal ram size
+
+ u8 m_rtemp; // temporary for import/export
static const mcs48_ophandler s_mcs48_opcodes[256];
static const mcs48_ophandler s_upi41_opcodes[256];
@@ -241,459 +226,467 @@ protected:
static const mcs48_ophandler s_i8022_opcodes[256];
const mcs48_ophandler *const m_opcode_table;
- /* ROM is mapped to AS_PROGRAM */
- uint8_t program_r(offs_t a) { return m_program->read_byte(a); }
-
- /* RAM is mapped to AS_DATA */
- uint8_t ram_r(offs_t a) { return m_data->read_byte(a); }
- void ram_w(offs_t a, uint8_t v) { m_data->write_byte(a, v); }
-
- /* ports are mapped to AS_IO and callbacks */
- uint8_t ext_r(offs_t a) { return m_io->read_byte(a); }
- void ext_w(offs_t a, uint8_t v) { m_io->write_byte(a, v); }
- uint8_t port_r(offs_t a) { return m_port_in_cb[a - 1](); }
- void port_w(offs_t a, uint8_t v) { m_port_out_cb[a - 1](v); }
- int test_r(offs_t a) { return m_test_in_cb[a](); }
- uint8_t bus_r() { return m_bus_in_cb(); }
- void bus_w(uint8_t v) { m_bus_out_cb(v); }
- void prog_w(int v) { m_prog_out_cb(v); }
-
- uint8_t opcode_fetch();
- uint8_t argument_fetch();
+ void program_map(address_map &map) ATTR_COLD;
+ void data_map(address_map &map) ATTR_COLD;
+
+ // ROM is mapped to AS_PROGRAM
+ u8 program_r(offs_t a) { return m_program.read_byte(a); }
+
+ // RAM is mapped to AS_DATA
+ u8 ram_r(offs_t a) { return m_data.read_byte(a); }
+ void ram_w(offs_t a, u8 v) { m_data.write_byte(a, v); }
+
+ // ports are mapped to AS_IO and callbacks
+ u8 ext_r(offs_t a) { return m_io.read_byte(a); }
+ void ext_w(offs_t a, u8 v) { m_io.write_byte(a, v); }
+ u8 port_r(offs_t a) { return m_port_in_cb[a - 1](); }
+ void port_w(offs_t a, u8 v) { m_port_out_cb[a - 1](v); }
+ int test_r(offs_t a) { return m_test_in_cb[a](); }
+ u8 bus_r() { return m_bus_in_cb(); }
+ void bus_w(u8 v) { m_bus_out_cb(v); }
+ void prog_w(int v) { m_prog_out_cb(v); }
+
+ u8 opcode_fetch();
+ u8 argument_fetch();
void update_regptr();
+ void update_ea();
void push_pc_psw();
void pull_pc_psw();
void pull_pc();
- void execute_add(uint8_t dat);
- void execute_addc(uint8_t dat);
- void execute_jmp(uint16_t address);
- void execute_call(uint16_t address);
- void execute_jcc(uint8_t result);
- uint8_t p2_mask();
- void expander_operation(expander_op operation, uint8_t port);
- int check_irqs();
+ void execute_add(u8 dat);
+ void execute_addc(u8 dat);
+ void execute_jmp(u16 address);
+ void execute_call(u16 address);
+ void execute_jcc(bool result);
+ u8 p2_mask();
+ void expander_operation(expander_op operation, u8 port);
+ void check_irqs();
void burn_cycles(int count);
- int illegal();
- int add_a_r0();
- int add_a_r1();
- int add_a_r2();
- int add_a_r3();
- int add_a_r4();
- int add_a_r5();
- int add_a_r6();
- int add_a_r7();
- int add_a_xr0();
- int add_a_xr1();
- int add_a_n();
- int adc_a_r0();
- int adc_a_r1();
- int adc_a_r2();
- int adc_a_r3();
- int adc_a_r4();
- int adc_a_r5();
- int adc_a_r6();
- int adc_a_r7();
- int adc_a_xr0();
- int adc_a_xr1();
- int adc_a_n();
- int anl_a_r0();
- int anl_a_r1();
- int anl_a_r2();
- int anl_a_r3();
- int anl_a_r4();
- int anl_a_r5();
- int anl_a_r6();
- int anl_a_r7();
- int anl_a_xr0();
- int anl_a_xr1();
- int anl_a_n();
- int anl_bus_n();
- int anl_p1_n();
- int anl_p2_n();
- int anld_p4_a();
- int anld_p5_a();
- int anld_p6_a();
- int anld_p7_a();
- int call_0();
- int call_1();
- int call_2();
- int call_3();
- int call_4();
- int call_5();
- int call_6();
- int call_7();
- int clr_a();
- int clr_c();
- int clr_f0();
- int clr_f1();
- int cpl_a();
- int cpl_c();
- int cpl_f0();
- int cpl_f1();
- int da_a();
- int dec_a();
- int dec_r0();
- int dec_r1();
- int dec_r2();
- int dec_r3();
- int dec_r4();
- int dec_r5();
- int dec_r6();
- int dec_r7();
- int dis_i();
- int dis_tcnti();
- int djnz_r0();
- int djnz_r1();
- int djnz_r2();
- int djnz_r3();
- int djnz_r4();
- int djnz_r5();
- int djnz_r6();
- int djnz_r7();
- int en_i();
- int en_tcnti();
- int en_dma();
- int en_flags();
- int ent0_clk();
- int in_a_p0();
- int in_a_p1();
- int in_a_p2();
- int ins_a_bus();
- int in_a_dbb();
- int inc_a();
- int inc_r0();
- int inc_r1();
- int inc_r2();
- int inc_r3();
- int inc_r4();
- int inc_r5();
- int inc_r6();
- int inc_r7();
- int inc_xr0();
- int inc_xr1();
- int jb_0();
- int jb_1();
- int jb_2();
- int jb_3();
- int jb_4();
- int jb_5();
- int jb_6();
- int jb_7();
- int jc();
- int jf0();
- int jf1();
- int jnc();
- int jni();
- int jnibf();
- int jnt_0();
- int jnt_1();
- int jnz();
- int jobf();
- int jtf();
- int jt_0();
- int jt_1();
- int jz();
- int jmp_0();
- int jmp_1();
- int jmp_2();
- int jmp_3();
- int jmp_4();
- int jmp_5();
- int jmp_6();
- int jmp_7();
- int jmpp_xa();
- int mov_a_n();
- int mov_a_psw();
- int mov_a_r0();
- int mov_a_r1();
- int mov_a_r2();
- int mov_a_r3();
- int mov_a_r4();
- int mov_a_r5();
- int mov_a_r6();
- int mov_a_r7();
- int mov_a_xr0();
- int mov_a_xr1();
- int mov_a_t();
- int mov_psw_a();
- int mov_sts_a();
- int mov_r0_a();
- int mov_r1_a();
- int mov_r2_a();
- int mov_r3_a();
- int mov_r4_a();
- int mov_r5_a();
- int mov_r6_a();
- int mov_r7_a();
- int mov_r0_n();
- int mov_r1_n();
- int mov_r2_n();
- int mov_r3_n();
- int mov_r4_n();
- int mov_r5_n();
- int mov_r6_n();
- int mov_r7_n();
- int mov_t_a();
- int mov_xr0_a();
- int mov_xr1_a();
- int mov_xr0_n();
- int mov_xr1_n();
- int movd_a_p4();
- int movd_a_p5();
- int movd_a_p6();
- int movd_a_p7();
- int movd_p4_a();
- int movd_p5_a();
- int movd_p6_a();
- int movd_p7_a();
- int movp_a_xa();
- int movp3_a_xa();
- int movx_a_xr0();
- int movx_a_xr1();
- int movx_xr0_a();
- int movx_xr1_a();
- int nop();
- int orl_a_r0();
- int orl_a_r1();
- int orl_a_r2();
- int orl_a_r3();
- int orl_a_r4();
- int orl_a_r5();
- int orl_a_r6();
- int orl_a_r7();
- int orl_a_xr0();
- int orl_a_xr1();
- int orl_a_n();
- int orl_bus_n();
- int orl_p1_n();
- int orl_p2_n();
- int orld_p4_a();
- int orld_p5_a();
- int orld_p6_a();
- int orld_p7_a();
- int outl_bus_a();
- int outl_p0_a();
- int outl_p1_a();
- int outl_p2_a();
- int out_dbb_a();
- int ret();
- int retr();
- int rl_a();
- int rlc_a();
- int rr_a();
- int rrc_a();
- int sel_mb0();
- int sel_mb1();
- int sel_rb0();
- int sel_rb1();
- int stop_tcnt();
- int strt_cnt();
- int strt_t();
- int swap_a();
- int xch_a_r0();
- int xch_a_r1();
- int xch_a_r2();
- int xch_a_r3();
- int xch_a_r4();
- int xch_a_r5();
- int xch_a_r6();
- int xch_a_r7();
- int xch_a_xr0();
- int xch_a_xr1();
- int xchd_a_xr0();
- int xchd_a_xr1();
- int xrl_a_r0();
- int xrl_a_r1();
- int xrl_a_r2();
- int xrl_a_r3();
- int xrl_a_r4();
- int xrl_a_r5();
- int xrl_a_r6();
- int xrl_a_r7();
- int xrl_a_xr0();
- int xrl_a_xr1();
- int xrl_a_n();
+ void illegal();
+ void add_a_r0();
+ void add_a_r1();
+ void add_a_r2();
+ void add_a_r3();
+ void add_a_r4();
+ void add_a_r5();
+ void add_a_r6();
+ void add_a_r7();
+ void add_a_xr0();
+ void add_a_xr1();
+ void add_a_n();
+ void adc_a_r0();
+ void adc_a_r1();
+ void adc_a_r2();
+ void adc_a_r3();
+ void adc_a_r4();
+ void adc_a_r5();
+ void adc_a_r6();
+ void adc_a_r7();
+ void adc_a_xr0();
+ void adc_a_xr1();
+ void adc_a_n();
+ void anl_a_r0();
+ void anl_a_r1();
+ void anl_a_r2();
+ void anl_a_r3();
+ void anl_a_r4();
+ void anl_a_r5();
+ void anl_a_r6();
+ void anl_a_r7();
+ void anl_a_xr0();
+ void anl_a_xr1();
+ void anl_a_n();
+ void anl_bus_n();
+ void anl_p1_n();
+ void anl_p2_n();
+ void anld_p4_a();
+ void anld_p5_a();
+ void anld_p6_a();
+ void anld_p7_a();
+ void call_0();
+ void call_1();
+ void call_2();
+ void call_3();
+ void call_4();
+ void call_5();
+ void call_6();
+ void call_7();
+ void clr_a();
+ void clr_c();
+ void clr_f0();
+ void clr_f1();
+ void cpl_a();
+ void cpl_c();
+ void cpl_f0();
+ void cpl_f1();
+ void da_a();
+ void dec_a();
+ void dec_r0();
+ void dec_r1();
+ void dec_r2();
+ void dec_r3();
+ void dec_r4();
+ void dec_r5();
+ void dec_r6();
+ void dec_r7();
+ void dis_i();
+ void dis_tcnti();
+ void djnz_r0();
+ void djnz_r1();
+ void djnz_r2();
+ void djnz_r3();
+ void djnz_r4();
+ void djnz_r5();
+ void djnz_r6();
+ void djnz_r7();
+ void en_i();
+ void en_tcnti();
+ void en_dma();
+ void en_flags();
+ void ent0_clk();
+ void in_a_p0();
+ void in_a_p1();
+ void in_a_p2();
+ void ins_a_bus();
+ void in_a_dbb();
+ void inc_a();
+ void inc_r0();
+ void inc_r1();
+ void inc_r2();
+ void inc_r3();
+ void inc_r4();
+ void inc_r5();
+ void inc_r6();
+ void inc_r7();
+ void inc_xr0();
+ void inc_xr1();
+ void jb_0();
+ void jb_1();
+ void jb_2();
+ void jb_3();
+ void jb_4();
+ void jb_5();
+ void jb_6();
+ void jb_7();
+ void jc();
+ void jf0();
+ void jf1();
+ void jnc();
+ void jni();
+ void jnibf();
+ void jnt_0();
+ void jnt_1();
+ void jnz();
+ void jobf();
+ void jtf();
+ void jt_0();
+ void jt_1();
+ void jz();
+ void jmp_0();
+ void jmp_1();
+ void jmp_2();
+ void jmp_3();
+ void jmp_4();
+ void jmp_5();
+ void jmp_6();
+ void jmp_7();
+ void jmpp_xa();
+ void mov_a_n();
+ void mov_a_psw();
+ void mov_a_r0();
+ void mov_a_r1();
+ void mov_a_r2();
+ void mov_a_r3();
+ void mov_a_r4();
+ void mov_a_r5();
+ void mov_a_r6();
+ void mov_a_r7();
+ void mov_a_xr0();
+ void mov_a_xr1();
+ void mov_a_t();
+ void mov_psw_a();
+ void mov_sts_a();
+ void mov_r0_a();
+ void mov_r1_a();
+ void mov_r2_a();
+ void mov_r3_a();
+ void mov_r4_a();
+ void mov_r5_a();
+ void mov_r6_a();
+ void mov_r7_a();
+ void mov_r0_n();
+ void mov_r1_n();
+ void mov_r2_n();
+ void mov_r3_n();
+ void mov_r4_n();
+ void mov_r5_n();
+ void mov_r6_n();
+ void mov_r7_n();
+ void mov_t_a();
+ void mov_xr0_a();
+ void mov_xr1_a();
+ void mov_xr0_n();
+ void mov_xr1_n();
+ void movd_a_p4();
+ void movd_a_p5();
+ void movd_a_p6();
+ void movd_a_p7();
+ void movd_p4_a();
+ void movd_p5_a();
+ void movd_p6_a();
+ void movd_p7_a();
+ void movp_a_xa();
+ void movp3_a_xa();
+ void movx_a_xr0();
+ void movx_a_xr1();
+ void movx_xr0_a();
+ void movx_xr1_a();
+ void nop();
+ void orl_a_r0();
+ void orl_a_r1();
+ void orl_a_r2();
+ void orl_a_r3();
+ void orl_a_r4();
+ void orl_a_r5();
+ void orl_a_r6();
+ void orl_a_r7();
+ void orl_a_xr0();
+ void orl_a_xr1();
+ void orl_a_n();
+ void orl_bus_n();
+ void orl_p1_n();
+ void orl_p2_n();
+ void orld_p4_a();
+ void orld_p5_a();
+ void orld_p6_a();
+ void orld_p7_a();
+ void outl_bus_a();
+ void outl_p0_a();
+ void outl_p1_a();
+ void outl_p2_a();
+ void out_dbb_a();
+ void ret();
+ void retr();
+ void rl_a();
+ void rlc_a();
+ void rr_a();
+ void rrc_a();
+ void sel_mb0();
+ void sel_mb1();
+ void sel_rb0();
+ void sel_rb1();
+ void stop_tcnt();
+ void strt_cnt();
+ void strt_t();
+ void swap_a();
+ void xch_a_r0();
+ void xch_a_r1();
+ void xch_a_r2();
+ void xch_a_r3();
+ void xch_a_r4();
+ void xch_a_r5();
+ void xch_a_r6();
+ void xch_a_r7();
+ void xch_a_xr0();
+ void xch_a_xr1();
+ void xchd_a_xr0();
+ void xchd_a_xr1();
+ void xrl_a_r0();
+ void xrl_a_r1();
+ void xrl_a_r2();
+ void xrl_a_r3();
+ void xrl_a_r4();
+ void xrl_a_r5();
+ void xrl_a_r6();
+ void xrl_a_r7();
+ void xrl_a_xr0();
+ void xrl_a_xr1();
+ void xrl_a_n();
};
class i8021_device : public mcs48_cpu_device
{
public:
+ // configuration
+ auto p0_in_cb() { return bus_in_cb(); }
+ auto p0_out_cb() { return bus_out_cb(); }
+
// construction/destruction
- i8021_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8021_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
// device_execute_interface overrides
- virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 30 - 1) / 30; }
- virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 30); }
+ virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept override { return (clocks + 30 - 1) / 30; }
+ virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override { return (cycles * 30); }
};
class i8022_device : public mcs48_cpu_device
{
public:
// construction/destruction
- i8022_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8022_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
// device_execute_interface overrides
- virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 30 - 1) / 30; }
- virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 30); }
+ virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept override { return (clocks + 30 - 1) / 30; }
+ virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override { return (cycles * 30); }
};
class i8035_device : public mcs48_cpu_device
{
public:
// construction/destruction
- i8035_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8035_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8048_device : public mcs48_cpu_device
{
public:
// construction/destruction
- i8048_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8048_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8648_device : public mcs48_cpu_device
{
public:
// construction/destruction
- i8648_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8648_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8748_device : public mcs48_cpu_device
{
public:
// construction/destruction
- i8748_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8748_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8039_device : public mcs48_cpu_device
{
public:
// construction/destruction
- i8039_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8039_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8049_device : public mcs48_cpu_device
{
public:
// construction/destruction
- i8049_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8049_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8749_device : public mcs48_cpu_device
{
public:
// construction/destruction
- i8749_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8749_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8040_device : public mcs48_cpu_device
{
public:
// construction/destruction
- i8040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8040_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8050_device : public mcs48_cpu_device
{
public:
// construction/destruction
- i8050_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8050_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class mb8884_device : public mcs48_cpu_device
{
public:
// construction/destruction
- mb8884_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ mb8884_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
-class n7751_device : public mcs48_cpu_device
+class upd7751_device : public mcs48_cpu_device
{
public:
// construction/destruction
- n7751_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ upd7751_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class m58715_device : public mcs48_cpu_device
{
public:
// construction/destruction
- m58715_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ m58715_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class upi41_cpu_device : public mcs48_cpu_device
{
public:
- /* functions for talking to the input/output buffers on the UPI41-class chips */
- DECLARE_READ8_MEMBER(upi41_master_r);
- DECLARE_WRITE8_MEMBER(upi41_master_w);
+ // functions for talking to the input/output buffers on the UPI41-class chips
+ u8 upi41_master_r(offs_t offset);
+ void upi41_master_w(offs_t offset, u8 data);
protected:
// construction/destruction
- upi41_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int rom_size, int ram_size);
+ upi41_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int rom_size, int ram_size);
- TIMER_CALLBACK_MEMBER( master_callback );
+ TIMER_CALLBACK_MEMBER(master_callback);
};
class i8041a_device : public upi41_cpu_device
{
public:
// construction/destruction
- i8041a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8041a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8741a_device : public upi41_cpu_device
{
public:
// construction/destruction
- i8741a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8741a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8041ah_device : public upi41_cpu_device
{
public:
// construction/destruction
- i8041ah_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8041ah_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8741ah_device : public upi41_cpu_device
{
public:
// construction/destruction
- i8741ah_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8741ah_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8042_device : public upi41_cpu_device
{
public:
// construction/destruction
- i8042_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8042_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8742_device : public upi41_cpu_device
{
public:
// construction/destruction
- i8742_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8742_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8042ah_device : public upi41_cpu_device
{
public:
// construction/destruction
- i8042ah_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8042ah_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class i8742ah_device : public upi41_cpu_device
{
public:
// construction/destruction
- i8742ah_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ i8742ah_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
-#endif // MAME_CPU_MCS48_MCS48_H
+#endif // MAME_CPU_MCS48_MCS48_H
diff --git a/src/devices/cpu/mcs48/mcs48dsm.cpp b/src/devices/cpu/mcs48/mcs48dsm.cpp
index 2f8363e3926..d35b18943a0 100644
--- a/src/devices/cpu/mcs48/mcs48dsm.cpp
+++ b/src/devices/cpu/mcs48/mcs48dsm.cpp
@@ -2,8 +2,6 @@
// copyright-holders:Aaron Giles
/***************************************************************************
- mcs48dsm.c
-
Simple MCS-48/UPI-41 disassembler.
Written by Aaron Giles
@@ -67,14 +65,17 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x10: util::stream_format(stream, "inc @r0"); break;
case 0x11: util::stream_format(stream, "inc @r1"); break;
case 0x12: if (!m_i802x)
+ {
util::stream_format(stream, "jb0 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
+ flags = STEP_COND;
+ }
else
util::stream_format(stream, "illegal");
break;
case 0x13: util::stream_format(stream, "addc a,#$%02X", params.r8(cpc++)); break;
case 0x14: util::stream_format(stream, "call $0%02X", params.r8(cpc++)); flags = STEP_OVER; break;
case 0x15: util::stream_format(stream, "dis i"); break;
- case 0x16: util::stream_format(stream, "jtf $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); break;
+ case 0x16: util::stream_format(stream, "jtf $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); flags = STEP_COND; break;
case 0x17: util::stream_format(stream, "inc a"); break;
case 0x18: util::stream_format(stream, "inc r0"); break;
case 0x19: util::stream_format(stream, "inc r1"); break;
@@ -94,7 +95,7 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x23: util::stream_format(stream, "mov a,#$%02X", params.r8(cpc++)); break;
case 0x24: util::stream_format(stream, "jmp $1%02X", params.r8(cpc++)); break;
case 0x25: util::stream_format(stream, "en tcnti"); break;
- case 0x26: util::stream_format(stream, "jnt0 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); break;
+ case 0x26: util::stream_format(stream, "jnt0 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); flags = STEP_COND; break;
case 0x27: util::stream_format(stream, "clr a"); break;
case 0x28: util::stream_format(stream, "xch a,r0"); break;
case 0x29: util::stream_format(stream, "xch a,r1"); break;
@@ -107,13 +108,16 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x30: util::stream_format(stream, "xchd a,@r0"); break;
case 0x31: util::stream_format(stream, "xchd a,@r1"); break;
case 0x32: if (!m_i802x)
+ {
util::stream_format(stream, "jb1 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
+ flags = STEP_COND;
+ }
else
util::stream_format(stream, "illegal");
break;
case 0x34: util::stream_format(stream, "call $1%02X", params.r8(cpc++)); flags = STEP_OVER; break;
case 0x35: util::stream_format(stream, "dis tcnti"); break;
- case 0x36: util::stream_format(stream, "jt0 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); break;
+ case 0x36: util::stream_format(stream, "jt0 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); flags = STEP_COND; break;
case 0x37: util::stream_format(stream, "cpl a"); break;
case 0x39: util::stream_format(stream, "outl p1,a"); break;
case 0x3a: util::stream_format(stream, "outl p2,a"); break;
@@ -127,7 +131,7 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x43: util::stream_format(stream, "orl a,#$%02X", params.r8(cpc++)); break;
case 0x44: util::stream_format(stream, "jmp $2%02X", params.r8(cpc++)); break;
case 0x45: util::stream_format(stream, "strt cnt"); break;
- case 0x46: util::stream_format(stream, "jnt1 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); break;
+ case 0x46: util::stream_format(stream, "jnt1 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); flags = STEP_COND; break;
case 0x47: util::stream_format(stream, "swap a"); break;
case 0x48: util::stream_format(stream, "orl a,r0"); break;
case 0x49: util::stream_format(stream, "orl a,r1"); break;
@@ -140,14 +144,17 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x50: util::stream_format(stream, "anl a,@r0"); break;
case 0x51: util::stream_format(stream, "anl a,@r1"); break;
case 0x52: if (!m_i802x)
+ {
util::stream_format(stream, "jb2 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
+ flags = STEP_COND;
+ }
else
util::stream_format(stream, "illegal");
break;
case 0x53: util::stream_format(stream, "anl a,#$%02X", params.r8(cpc++)); break;
case 0x54: util::stream_format(stream, "call $2%02X", params.r8(cpc++)); flags = STEP_OVER; break;
case 0x55: util::stream_format(stream, "strt t"); break;
- case 0x56: util::stream_format(stream, "jt1 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); break;
+ case 0x56: util::stream_format(stream, "jt1 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); flags = STEP_COND; break;
case 0x57: util::stream_format(stream, "da a"); break;
case 0x58: util::stream_format(stream, "anl a,r0"); break;
case 0x59: util::stream_format(stream, "anl a,r1"); break;
@@ -174,7 +181,10 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x70: util::stream_format(stream, "addc a,@r0"); break;
case 0x71: util::stream_format(stream, "addc a,@r1"); break;
case 0x72: if (!m_i802x)
+ {
util::stream_format(stream, "jb3 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
+ flags = STEP_COND;
+ }
else
util::stream_format(stream, "illegal");
break;
@@ -185,7 +195,10 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
util::stream_format(stream, "illegal");
break;
case 0x76: if (!m_i802x)
+ {
util::stream_format(stream, "jf1 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
+ flags = STEP_COND;
+ }
else
util::stream_format(stream, "illegal");
break;
@@ -219,10 +232,14 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
break;
case 0x86: if (m_i802x)
util::stream_format(stream, "illegal");
- else if (!m_upi41)
- util::stream_format(stream, "jni $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
else
- util::stream_format(stream, "jobf $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
+ {
+ if (!m_upi41)
+ util::stream_format(stream, "jni $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
+ else
+ util::stream_format(stream, "jobf $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
+ flags = STEP_COND;
+ }
break;
case 0x88: if (!m_upi41 && !m_i802x)
util::stream_format(stream, "orl bus,#$%02X", params.r8(cpc++));
@@ -256,7 +273,10 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
util::stream_format(stream, "illegal");
break;
case 0x92: if (!m_i802x)
+ {
util::stream_format(stream, "jb4 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
+ flags = STEP_COND;
+ }
else
util::stream_format(stream, "illegal");
break;
@@ -272,7 +292,7 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
else
util::stream_format(stream, "sel an1");
break;
- case 0x96: util::stream_format(stream, "jnz $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); break;
+ case 0x96: util::stream_format(stream, "jnz $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); flags = STEP_COND; break;
case 0x97: util::stream_format(stream, "clr c"); break;
case 0x98: if (!m_upi41 && !m_i802x)
util::stream_format(stream, "anl bus,#$%02X", params.r8(cpc++));
@@ -314,7 +334,10 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0xb0: util::stream_format(stream, "mov @r0,#$%02X", params.r8(cpc++)); break;
case 0xb1: util::stream_format(stream, "mov @r1,#$%02X", params.r8(cpc++)); break;
case 0xb2: if (!m_i802x)
+ {
util::stream_format(stream, "jb5 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
+ flags = STEP_COND;
+ }
else
util::stream_format(stream, "illegal");
break;
@@ -326,7 +349,10 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
util::stream_format(stream, "illegal");
break;
case 0xb6: if (!m_i802x)
+ {
util::stream_format(stream, "jf0 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
+ flags = STEP_COND;
+ }
else
util::stream_format(stream, "illegal");
break;
@@ -344,7 +370,7 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
else
util::stream_format(stream, "illegal");
break;
- case 0xc6: util::stream_format(stream, "jz $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); break;
+ case 0xc6: util::stream_format(stream, "jz $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); flags = STEP_COND; break;
case 0xc7: if (!m_i802x)
util::stream_format(stream, "mov a,psw");
else
@@ -393,7 +419,10 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0xd0: util::stream_format(stream, "xrl a,@r0"); break;
case 0xd1: util::stream_format(stream, "xrl a,@r1"); break;
case 0xd2: if (!m_i802x)
+ {
util::stream_format(stream, "jb6 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
+ flags = STEP_COND;
+ }
else
util::stream_format(stream, "illegal");
break;
@@ -407,7 +436,10 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0xd6: if (!m_upi41)
util::stream_format(stream, "illegal");
else
+ {
util::stream_format(stream, "jnibf $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
+ flags = STEP_COND;
+ }
break;
case 0xd7: if (!m_i802x)
util::stream_format(stream, "mov psw,a");
@@ -435,7 +467,7 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
else
util::stream_format(stream, "en dma");
break;
- case 0xe6: util::stream_format(stream, "jnc $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); break;
+ case 0xe6: util::stream_format(stream, "jnc $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); flags = STEP_COND; break;
case 0xe7: util::stream_format(stream, "rl a"); break;
case 0xe8: util::stream_format(stream, "djnz r0,$%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); flags = STEP_OVER; break;
case 0xe9: util::stream_format(stream, "djnz r1,$%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); flags = STEP_OVER; break;
@@ -448,7 +480,10 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0xf0: util::stream_format(stream, "mov a,@r0"); break;
case 0xf1: util::stream_format(stream, "mov a,@r1"); break;
case 0xf2: if (!m_i802x)
+ {
util::stream_format(stream, "jb7 $%03X", ((pc + 1) & 0x700) | params.r8(cpc++));
+ flags = STEP_COND;
+ }
else
util::stream_format(stream, "illegal");
break;
@@ -460,7 +495,7 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
else
util::stream_format(stream, "en flags");
break;
- case 0xf6: util::stream_format(stream, "jc $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); break;
+ case 0xf6: util::stream_format(stream, "jc $%03X", ((pc + 1) & 0x700) | params.r8(cpc++)); flags = STEP_COND; break;
case 0xf7: util::stream_format(stream, "rlc a"); break;
case 0xf8: util::stream_format(stream, "mov a,r0"); break;
case 0xf9: util::stream_format(stream, "mov a,r1"); break;
diff --git a/src/devices/cpu/mcs48/mcs48dsm.h b/src/devices/cpu/mcs48/mcs48dsm.h
index 38d6c899183..3144796ad1a 100644
--- a/src/devices/cpu/mcs48/mcs48dsm.h
+++ b/src/devices/cpu/mcs48/mcs48dsm.h
@@ -2,16 +2,13 @@
// copyright-holders:Aaron Giles
/***************************************************************************
- mcs48dsm.c
-
Simple MCS-48/UPI-41 disassembler.
Written by Aaron Giles
***************************************************************************/
-
-#ifndef MAME_CPU_MCS48_MCS48DASM_H
-#define MAME_CPU_MCS48_MCS48DASM_H
+#ifndef MAME_CPU_MCS48_MCS48DSM_H
+#define MAME_CPU_MCS48_MCS48DSM_H
#pragma once
@@ -31,4 +28,4 @@ private:
bool m_i802x;
};
-#endif
+#endif // MAME_CPU_MCS48_MCS48DSM_H