mcs48: More specific emulation of Intel 8021

- Separate disassembler for i802x (including unemulated 8022 instructions)
- Provide separate (though mostly just more limited) 8021 opcode table
- Writes to 8021 P0 no longer go through memory space
This commit is contained in:
AJR 2018-01-23 15:11:19 -05:00
parent 1b17d9882e
commit 19d57d9419
8 changed files with 370 additions and 164 deletions

View File

@ -5,9 +5,8 @@
- EA pin - defined by architecture, must implement:
1 means external access, bypassing internal ROM
reimplement as a push, not a pull
- T0 output clock
- get rid of i/o addressmap, use devcb for mcu pins
- add CMOS devices, 1 new opcode (01 HALT)
- 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
@ -119,9 +118,11 @@
#define ENABLE_DMA 0x02
/* feature masks */
#define MCS48_FEATURE 0x01
#define UPI41_FEATURE 0x02
#define MB_FEATURE 0x01
#define EXT_BUS_FEATURE 0x02
#define UPI41_FEATURE 0x04
#define I802X_FEATURE 0x08
#define I8048_FEATURE (MB_FEATURE | EXT_BUS_FEATURE)
/***************************************************************************
@ -191,9 +192,9 @@ static ADDRESS_MAP_START(data_8bit, AS_DATA, 8, mcs48_cpu_device)
ADDRESS_MAP_END
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)
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)
: cpu_device(mconfig, type, tag, owner, clock)
, m_program_config("program", ENDIANNESS_LITTLE, 8, (feature_mask & UPI41_FEATURE) != 0 ? 11 : 12, 0
, m_program_config("program", ENDIANNESS_LITTLE, 8, (feature_mask & MB_FEATURE) != 0 ? 12 : 11, 0
, (rom_size == 1024) ? ADDRESS_MAP_NAME(program_10bit) : (rom_size == 2048) ? ADDRESS_MAP_NAME(program_11bit) : (rom_size == 4096) ? ADDRESS_MAP_NAME(program_12bit) : nullptr)
, m_data_config("data", ENDIANNESS_LITTLE, 8, ( ( ram_size == 64 ) ? 6 : ( ( ram_size == 128 ) ? 7 : 8 ) ), 0
, (ram_size == 64) ? ADDRESS_MAP_NAME(data_6bit) : (ram_size == 128) ? ADDRESS_MAP_NAME(data_7bit) : ADDRESS_MAP_NAME(data_8bit))
@ -208,6 +209,7 @@ mcs48_cpu_device::mcs48_cpu_device(const machine_config &mconfig, device_type ty
, m_psw(0)
, m_feature_mask(feature_mask)
, m_int_rom_size(rom_size)
, m_opcode_table(opcode_table)
{
// Sanity checks
if ( ram_size != 64 && ram_size != 128 && ram_size != 256 )
@ -222,77 +224,77 @@ mcs48_cpu_device::mcs48_cpu_device(const machine_config &mconfig, device_type ty
}
i8021_device::i8021_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: mcs48_cpu_device(mconfig, I8021, tag, owner, clock, 1024, 64)
: 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)
: mcs48_cpu_device(mconfig, I8022, tag, owner, clock, 2048, 128)
: 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)
: mcs48_cpu_device(mconfig, I8035, tag, owner, clock, 0, 64)
: 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)
: mcs48_cpu_device(mconfig, I8048, tag, owner, clock, 1024, 64)
: 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)
: mcs48_cpu_device(mconfig, I8648, tag, owner, clock, 1024, 64)
: 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)
: mcs48_cpu_device(mconfig, I8748, tag, owner, clock, 1024, 64)
: 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)
: mcs48_cpu_device(mconfig, I8039, tag, owner, clock, 0, 128)
: 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)
: mcs48_cpu_device(mconfig, I8049, tag, owner, clock, 2048, 128)
: 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)
: mcs48_cpu_device(mconfig, I8749, tag, owner, clock, 2048, 128)
: 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)
: mcs48_cpu_device(mconfig, I8040, tag, owner, clock, 0, 256)
: 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)
: mcs48_cpu_device(mconfig, I8050, tag, owner, clock, 4096, 256)
: 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)
: mcs48_cpu_device(mconfig, MB8884, tag, owner, clock, 0, 64)
: 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)
: mcs48_cpu_device(mconfig, N7751, 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)
: mcs48_cpu_device(mconfig, M58715, tag, owner, clock, 2048, 128)
: 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)
: mcs48_cpu_device(mconfig, type, tag, owner, clock, rom_size, ram_size, UPI41_FEATURE)
: mcs48_cpu_device(mconfig, type, tag, owner, clock, rom_size, ram_size, UPI41_FEATURE, s_upi41_opcodes)
{
}
@ -323,7 +325,7 @@ i8742_device::i8742_device(const machine_config &mconfig, const char *tag, devic
device_memory_interface::space_config_vector mcs48_cpu_device::memory_space_config() const
{
if ((m_feature_mask & UPI41_FEATURE) == 0)
if ((m_feature_mask & EXT_BUS_FEATURE) != 0)
return space_config_vector {
std::make_pair(AS_PROGRAM, &m_program_config),
std::make_pair(AS_DATA, &m_data_config),
@ -338,12 +340,7 @@ device_memory_interface::space_config_vector mcs48_cpu_device::memory_space_conf
util::disasm_interface *mcs48_cpu_device::create_disassembler()
{
return new mcs48_disassembler(false);
}
util::disasm_interface *upi41_cpu_device::create_disassembler()
{
return new mcs48_disassembler(true);
return new mcs48_disassembler((m_feature_mask & UPI41_FEATURE) != 0, (m_feature_mask & I802X_FEATURE) != 0);
}
/***************************************************************************
@ -552,9 +549,6 @@ void mcs48_cpu_device::expander_operation(expander_op operation, uint8_t port)
#define OPHANDLER(_name) int mcs48_cpu_device::_name()
#define SPLIT_OPHANDLER(_name, _mcs48name, _upi41name) \
OPHANDLER(_name) { return (!(m_feature_mask & UPI41_FEATURE)) ? _mcs48name() : _upi41name(); }
OPHANDLER( illegal )
{
@ -678,6 +672,7 @@ OPHANDLER( ent0_clk )
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; }
@ -818,6 +813,7 @@ 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( out_dbb_a )
@ -888,21 +884,6 @@ 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; }
SPLIT_OPHANDLER( split_02, outl_bus_a, out_dbb_a )
SPLIT_OPHANDLER( split_08, ins_a_bus, illegal )
SPLIT_OPHANDLER( split_22, illegal, in_a_dbb )
SPLIT_OPHANDLER( split_75, ent0_clk, illegal )
SPLIT_OPHANDLER( split_80, movx_a_xr0, illegal )
SPLIT_OPHANDLER( split_81, movx_a_xr1, illegal )
SPLIT_OPHANDLER( split_86, jni, jobf )
SPLIT_OPHANDLER( split_88, orl_bus_n, illegal )
SPLIT_OPHANDLER( split_90, movx_xr0_a, mov_sts_a )
SPLIT_OPHANDLER( split_91, movx_xr1_a, illegal )
SPLIT_OPHANDLER( split_98, anl_bus_n, illegal )
SPLIT_OPHANDLER( split_d6, illegal, jnibf )
SPLIT_OPHANDLER( split_e5, sel_mb0, en_dma )
SPLIT_OPHANDLER( split_f5, sel_mb1, en_flags )
/***************************************************************************
@ -911,13 +892,13 @@ SPLIT_OPHANDLER( split_f5, sel_mb1, en_flags )
#define OP(_a) &mcs48_cpu_device::_a
const mcs48_cpu_device::mcs48_ophandler mcs48_cpu_device::s_opcode_table[256]=
const mcs48_cpu_device::mcs48_ophandler mcs48_cpu_device::s_mcs48_opcodes[256] =
{
OP(nop), OP(illegal), OP(split_02), OP(add_a_n), OP(jmp_0), OP(en_i), OP(illegal), OP(dec_a), /* 00 */
OP(split_08), 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(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_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(split_22), 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(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),
@ -927,23 +908,131 @@ const mcs48_cpu_device::mcs48_ophandler mcs48_cpu_device::s_opcode_table[256]=
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_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(split_75), 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(split_80), OP(split_81), OP(illegal), OP(ret), OP(jmp_4), OP(clr_f0), OP(split_86), OP(illegal), /* 80 */
OP(split_88), 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(split_90), OP(split_91), OP(jb_4), OP(retr), OP(call_4), OP(cpl_f0), OP(jnz), OP(clr_c), /* 90 */
OP(split_98), 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(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(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_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_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(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(split_d6), 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(split_e5), 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(split_f5), 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(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_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_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(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_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_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_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_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(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(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_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_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(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_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(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_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(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_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_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(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_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_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_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_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(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(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_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_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(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_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(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_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(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_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_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(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_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_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_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_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(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(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_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_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(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_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(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_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)
};
@ -985,7 +1074,7 @@ void mcs48_cpu_device::device_start()
m_program = &space(AS_PROGRAM);
m_direct = m_program->direct<0>();
m_data = &space(AS_DATA);
m_io = (m_feature_mask & UPI41_FEATURE) == 0 ? &space(AS_IO) : nullptr;
m_io = (m_feature_mask & EXT_BUS_FEATURE) != 0 ? &space(AS_IO) : nullptr;
// resolve callbacks
for (auto &cb : m_port_in_cb)
@ -1008,13 +1097,18 @@ void mcs48_cpu_device::device_start()
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();
}
state_add(MCS48_EA, "EA", m_ea).mask(0x1);
if (m_feature_mask & EXT_BUS_FEATURE)
state_add(MCS48_EA, "EA", m_ea).mask(0x1);
if (m_feature_mask & UPI41_FEATURE)
{
@ -1065,6 +1159,7 @@ void mcs48_cpu_device::device_reset()
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;
@ -1086,7 +1181,6 @@ void mcs48_cpu_device::device_reset()
}
/***************************************************************************
EXECUTION
***************************************************************************/
@ -1203,7 +1297,7 @@ void mcs48_cpu_device::execute_run()
opcode = opcode_fetch();
/* process opcode and count cycles */
curcycles = (this->*s_opcode_table[opcode])();
curcycles = (this->*m_opcode_table[opcode])();
/* burn the cycles */
m_icount -= curcycles;

View File

@ -30,6 +30,7 @@ enum
MCS48_A,
MCS48_TC,
MCS48_TPRE,
MCS48_P0, // 8021/8022 only
MCS48_P1,
MCS48_P2,
MCS48_R0,
@ -41,9 +42,9 @@ enum
MCS48_R6,
MCS48_R7,
MCS48_EA,
MCS48_STS, /* UPI-41 systems only */
MCS48_DBBO, /* UPI-41 systems only */
MCS48_DBBI /* UPI-41 systems only */
MCS48_STS, // UPI-41 only
MCS48_DBBO, // UPI-41 only
MCS48_DBBI // UPI-41 only
};
@ -153,8 +154,10 @@ public:
DECLARE_READ8_MEMBER(p2_r);
protected:
typedef int (mcs48_cpu_device::*mcs48_ophandler)();
// construction/destruction
mcs48_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int rom_size, int ram_size, uint8_t feature_mask = 0);
mcs48_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int rom_size, int ram_size, uint8_t feature_mask, const mcs48_ophandler *opcode_table);
// device-level overrides
virtual void device_start() override;
@ -237,8 +240,11 @@ protected:
uint8_t m_rtemp; /* temporary for import/export */
typedef int (mcs48_cpu_device::*mcs48_ophandler)();
static const mcs48_ophandler s_opcode_table[256];
static const mcs48_ophandler s_mcs48_opcodes[256];
static const mcs48_ophandler s_upi41_opcodes[256];
static const mcs48_ophandler s_i8021_opcodes[256];
static const mcs48_ophandler s_i8022_opcodes[256];
const mcs48_ophandler *const m_opcode_table;
/* ROM is mapped to AS_PROGRAM */
uint8_t program_r(offs_t a) { return m_program->read_byte(a); }
@ -355,6 +361,7 @@ protected:
int en_dma();
int en_flags();
int ent0_clk();
int in_a_p0();
int in_a_p1();
int in_a_p2();
int ins_a_bus();
@ -471,6 +478,7 @@ protected:
int orld_p6_a();
int orld_p7_a();
int outl_bus_a();
int outl_p0_a();
int outl_p1_a();
int outl_p2_a();
int out_dbb_a();
@ -511,21 +519,6 @@ protected:
int xrl_a_xr0();
int xrl_a_xr1();
int xrl_a_n();
int split_02();
int split_08();
int split_22();
int split_75();
int split_80();
int split_81();
int split_86();
int split_88();
int split_90();
int split_91();
int split_98();
int split_d6();
int split_e5();
int split_f5();
};
class i8021_device : public mcs48_cpu_device
@ -648,8 +641,6 @@ protected:
// construction/destruction
upi41_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int rom_size, int ram_size);
virtual util::disasm_interface *create_disassembler() override;
TIMER_CALLBACK_MEMBER( master_callback );
};

View File

@ -12,7 +12,7 @@
#include "emu.h"
#include "mcs48dsm.h"
mcs48_disassembler::mcs48_disassembler(bool upi41) : m_upi41(upi41)
mcs48_disassembler::mcs48_disassembler(bool upi41, bool i802x) : m_upi41(upi41), m_i802x(i802x)
{
}
@ -23,7 +23,7 @@ u32 mcs48_disassembler::opcode_alignment() const
u32 mcs48_disassembler::interface_flags() const
{
return m_upi41 ? 0 : PAGED;
return (m_upi41 || m_i802x) ? 0 : PAGED;
}
u32 mcs48_disassembler::page_address_bits() const
@ -39,8 +39,10 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
switch (opcodes.r8(cpc++))
{
case 0x00: util::stream_format(stream, "nop"); break;
case 0x02: if (!m_upi41)
util::stream_format(stream, "out bus,a");
case 0x02: if (m_i802x)
util::stream_format(stream, "illegal");
else if (!m_upi41)
util::stream_format(stream, "outl bus,a");
else
util::stream_format(stream, "out dbb,a");
break;
@ -48,7 +50,9 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x04: util::stream_format(stream, "jmp $0%02X", params.r8(cpc++)); break;
case 0x05: util::stream_format(stream, "en i"); break;
case 0x07: util::stream_format(stream, "dec a"); break;
case 0x08: if (!m_upi41)
case 0x08: if (m_i802x)
util::stream_format(stream, "in a,p0");
else if (!m_upi41)
util::stream_format(stream, "in a,bus");
else
util::stream_format(stream, "illegal");
@ -61,7 +65,11 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x0f: util::stream_format(stream, "movd a,p7"); break;
case 0x10: util::stream_format(stream, "inc @r0"); break;
case 0x11: util::stream_format(stream, "inc @r1"); break;
case 0x12: util::stream_format(stream, "jb0 $%03X", (pc & 0x700) | params.r8(cpc++)); break;
case 0x12: if (!m_i802x)
util::stream_format(stream, "jb0 $%03X", (pc & 0x700) | params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0x13: util::stream_format(stream, "addc a,#$%02X", params.r8(cpc++)); break;
case 0x14: util::stream_format(stream, "call $0%02X", params.r8(cpc++)); flags = STEP_OVER; break;
case 0x15: util::stream_format(stream, "dis i"); break;
@ -97,7 +105,11 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x2f: util::stream_format(stream, "xch a,r7"); break;
case 0x30: util::stream_format(stream, "xchd a,@r0"); break;
case 0x31: util::stream_format(stream, "xchd a,@r1"); break;
case 0x32: util::stream_format(stream, "jb1 $%03X", (pc & 0x700) | params.r8(cpc++)); break;
case 0x32: if (!m_i802x)
util::stream_format(stream, "jb1 $%03X", (pc & 0x700) | params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0x34: util::stream_format(stream, "call $1%02X", params.r8(cpc++)); flags = STEP_OVER; break;
case 0x35: util::stream_format(stream, "dis tcnti"); break;
case 0x36: util::stream_format(stream, "jt0 $%03X", (pc & 0x700) | params.r8(cpc++)); break;
@ -126,7 +138,11 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x4f: util::stream_format(stream, "orl a,r7"); break;
case 0x50: util::stream_format(stream, "anl a,@r0"); break;
case 0x51: util::stream_format(stream, "anl a,@r1"); break;
case 0x52: util::stream_format(stream, "jb2 $%03X", (pc & 0x700) | params.r8(cpc++)); break;
case 0x52: if (!m_i802x)
util::stream_format(stream, "jb2 $%03X", (pc & 0x700) | params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0x53: util::stream_format(stream, "anl a,#$%02X", params.r8(cpc++)); break;
case 0x54: util::stream_format(stream, "call $2%02X", params.r8(cpc++)); flags = STEP_OVER; break;
case 0x55: util::stream_format(stream, "strt t"); break;
@ -156,14 +172,22 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x6f: util::stream_format(stream, "add a,r7"); break;
case 0x70: util::stream_format(stream, "addc a,@r0"); break;
case 0x71: util::stream_format(stream, "addc a,@r1"); break;
case 0x72: util::stream_format(stream, "jb3 $%03X", (pc & 0x700) | params.r8(cpc++)); break;
case 0x72: if (!m_i802x)
util::stream_format(stream, "jb3 $%03X", (pc & 0x700) | params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0x74: util::stream_format(stream, "call $3%02X", params.r8(cpc++)); flags = STEP_OVER; break;
case 0x75: if (!m_upi41)
case 0x75: if (!m_upi41 && !m_i802x)
util::stream_format(stream, "ent0 clk");
else
util::stream_format(stream, "illegal");
break;
case 0x76: util::stream_format(stream, "jf1 $%03X", (pc & 0x700) | params.r8(cpc++)); break;
case 0x76: if (!m_i802x)
util::stream_format(stream, "jf1 $%03X", (pc & 0x700) | params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0x77: util::stream_format(stream, "rr a"); break;
case 0x78: util::stream_format(stream, "addc a,r0"); break;
case 0x79: util::stream_format(stream, "addc a,r1"); break;
@ -173,58 +197,97 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0x7d: util::stream_format(stream, "addc a,r5"); break;
case 0x7e: util::stream_format(stream, "addc a,r6"); break;
case 0x7f: util::stream_format(stream, "addc a,r7"); break;
case 0x80: if (!m_upi41)
case 0x80: if (m_i802x)
util::stream_format(stream, "rad");
else if (!m_upi41)
util::stream_format(stream, "movx a,@r0");
else
util::stream_format(stream, "illegal");
break;
case 0x81: if (!m_upi41)
case 0x81: if (!m_upi41 && !m_i802x)
util::stream_format(stream, "movx a,@r1");
else
util::stream_format(stream, "illegal");
break;
case 0x83: util::stream_format(stream, "ret"); flags = STEP_OUT; break;
case 0x84: util::stream_format(stream, "jmp $4%02X", params.r8(cpc++)); break;
case 0x85: util::stream_format(stream, "clr f0"); break;
case 0x86: if (!m_upi41)
case 0x85: if (!m_i802x)
util::stream_format(stream, "clr f0");
else
util::stream_format(stream, "sel an0");
break;
case 0x86: if (m_i802x)
util::stream_format(stream, "illegal");
else if (!m_upi41)
util::stream_format(stream, "jni $%03X", (pc & 0x700) | params.r8(cpc++));
else
util::stream_format(stream, "jobf $%03X", (pc & 0x700) | params.r8(cpc++));
break;
case 0x88: if (!m_upi41)
case 0x88: if (!m_upi41 && !m_i802x)
util::stream_format(stream, "orl bus,#$%02X", params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0x89: util::stream_format(stream, "orl p1,#$%02X", params.r8(cpc++)); break;
case 0x8a: util::stream_format(stream, "orl p2,#$%02X", params.r8(cpc++)); break;
case 0x89: if (!m_i802x)
util::stream_format(stream, "orl p1,#$%02X", params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0x8a: if (!m_i802x)
util::stream_format(stream, "orl p2,#$%02X", params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0x8c: util::stream_format(stream, "orld p4,a"); break;
case 0x8d: util::stream_format(stream, "orld p5,a"); break;
case 0x8e: util::stream_format(stream, "orld p6,a"); break;
case 0x8f: util::stream_format(stream, "orld p7,a"); break;
case 0x90: if (!m_upi41)
case 0x90: if (m_i802x)
util::stream_format(stream, "outl p0,a");
else if (!m_upi41)
util::stream_format(stream, "movx @r0,a");
else
util::stream_format(stream, "mov sts,a");
break;
case 0x91: if (!m_upi41)
case 0x91: if (!m_upi41 && !m_i802x)
util::stream_format(stream, "movx @r1,a");
else
util::stream_format(stream, "illegal");
break;
case 0x92: util::stream_format(stream, "jb4 $%03X", (pc & 0x700) | params.r8(cpc++)); break;
case 0x93: util::stream_format(stream, "retr"); flags = STEP_OUT; break;
case 0x92: if (!m_i802x)
util::stream_format(stream, "jb4 $%03X", (pc & 0x700) | params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0x93: if (!m_i802x)
util::stream_format(stream, "retr");
else
util::stream_format(stream, "reti");
flags = STEP_OUT;
break;
case 0x94: util::stream_format(stream, "call $4%02X", params.r8(cpc++)); flags = STEP_OVER; break;
case 0x95: util::stream_format(stream, "cpl f0"); break;
case 0x95: if (m_i802x)
util::stream_format(stream, "cpl f0");
else
util::stream_format(stream, "sel an1");
break;
case 0x96: util::stream_format(stream, "jnz $%03X", (pc & 0x700) | params.r8(cpc++)); break;
case 0x97: util::stream_format(stream, "clr c"); break;
case 0x98: if (!m_upi41)
case 0x98: if (!m_upi41 && !m_i802x)
util::stream_format(stream, "anl bus,#$%02X", params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0x99: util::stream_format(stream, "anl p1,#$%02X", params.r8(cpc++)); break;
case 0x9a: util::stream_format(stream, "anl p2,#$%02X", params.r8(cpc++)); break;
case 0x99: if (!m_i802x)
util::stream_format(stream, "anl p1,#$%02X", params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0x9a: if (!m_i802x)
util::stream_format(stream, "anl p2,#$%02X", params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0x9c: util::stream_format(stream, "anld p4,a"); break;
case 0x9d: util::stream_format(stream, "anld p5,a"); break;
case 0x9e: util::stream_format(stream, "anld p6,a"); break;
@ -233,7 +296,11 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0xa1: util::stream_format(stream, "mov @r1,a"); break;
case 0xa3: util::stream_format(stream, "movp a,@a"); break;
case 0xa4: util::stream_format(stream, "jmp $5%02X", params.r8(cpc++)); break;
case 0xa5: util::stream_format(stream, "clr f1"); break;
case 0xa5: if (!m_i802x)
util::stream_format(stream, "clr f1");
else
util::stream_format(stream, "illegal");
break;
case 0xa7: util::stream_format(stream, "cpl c"); break;
case 0xa8: util::stream_format(stream, "mov r0,a"); break;
case 0xa9: util::stream_format(stream, "mov r1,a"); break;
@ -245,11 +312,23 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0xaf: util::stream_format(stream, "mov r7,a"); break;
case 0xb0: util::stream_format(stream, "mov @r0,#$%02X", params.r8(cpc++)); break;
case 0xb1: util::stream_format(stream, "mov @r1,#$%02X", params.r8(cpc++)); break;
case 0xb2: util::stream_format(stream, "jb5 $%03X", (pc & 0x700) | params.r8(cpc++)); break;
case 0xb2: if (!m_i802x)
util::stream_format(stream, "jb5 $%03X", (pc & 0x700) | params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0xb3: util::stream_format(stream, "jmpp @a"); break;
case 0xb4: util::stream_format(stream, "call $5%02X", params.r8(cpc++)); flags = STEP_OVER; break;
case 0xb5: util::stream_format(stream, "cpl f1"); break;
case 0xb6: util::stream_format(stream, "jf0 $%03X", (pc & 0x700) | params.r8(cpc++)); break;
case 0xb5: if (!m_i802x)
util::stream_format(stream, "cpl f1");
else
util::stream_format(stream, "illegal");
break;
case 0xb6: if (!m_i802x)
util::stream_format(stream, "jf0 $%03X", (pc & 0x700) | params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0xb8: util::stream_format(stream, "mov r0,#$%02X", params.r8(cpc++)); break;
case 0xb9: util::stream_format(stream, "mov r1,#$%02X", params.r8(cpc++)); break;
case 0xba: util::stream_format(stream, "mov r2,#$%02X", params.r8(cpc++)); break;
@ -259,29 +338,80 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0xbe: util::stream_format(stream, "mov r6,#$%02X", params.r8(cpc++)); break;
case 0xbf: util::stream_format(stream, "mov r7,#$%02X", params.r8(cpc++)); break;
case 0xc4: util::stream_format(stream, "jmp $6%02X", params.r8(cpc++)); break;
case 0xc5: util::stream_format(stream, "sel rb0"); break;
case 0xc5: if (!m_i802x)
util::stream_format(stream, "sel rb0");
else
util::stream_format(stream, "illegal");
break;
case 0xc6: util::stream_format(stream, "jz $%03X", (pc & 0x700) | params.r8(cpc++)); break;
case 0xc7: util::stream_format(stream, "mov a,psw"); break;
case 0xc8: util::stream_format(stream, "dec r0"); break;
case 0xc9: util::stream_format(stream, "dec r1"); break;
case 0xca: util::stream_format(stream, "dec r2"); break;
case 0xcb: util::stream_format(stream, "dec r3"); break;
case 0xcc: util::stream_format(stream, "dec r4"); break;
case 0xcd: util::stream_format(stream, "dec r5"); break;
case 0xce: util::stream_format(stream, "dec r6"); break;
case 0xcf: util::stream_format(stream, "dec r7"); break;
case 0xc7: if (!m_i802x)
util::stream_format(stream, "mov a,psw");
else
util::stream_format(stream, "illegal");
break;
case 0xc8: if (!m_i802x)
util::stream_format(stream, "dec r0");
else
util::stream_format(stream, "illegal");
break;
case 0xc9: if (!m_i802x)
util::stream_format(stream, "dec r1");
else
util::stream_format(stream, "illegal");
break;
case 0xca: if (!m_i802x)
util::stream_format(stream, "dec r2");
else
util::stream_format(stream, "illegal");
break;
case 0xcb: if (!m_i802x)
util::stream_format(stream, "dec r3");
else
util::stream_format(stream, "illegal");
break;
case 0xcc: if (!m_i802x)
util::stream_format(stream, "dec r4");
else
util::stream_format(stream, "illegal");
break;
case 0xcd: if (!m_i802x)
util::stream_format(stream, "dec r5");
else
util::stream_format(stream, "illegal");
break;
case 0xce: if (!m_i802x)
util::stream_format(stream, "dec r6");
else
util::stream_format(stream, "illegal");
break;
case 0xcf: if (!m_i802x)
util::stream_format(stream, "dec r7");
else
util::stream_format(stream, "illegal");
break;
case 0xd0: util::stream_format(stream, "xrl a,@r0"); break;
case 0xd1: util::stream_format(stream, "xrl a,@r1"); break;
case 0xd2: util::stream_format(stream, "jb6 $%03X", (pc & 0x700) | params.r8(cpc++)); break;
case 0xd2: if (!m_i802x)
util::stream_format(stream, "jb6 $%03X", (pc & 0x700) | params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0xd3: util::stream_format(stream, "xrl a,#$%02X", params.r8(cpc++)); break;
case 0xd4: util::stream_format(stream, "call $6%02X", params.r8(cpc++)); flags = STEP_OVER; break;
case 0xd5: util::stream_format(stream, "sel rb1"); break;
case 0xd5: if (!m_i802x)
util::stream_format(stream, "sel rb1");
else
util::stream_format(stream, "illegal");
break;
case 0xd6: if (!m_upi41)
util::stream_format(stream, "illegal");
else
util::stream_format(stream, "jnibf $%03X", (pc & 0x700) | params.r8(cpc++));
break;
case 0xd7: util::stream_format(stream, "mov psw,a"); break;
case 0xd7: if (!m_i802x)
util::stream_format(stream, "mov psw,a");
else
util::stream_format(stream, "illegal");
case 0xd8: util::stream_format(stream, "xrl a,r0"); break;
case 0xd9: util::stream_format(stream, "xrl a,r1"); break;
case 0xda: util::stream_format(stream, "xrl a,r2"); break;
@ -290,9 +420,15 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0xdd: util::stream_format(stream, "xrl a,r5"); break;
case 0xde: util::stream_format(stream, "xrl a,r6"); break;
case 0xdf: util::stream_format(stream, "xrl a,r7"); break;
case 0xe3: util::stream_format(stream, "movp3 a,@a"); break;
case 0xe3: if (!m_i802x)
util::stream_format(stream, "movp3 a,@a");
else
util::stream_format(stream, "illegal");
break;
case 0xe4: util::stream_format(stream, "jmp $7%02X", params.r8(cpc++)); break;
case 0xe5: if (!m_upi41)
case 0xe5: if (m_i802x)
util::stream_format(stream, "illegal");
else if (!m_upi41)
util::stream_format(stream, "sel mb0");
else
util::stream_format(stream, "en dma");
@ -309,11 +445,17 @@ offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const da
case 0xef: util::stream_format(stream, "djnz r7,$%03X", (pc & 0x700) | params.r8(cpc++)); flags = STEP_OVER; break;
case 0xf0: util::stream_format(stream, "mov a,@r0"); break;
case 0xf1: util::stream_format(stream, "mov a,@r1"); break;
case 0xf2: util::stream_format(stream, "jb7 $%03X", (pc & 0x700) | params.r8(cpc++)); break;
case 0xf4: util::stream_format(stream, "call $7%02X", params.r8(cpc++)); flags = STEP_OVER; break;
case 0xf5: if (!m_upi41)
util::stream_format(stream, "sel mb1");
case 0xf2: if (!m_i802x)
util::stream_format(stream, "jb7 $%03X", (pc & 0x700) | params.r8(cpc++));
else
util::stream_format(stream, "illegal");
break;
case 0xf4: util::stream_format(stream, "call $7%02X", params.r8(cpc++)); flags = STEP_OVER; break;
case 0xf5: if (m_i802x)
util::stream_format(stream, "illegal");
else if (!m_upi41)
util::stream_format(stream, "sel mb1");
else if (!m_i802x)
util::stream_format(stream, "en flags");
break;
case 0xf6: util::stream_format(stream, "jc $%03X", (pc & 0x700) | params.r8(cpc++)); break;

View File

@ -18,7 +18,7 @@
class mcs48_disassembler : public util::disasm_interface
{
public:
mcs48_disassembler(bool upi41);
mcs48_disassembler(bool upi41, bool i802x);
virtual ~mcs48_disassembler() = default;
virtual u32 opcode_alignment() const override;
@ -28,6 +28,7 @@ public:
private:
bool m_upi41;
bool m_i802x;
};
#endif

View File

@ -359,11 +359,6 @@ WRITE_LINE_MEMBER(k28_state::mcu_prog_w)
}
static ADDRESS_MAP_START( k28_mcu_map, AS_IO, 8, k28_state )
AM_RANGE(0x00, 0x00) AM_MIRROR(0xff) AM_WRITE(mcu_p0_w)
ADDRESS_MAP_END
/***************************************************************************
@ -455,7 +450,7 @@ MACHINE_CONFIG_START(k28_state::k28)
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", I8021, XTAL(3'579'545))
MCFG_CPU_IO_MAP(k28_mcu_map)
MCFG_MCS48_PORT_BUS_OUT_CB(WRITE8(k28_state, mcu_p0_w))
MCFG_MCS48_PORT_P1_IN_CB(READ8(k28_state, mcu_p1_r))
MCFG_MCS48_PORT_P2_IN_CB(READ8(k28_state, mcu_p2_r))
MCFG_MCS48_PORT_P2_OUT_CB(WRITE8(k28_state, mcu_p2_w))

View File

@ -633,14 +633,9 @@ static INPUT_PORTS_START( microvision )
INPUT_PORTS_END
static ADDRESS_MAP_START( microvision_8021_io, AS_IO, 8, microvision_state )
AM_RANGE( 0x00, 0xFF ) AM_WRITE( i8021_p0_write )
ADDRESS_MAP_END
MACHINE_CONFIG_START(microvision_state::microvision)
MCFG_CPU_ADD("maincpu1", I8021, 2000000) // approximately
MCFG_CPU_IO_MAP(microvision_8021_io)
MCFG_MCS48_PORT_BUS_OUT_CB(WRITE8(microvision_state, i8021_p0_write))
MCFG_MCS48_PORT_P1_OUT_CB(WRITE8(microvision_state, i8021_p1_write))
MCFG_MCS48_PORT_P2_OUT_CB(WRITE8(microvision_state, i8021_p2_write))
MCFG_MCS48_PORT_T1_IN_CB(READLINE(microvision_state, i8021_t1_read))

View File

@ -75,18 +75,6 @@ ROM_START( mackbd )
ROM_LOAD( "341-0332-a.bin", 0x000400, 0x000400, CRC(6554f5b6) SHA1(a80404a122d74721cda13b285c412057c2c78bd7) )
ROM_END
//-------------------------------------------------
// ADDRESS_MAP
//-------------------------------------------------
static ADDRESS_MAP_START( mackbd_map, AS_PROGRAM, 8, mackbd_device )
AM_RANGE(0x0000, 0x03ff) AM_ROM AM_REGION(MACKBD_CPU_TAG, 0)
ADDRESS_MAP_END
static ADDRESS_MAP_START( mackbd_io_map, AS_IO, 8, mackbd_device )
AM_RANGE(0x2f, 0x36) AM_WRITE(p0_w)
ADDRESS_MAP_END
static INPUT_PORTS_START( mackbd )
PORT_START("COL0")
@ -174,9 +162,8 @@ INPUT_PORTS_END
MACHINE_CONFIG_START(mackbd_device::device_add_mconfig)
MCFG_CPU_ADD(MACKBD_CPU_TAG, I8021, 3000000) // "the approximate clock rate of the MPU is 3 MHz"
MCFG_CPU_PROGRAM_MAP(mackbd_map)
MCFG_CPU_IO_MAP(mackbd_io_map)
MCFG_MCS48_PORT_BUS_IN_CB(READ8(mackbd_device, p0_r))
MCFG_MCS48_PORT_BUS_OUT_CB(WRITE8(mackbd_device, p0_w))
MCFG_MCS48_PORT_P1_IN_CB(READ8(mackbd_device, p1_r))
MCFG_MCS48_PORT_P1_OUT_CB(WRITE8(mackbd_device, p1_w))
MCFG_MCS48_PORT_P2_IN_CB(READ8(mackbd_device, p2_r))

View File

@ -337,6 +337,7 @@ static const dasm_table_entry dasm_table[] =
{ "i4004", le, 0, []() -> util::disasm_interface * { return new i4004_disassembler; } },
{ "i4040", le, 0, []() -> util::disasm_interface * { return new i4040_disassembler; } },
{ "i8008", le, 0, []() -> util::disasm_interface * { return new i8008_disassembler; } },
{ "i802x", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(false, true); } },
{ "i8051", le, 0, []() -> util::disasm_interface * { return new i8051_disassembler; } },
{ "i8052", le, 0, []() -> util::disasm_interface * { return new i8052_disassembler; } },
{ "i8085", le, 0, []() -> util::disasm_interface * { return new i8085_disassembler; } },
@ -382,7 +383,7 @@ static const dasm_table_entry dasm_table[] =
{ "mb86233", le, -2, []() -> util::disasm_interface * { return new mb86233_disassembler; } },
{ "mb86235", le, -3, []() -> util::disasm_interface * { return new mb86235_disassembler; } },
{ "mb88", le, 0, []() -> util::disasm_interface * { return new mb88_disassembler; } },
{ "mcs48", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(false); } },
{ "mcs48", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(false, false); } },
{ "minx", le, 0, []() -> util::disasm_interface * { return new minx_disassembler; } },
{ "mips3be", be, 0, []() -> util::disasm_interface * { return new mips3_disassembler; } },
{ "mips3le", le, 0, []() -> util::disasm_interface * { return new mips3_disassembler; } },
@ -459,7 +460,7 @@ static const dasm_table_entry dasm_table[] =
{ "upd7807", le, 0, []() -> util::disasm_interface * { return new upd7807_disassembler; } },
{ "upd7810", le, 0, []() -> util::disasm_interface * { return new upd7810_disassembler; } },
{ "upd78c05", le, 0, []() -> util::disasm_interface * { return new upd78c05_disassembler; } },
{ "upi41", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(true); } },
{ "upi41", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(true, false); } },
{ "v60", le, 0, []() -> util::disasm_interface * { return new v60_disassembler; } },
{ "v810", le, 0, []() -> util::disasm_interface * { return new v810_disassembler; } },
{ "x86_16", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 16; return new i386_disassembler(&i386_unidasm); } },