diff options
Diffstat (limited to 'src/devices/cpu/mcs48/mcs48.cpp')
-rw-r--r-- | src/devices/cpu/mcs48/mcs48.cpp | 1398 |
1 files changed, 720 insertions, 678 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; } } |