From ef8ac6eee82fb1c033cf32925ffdcdac146b51f1 Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Sat, 3 Sep 2022 23:55:53 +0200 Subject: * new WORKING machine ---- MTU-130 [Olivier Galibert, David Williams, Disk Blitz, Eric Wright] --- scripts/src/cpu.lua | 5 + src/devices/cpu/m6502/dm6502mtu.lst | 20 + src/devices/cpu/m6502/m6502.cpp | 14 +- src/devices/cpu/m6502/m6502mtu.cpp | 76 ++ src/devices/cpu/m6502/m6502mtu.h | 151 +++ src/devices/cpu/m6502/om6502mtu.lst | 2007 +++++++++++++++++++++++++++++++++++ src/devices/machine/upd765.cpp | 2 + src/emu/xtal.cpp | 1 + src/mame/mame.lst | 3 + src/mame/misc/mtu130.cpp | 590 ++++++++++ 10 files changed, 2863 insertions(+), 6 deletions(-) create mode 100644 src/devices/cpu/m6502/dm6502mtu.lst create mode 100644 src/devices/cpu/m6502/m6502mtu.cpp create mode 100644 src/devices/cpu/m6502/m6502mtu.h create mode 100644 src/devices/cpu/m6502/om6502mtu.lst create mode 100644 src/mame/misc/mtu130.cpp diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index 0217ccebeec..8ca5f85418c 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -1575,6 +1575,7 @@ end --@src/devices/cpu/m6502/m740.h,CPUS["M6502"] = true --@src/devices/cpu/m6502/m3745x.h,CPUS["M6502"] = true --@src/devices/cpu/m6502/m5074x.h,CPUS["M6502"] = true +--@src/devices/cpu/m6502/m6502mtu.h,CPUS["M6502"] = true --@src/devices/cpu/m6502/st2xxx.h,CPUS["ST2XXX"] = true --@src/devices/cpu/m6502/st2204.h,CPUS["ST2XXX"] = true --@src/devices/cpu/m6502/st2205u.h,CPUS["ST2XXX"] = true @@ -1592,6 +1593,8 @@ if CPUS["M6502"] then MAME_DIR .. "src/devices/cpu/m6502/m4510.h", MAME_DIR .. "src/devices/cpu/m6502/m6502.cpp", MAME_DIR .. "src/devices/cpu/m6502/m6502.h", + MAME_DIR .. "src/devices/cpu/m6502/m6502mtu.cpp", + MAME_DIR .. "src/devices/cpu/m6502/m6502mtu.h", MAME_DIR .. "src/devices/cpu/m6502/m65c02.cpp", MAME_DIR .. "src/devices/cpu/m6502/m65c02.h", MAME_DIR .. "src/devices/cpu/m6502/m65ce02.cpp", @@ -1634,6 +1637,7 @@ if CPUS["M6502"] then { MAME_DIR .. "src/devices/cpu/m6502/odeco16.lst", GEN_DIR .. "emu/cpu/m6502/deco16.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/ddeco16.lst" }, {"@echo Generating deco16 instruction source file...", PYTHON .. " $(1) s deco16 $(<) $(2) $(@)" }}, { MAME_DIR .. "src/devices/cpu/m6502/om4510.lst", GEN_DIR .. "emu/cpu/m6502/m4510.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dm4510.lst" }, {"@echo Generating m4510 instruction source file...", PYTHON .. " $(1) s m4510 $(<) $(2) $(@)" }}, { MAME_DIR .. "src/devices/cpu/m6502/om6502.lst", GEN_DIR .. "emu/cpu/m6502/m6502.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dm6502.lst" }, {"@echo Generating m6502 instruction source file...", PYTHON .. " $(1) s m6502 $(<) $(2) $(@)" }}, + { MAME_DIR .. "src/devices/cpu/m6502/om6502mtu.lst", GEN_DIR .. "emu/cpu/m6502/m6502mtu.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dm6502mtu.lst" }, {"@echo Generating m6502 MTU instruction source file...", PYTHON .. " $(1) s m6502mtu $(<) $(2) $(@)" }}, { MAME_DIR .. "src/devices/cpu/m6502/om65c02.lst", GEN_DIR .. "emu/cpu/m6502/m65c02.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dm65c02.lst" }, {"@echo Generating m65c02 instruction source file...", PYTHON .. " $(1) s m65c02 $(<) $(2) $(@)" }}, { MAME_DIR .. "src/devices/cpu/m6502/om65ce02.lst", GEN_DIR .. "emu/cpu/m6502/m65ce02.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dm65ce02.lst" }, {"@echo Generating m65ce02 instruction source file...", PYTHON .. " $(1) s m65ce02 $(<) $(2) $(@)" }}, { MAME_DIR .. "src/devices/cpu/m6502/om6509.lst", GEN_DIR .. "emu/cpu/m6502/m6509.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dm6509.lst" }, {"@echo Generating m6509 instruction source file...", PYTHON .. " $(1) s m6509 $(<) $(2) $(@)" }}, @@ -1649,6 +1653,7 @@ if CPUS["M6502"] then { MAME_DIR .. "src/devices/cpu/m6502/deco16.cpp", GEN_DIR .. "emu/cpu/m6502/deco16.hxx" }, { MAME_DIR .. "src/devices/cpu/m6502/m4510.cpp", GEN_DIR .. "emu/cpu/m6502/m4510.hxx" }, { MAME_DIR .. "src/devices/cpu/m6502/m6502.cpp", GEN_DIR .. "emu/cpu/m6502/m6502.hxx" }, + { MAME_DIR .. "src/devices/cpu/m6502/m6502mtu.cpp", GEN_DIR .. "emu/cpu/m6502/m6502mtu.hxx" }, { MAME_DIR .. "src/devices/cpu/m6502/m65c02.cpp", GEN_DIR .. "emu/cpu/m6502/m65c02.hxx" }, { MAME_DIR .. "src/devices/cpu/m6502/m65ce02.cpp", GEN_DIR .. "emu/cpu/m6502/m65ce02.hxx" }, { MAME_DIR .. "src/devices/cpu/m6502/m6509.cpp", GEN_DIR .. "emu/cpu/m6502/m6509.hxx" }, diff --git a/src/devices/cpu/m6502/dm6502mtu.lst b/src/devices/cpu/m6502/dm6502mtu.lst new file mode 100644 index 00000000000..fb3f52e0c2a --- /dev/null +++ b/src/devices/cpu/m6502/dm6502mtu.lst @@ -0,0 +1,20 @@ +# license:BSD-3-Clause +# copyright-holders:Olivier Galibert +# m6502 MTU - external circuitry for transparent banking handling +brk_mtu_imp ora_mtu_idx kil_mtu_non slo_mtu_idx nop_mtu_zpg ora_mtu_zpg asl_mtu_zpg slo_mtu_zpg php_mtu_imp ora_mtu_imm asl_mtu_acc anc_mtu_imm nop_mtu_aba ora_mtu_aba asl_mtu_aba slo_mtu_aba +bpl_mtu_rel ora_mtu_idy kil_mtu_non slo_mtu_idy nop_mtu_zpx ora_mtu_zpx asl_mtu_zpx slo_mtu_zpx clc_mtu_imp ora_mtu_aby nop_mtu_imp slo_mtu_aby nop_mtu_abx ora_mtu_abx asl_mtu_abx slo_mtu_abx +jsr_mtu_adr and_mtu_idx kil_mtu_non rla_mtu_idx bit_mtu_zpg and_mtu_zpg rol_mtu_zpg rla_mtu_zpg plp_mtu_imp and_mtu_imm rol_mtu_acc anc_mtu_imm bit_mtu_aba and_mtu_aba rol_mtu_aba rla_mtu_aba +bmi_mtu_rel and_mtu_idy kil_mtu_non rla_mtu_idy nop_mtu_zpx and_mtu_zpx rol_mtu_zpx rla_mtu_zpx sec_mtu_imp and_mtu_aby nop_mtu_imp rla_mtu_aby nop_mtu_abx and_mtu_abx rol_mtu_abx rla_mtu_abx +rti_mtu_imp eor_mtu_idx kil_mtu_non sre_mtu_idx nop_mtu_zpg eor_mtu_zpg lsr_mtu_zpg sre_mtu_zpg pha_mtu_imp eor_mtu_imm lsr_mtu_acc asr_mtu_imm jmp_mtu_adr eor_mtu_aba lsr_mtu_aba sre_mtu_aba +bvc_mtu_rel eor_mtu_idy kil_mtu_non sre_mtu_idy nop_mtu_zpx eor_mtu_zpx lsr_mtu_zpx sre_mtu_zpx cli_mtu_imp eor_mtu_aby nop_mtu_imp sre_mtu_aby nop_mtu_abx eor_mtu_abx lsr_mtu_abx sre_mtu_abx +rts_mtu_imp adc_mtu_idx kil_mtu_non rra_mtu_idx nop_mtu_zpg adc_mtu_zpg ror_mtu_zpg rra_mtu_zpg pla_mtu_imp adc_mtu_imm ror_mtu_acc arr_mtu_imm jmp_mtu_ind adc_mtu_aba ror_mtu_aba rra_mtu_aba +bvs_mtu_rel adc_mtu_idy kil_mtu_non rra_mtu_idy nop_mtu_zpx adc_mtu_zpx ror_mtu_zpx rra_mtu_zpx sei_mtu_imp adc_mtu_aby nop_mtu_imp rra_mtu_aby nop_mtu_abx adc_mtu_abx ror_mtu_abx rra_mtu_abx +nop_mtu_imm sta_mtu_idx nop_mtu_imm sax_mtu_idx sty_mtu_zpg sta_mtu_zpg stx_mtu_zpg sax_mtu_zpg dey_mtu_imp nop_mtu_imm txa_mtu_imp ane_mtu_imm sty_mtu_aba sta_mtu_aba stx_mtu_aba sax_mtu_aba +bcc_mtu_rel sta_mtu_idy kil_mtu_non sha_mtu_idy sty_mtu_zpx sta_mtu_zpx stx_mtu_zpy sax_mtu_zpy tya_mtu_imp sta_mtu_aby txs_mtu_imp shs_mtu_aby shy_mtu_abx sta_mtu_abx shx_mtu_aby sha_mtu_aby +ldy_mtu_imm lda_mtu_idx ldx_mtu_imm lax_mtu_idx ldy_mtu_zpg lda_mtu_zpg ldx_mtu_zpg lax_mtu_zpg tay_mtu_imp lda_mtu_imm tax_mtu_imp lxa_mtu_imm ldy_mtu_aba lda_mtu_aba ldx_mtu_aba lax_mtu_aba +bcs_mtu_rel lda_mtu_idy kil_mtu_non lax_mtu_idy ldy_mtu_zpx lda_mtu_zpx ldx_mtu_zpy lax_mtu_zpy clv_mtu_imp lda_mtu_aby tsx_mtu_imp las_mtu_aby ldy_mtu_abx lda_mtu_abx ldx_mtu_aby lax_mtu_aby +cpy_mtu_imm cmp_mtu_idx nop_mtu_imm dcp_mtu_idx cpy_mtu_zpg cmp_mtu_zpg dec_mtu_zpg dcp_mtu_zpg iny_mtu_imp cmp_mtu_imm dex_mtu_imp sbx_mtu_imm cpy_mtu_aba cmp_mtu_aba dec_mtu_aba dcp_mtu_aba +bne_mtu_rel cmp_mtu_idy kil_mtu_non dcp_mtu_idy nop_mtu_zpx cmp_mtu_zpx dec_mtu_zpx dcp_mtu_zpx cld_mtu_imp cmp_mtu_aby nop_mtu_imp dcp_mtu_aby nop_mtu_abx cmp_mtu_abx dec_mtu_abx dcp_mtu_abx +cpx_mtu_imm sbc_mtu_idx nop_mtu_imm isb_mtu_idx cpx_mtu_zpg sbc_mtu_zpg inc_mtu_zpg isb_mtu_zpg inx_mtu_imp sbc_mtu_imm nop_mtu_imp sbc_mtu_imm cpx_mtu_aba sbc_mtu_aba inc_mtu_aba isb_mtu_aba +beq_mtu_rel sbc_mtu_idy kil_mtu_non isb_mtu_idy nop_mtu_zpx sbc_mtu_zpx inc_mtu_zpx isb_mtu_zpx sed_mtu_imp sbc_mtu_aby nop_mtu_imp isb_mtu_aby nop_mtu_abx sbc_mtu_abx inc_mtu_abx isb_mtu_abx +reset_mtu diff --git a/src/devices/cpu/m6502/m6502.cpp b/src/devices/cpu/m6502/m6502.cpp index 5db4186ebd9..3817ab33187 100644 --- a/src/devices/cpu/m6502/m6502.cpp +++ b/src/devices/cpu/m6502/m6502.cpp @@ -43,12 +43,14 @@ void m6502_device::device_start() void m6502_device::init() { - space(AS_PROGRAM).cache(mintf->cprogram); - space(has_space(AS_OPCODES) ? AS_OPCODES : AS_PROGRAM).cache(mintf->csprogram); - if(space(AS_PROGRAM).addr_width() > 14) - space(AS_PROGRAM).specific(mintf->program); - else - space(AS_PROGRAM).specific(mintf->program14); + if(mintf) { + space(AS_PROGRAM).cache(mintf->cprogram); + space(has_space(AS_OPCODES) ? AS_OPCODES : AS_PROGRAM).cache(mintf->csprogram); + if(space(AS_PROGRAM).addr_width() > 14) + space(AS_PROGRAM).specific(mintf->program); + else + space(AS_PROGRAM).specific(mintf->program14); + } sync_w.resolve_safe(); diff --git a/src/devices/cpu/m6502/m6502mtu.cpp b/src/devices/cpu/m6502/m6502mtu.cpp new file mode 100644 index 00000000000..917ca93158e --- /dev/null +++ b/src/devices/cpu/m6502/m6502mtu.cpp @@ -0,0 +1,76 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m6502mtu.cpp + + M6502 with MTU external banking hardware + +***************************************************************************/ + +#include "emu.h" +#include "m6502mtu.h" + +DEFINE_DEVICE_TYPE(M6502MTU, m6502mtu_device, "m6502mtu", "M6502 with MTU banking") + +m6502mtu_device::m6502mtu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + m6502_device(mconfig, M6502MTU, tag, owner, clock) +{ + program_config.m_addr_width = 18; + sprogram_config.m_addr_width = 18; +} + +void m6502mtu_device::device_start() +{ + mintf = nullptr; + space(AS_PROGRAM).specific(cprogram); + space(has_space(AS_OPCODES) ? AS_OPCODES : AS_PROGRAM).specific(csprogram); + + save_item(NAME(low_instruction)); + save_item(NAME(interrupt_mode)); + save_item(NAME(pbank)); + save_item(NAME(dbank)); + + init(); +} + +void m6502mtu_device::device_reset() +{ + m6502_device::device_reset(); + pbank = 0; + dbank = 0; + low_instruction = false; + interrupt_mode = false; +} + + +void m6502mtu_device::prefetchd() +{ + sync = true; + sync_w(ASSERT_LINE); + NPC = PC; + low_instruction = PC < 0x200; + IR = csprogram.read_byte(low_instruction || interrupt_mode ? PC : PC | pbank); + sync = false; + sync_w(CLEAR_LINE); + + if((nmi_pending || ((irq_state || apu_irq_state) && !(P & F_I))) && !inhibit_interrupts) { + irq_taken = true; + IR = 0x00; + } else + PC++; +} + +void m6502mtu_device::prefetchd_noirq() +{ + sync = true; + sync_w(ASSERT_LINE); + NPC = PC; + low_instruction = PC < 0x200; + IR = csprogram.read_byte(low_instruction || interrupt_mode ? PC : PC | pbank); + sync = false; + sync_w(CLEAR_LINE); + PC++; +} + +#include "cpu/m6502/m6502mtu.hxx" diff --git a/src/devices/cpu/m6502/m6502mtu.h b/src/devices/cpu/m6502/m6502mtu.h new file mode 100644 index 00000000000..066ed1cab58 --- /dev/null +++ b/src/devices/cpu/m6502/m6502mtu.h @@ -0,0 +1,151 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m6502mtu.h + + M6502 with MTU external banking hardware + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M6502MTU_H +#define MAME_CPU_M6502_M6502MTU_H + +#include "m6502.h" + +class m6502mtu_device : public m6502_device { +public: + m6502mtu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual void do_exec_full() override; + virtual void do_exec_partial() override; + + void set_pbank(u32 bank) { pbank = bank << 16; } + void set_dbank(u32 bank) { dbank = bank << 16; } + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + memory_access<18, 0, 0, ENDIANNESS_LITTLE>::specific cprogram; + memory_access<18, 0, 0, ENDIANNESS_LITTLE>::specific csprogram; + + bool low_instruction, interrupt_mode; + u32 pbank, dbank; + + uint8_t readd(uint16_t adr) { return cprogram.read_byte(low_instruction || interrupt_mode ? adr : adr | pbank); } + void writed(uint16_t adr, uint8_t val) { cprogram.write_byte(low_instruction || interrupt_mode ? adr : adr | pbank, val); } + uint8_t readi(uint16_t adr) { return cprogram.read_byte(adr | dbank); } + void writei(uint16_t adr, uint8_t val) { cprogram.write_byte(adr | dbank, val); } + uint8_t readil(uint16_t adr) { return cprogram.read_byte(low_instruction ? adr | dbank : adr); } + void writeil(uint16_t adr, uint8_t val) { cprogram.write_byte(low_instruction ? adr | dbank : adr, val); } + uint8_t readd_arg(uint16_t adr) { return readd(adr); } + uint8_t readd_pc() { return readd(PC++); } + uint8_t readd_pc_noinc() { return readd(PC); } + void prefetchd(); + void prefetchd_noirq(); + + void interrupt_mode_on() { interrupt_mode = true; } + void interrupt_mode_off() { interrupt_mode = false; } + +#define O(o) void o ## _full(); void o ## _partial() + + // NMOS 6502 opcodes + // documented opcodes + O(adc_mtu_aba); O(adc_mtu_abx); O(adc_mtu_aby); O(adc_mtu_idx); O(adc_mtu_idy); O(adc_mtu_imm); O(adc_mtu_zpg); O(adc_mtu_zpx); + O(and_mtu_aba); O(and_mtu_abx); O(and_mtu_aby); O(and_mtu_imm); O(and_mtu_idx); O(and_mtu_idy); O(and_mtu_zpg); O(and_mtu_zpx); + O(asl_mtu_aba); O(asl_mtu_abx); O(asl_mtu_acc); O(asl_mtu_zpg); O(asl_mtu_zpx); + O(bcc_mtu_rel); + O(bcs_mtu_rel); + O(beq_mtu_rel); + O(bit_mtu_aba); O(bit_mtu_zpg); + O(bmi_mtu_rel); + O(bne_mtu_rel); + O(bpl_mtu_rel); + O(brk_mtu_imp); + O(bvc_mtu_rel); + O(bvs_mtu_rel); + O(clc_mtu_imp); + O(cld_mtu_imp); + O(cli_mtu_imp); + O(clv_mtu_imp); + O(cmp_mtu_aba); O(cmp_mtu_abx); O(cmp_mtu_aby); O(cmp_mtu_idx); O(cmp_mtu_idy); O(cmp_mtu_imm); O(cmp_mtu_zpg); O(cmp_mtu_zpx); + O(cpx_mtu_aba); O(cpx_mtu_imm); O(cpx_mtu_zpg); + O(cpy_mtu_aba); O(cpy_mtu_imm); O(cpy_mtu_zpg); + O(dec_mtu_aba); O(dec_mtu_abx); O(dec_mtu_zpg); O(dec_mtu_zpx); + O(dex_mtu_imp); + O(dey_mtu_imp); + O(eor_mtu_aba); O(eor_mtu_abx); O(eor_mtu_aby); O(eor_mtu_idx); O(eor_mtu_idy); O(eor_mtu_imm); O(eor_mtu_zpg); O(eor_mtu_zpx); + O(inc_mtu_aba); O(inc_mtu_abx); O(inc_mtu_zpg); O(inc_mtu_zpx); + O(inx_mtu_imp); + O(iny_mtu_imp); + O(jmp_mtu_adr); O(jmp_mtu_ind); + O(jsr_mtu_adr); + O(lda_mtu_aba); O(lda_mtu_abx); O(lda_mtu_aby); O(lda_mtu_idx); O(lda_mtu_idy); O(lda_mtu_imm); O(lda_mtu_zpg); O(lda_mtu_zpx); + O(ldx_mtu_aba); O(ldx_mtu_aby); O(ldx_mtu_imm); O(ldx_mtu_zpg); O(ldx_mtu_zpy); + O(ldy_mtu_aba); O(ldy_mtu_abx); O(ldy_mtu_imm); O(ldy_mtu_zpg); O(ldy_mtu_zpx); + O(lsr_mtu_aba); O(lsr_mtu_abx); O(lsr_mtu_acc); O(lsr_mtu_zpg); O(lsr_mtu_zpx); + O(nop_mtu_imp); + O(ora_mtu_aba); O(ora_mtu_abx); O(ora_mtu_aby); O(ora_mtu_imm); O(ora_mtu_idx); O(ora_mtu_idy); O(ora_mtu_zpg); O(ora_mtu_zpx); + O(pha_mtu_imp); + O(php_mtu_imp); + O(pla_mtu_imp); + O(plp_mtu_imp); + O(rol_mtu_aba); O(rol_mtu_abx); O(rol_mtu_acc); O(rol_mtu_zpg); O(rol_mtu_zpx); + O(ror_mtu_aba); O(ror_mtu_abx); O(ror_mtu_acc); O(ror_mtu_zpg); O(ror_mtu_zpx); + O(rti_mtu_imp); + O(rts_mtu_imp); + O(sbc_mtu_aba); O(sbc_mtu_abx); O(sbc_mtu_aby); O(sbc_mtu_idx); O(sbc_mtu_idy); O(sbc_mtu_imm); O(sbc_mtu_zpg); O(sbc_mtu_zpx); + O(sec_mtu_imp); + O(sed_mtu_imp); + O(sei_mtu_imp); + O(sta_mtu_aba); O(sta_mtu_abx); O(sta_mtu_aby); O(sta_mtu_idx); O(sta_mtu_idy); O(sta_mtu_zpg); O(sta_mtu_zpx); + O(stx_mtu_aba); O(stx_mtu_zpg); O(stx_mtu_zpy); + O(sty_mtu_aba); O(sty_mtu_zpg); O(sty_mtu_zpx); + O(tax_mtu_imp); + O(tay_mtu_imp); + O(tsx_mtu_imp); + O(txa_mtu_imp); + O(txs_mtu_imp); + O(tya_mtu_imp); + + // exceptions + O(reset_mtu); + + // undocumented reliable instructions + O(dcp_mtu_aba); O(dcp_mtu_abx); O(dcp_mtu_aby); O(dcp_mtu_idx); O(dcp_mtu_idy); O(dcp_mtu_zpg); O(dcp_mtu_zpx); + O(isb_mtu_aba); O(isb_mtu_abx); O(isb_mtu_aby); O(isb_mtu_idx); O(isb_mtu_idy); O(isb_mtu_zpg); O(isb_mtu_zpx); + O(lax_mtu_aba); O(lax_mtu_aby); O(lax_mtu_idx); O(lax_mtu_idy); O(lax_mtu_zpg); O(lax_mtu_zpy); + O(rla_mtu_aba); O(rla_mtu_abx); O(rla_mtu_aby); O(rla_mtu_idx); O(rla_mtu_idy); O(rla_mtu_zpg); O(rla_mtu_zpx); + O(rra_mtu_aba); O(rra_mtu_abx); O(rra_mtu_aby); O(rra_mtu_idx); O(rra_mtu_idy); O(rra_mtu_zpg); O(rra_mtu_zpx); + O(sax_mtu_aba); O(sax_mtu_idx); O(sax_mtu_zpg); O(sax_mtu_zpy); + O(sbx_mtu_imm); + O(sha_mtu_aby); O(sha_mtu_idy); + O(shs_mtu_aby); + O(shx_mtu_aby); + O(shy_mtu_abx); + O(slo_mtu_aba); O(slo_mtu_abx); O(slo_mtu_aby); O(slo_mtu_idx); O(slo_mtu_idy); O(slo_mtu_zpg); O(slo_mtu_zpx); + O(sre_mtu_aba); O(sre_mtu_abx); O(sre_mtu_aby); O(sre_mtu_idx); O(sre_mtu_idy); O(sre_mtu_zpg); O(sre_mtu_zpx); + + // undocumented unreliable instructions + // behaviour differs between visual6502 and online docs, which + // is a clear sign reliability is not to be expected + // implemented version follows visual6502 + O(anc_mtu_imm); + O(ane_mtu_imm); + O(arr_mtu_imm); + O(asr_mtu_imm); + O(las_mtu_aby); + O(lxa_mtu_imm); + + // nop variants + O(nop_mtu_imm); O(nop_mtu_aba); O(nop_mtu_abx); O(nop_mtu_zpg); O(nop_mtu_zpx); + + // system killers + O(kil_mtu_non); + +#undef O +}; + +DECLARE_DEVICE_TYPE(M6502MTU, m6502mtu_device); + +#endif // MAME_CPU_M6502_M6502MTU_H diff --git a/src/devices/cpu/m6502/om6502mtu.lst b/src/devices/cpu/m6502/om6502mtu.lst new file mode 100644 index 00000000000..b30d0bc940a --- /dev/null +++ b/src/devices/cpu/m6502/om6502mtu.lst @@ -0,0 +1,2007 @@ +# license:BSD-3-Clause +# copyright-holders:Olivier Galibert +# NMOS 6502 opcodes, with modifications for the MTU-130/Monomeg external banking circuitry + +# Rules: +# +# A "low" instruction is an instruction for which the first byte +# (prefetch address) is at an address < 0x200. +# +# A memory access is indirect if: +# It's the data read/write part of a (abs, X) access +# It's the data read/write part of a (abs), Y access +# It's the data read/write part of a abs, abs,X or abs,Y access in a low instruction +# +# All other accesses are direct +# +# The address bus is 18 bits, with the two top bits being the bank. +# +# BRK and taking an interrupt activates the interrupt mode. Prefetching rti deactivates it. +# +# Two bank numbers are programmable, called "program" and "data". +# +# Direct accesses use the program bank unless in interrupt mode or +# for a low instruction where bank 0 is used instead. +# +# Indirect accesses use the data bank. +# +# At the opcode level we qualify each access depending on its +# category, always direct, always indirect, or indirect if in a low +# instruction. Prefetch takes care of detecting the low instructions. +# Interrupt mode is directly toggled in the brk and rti opcodes. +# +# readd/writei = direct memory access +# readi/writei = indirect memory access +# readil/writeil = indirect memory access for low instructions, direct otherwise + +# documented opcodes + +adc_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + do_adc(TMP2); + prefetchd(); + +adc_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, X)) { + readd(set_l(TMP, TMP+X)); + } + TMP += X; + TMP2 = readil(TMP); + do_adc(TMP2); + prefetchd(); + +adc_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, Y)) { + readd(set_l(TMP, TMP+Y)); + } + TMP += Y; + TMP2 = readil(TMP); + do_adc(TMP2); + prefetchd(); + +adc_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + do_adc(readi(TMP)); + prefetchd(); + +adc_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + if(page_changing(TMP, Y)) { + readi(set_l(TMP, TMP+Y)); + } + do_adc(readi(TMP+Y)); + prefetchd(); + +adc_mtu_imm + TMP = readd_pc(); + do_adc(TMP); + prefetchd(); + +adc_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + do_adc(TMP2); + prefetchd(); + +adc_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP2 = readd(uint8_t(TMP+X)); + do_adc(TMP2); + prefetchd(); + +and_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + A &= readil(TMP); + set_nz(A); + prefetchd(); + +and_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, X)) { + readil(set_l(TMP, TMP+X)); + } + TMP += X; + A &= readil(TMP); + set_nz(A); + prefetchd(); + +and_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, Y)) { + readil(set_l(TMP, TMP+Y)); + } + TMP += Y; + A &= readil(TMP); + set_nz(A); + prefetchd(); + +and_mtu_imm + A &= readd_pc(); + set_nz(A); + prefetchd(); + +and_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + A &= readi(TMP); + set_nz(A); + prefetchd(); + +and_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + if(page_changing(TMP, Y)) { + readi(set_l(TMP, TMP+Y)); + } + A &= readi(TMP+Y); + set_nz(A); + prefetchd(); + +and_mtu_zpg + TMP = readd_pc(); + A &= readd(TMP); + set_nz(A); + prefetchd(); + +and_mtu_zpx + TMP = readd_pc(); + readd(TMP); + A &= readd(uint8_t(TMP+X)); + set_nz(A); + prefetchd(); + +asl_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_asl(TMP2); + writeil(TMP, TMP2); + prefetchd(); + +asl_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+X)); + TMP += X; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_asl(TMP2); + writeil(TMP, TMP2); + prefetchd(); + +asl_mtu_acc + readd_pc_noinc(); + A = do_asl(A); + prefetchd(); + +asl_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_asl(TMP2); + writed(TMP, TMP2); + prefetchd(); + +asl_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP = uint8_t(TMP+X); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_asl(TMP2); + writed(TMP, TMP2); + prefetchd(); + +bcc_mtu_rel + TMP = readd_pc(); + if(!(P & F_C)) { + readd_pc_noinc(); + if(page_changing(PC, int8_t(TMP))) { + readd_arg(set_l(PC, PC+int8_t(TMP))); + } + PC += int8_t(TMP); + } + prefetchd(); + +bcs_mtu_rel + TMP = readd_pc(); + if(P & F_C) { + readd_pc_noinc(); + if(page_changing(PC, int8_t(TMP))) { + readd_arg(set_l(PC, PC+int8_t(TMP))); + } + PC += int8_t(TMP); + } + prefetchd(); + +beq_mtu_rel + TMP = readd_pc(); + if(P & F_Z) { + readd_pc_noinc(); + if(page_changing(PC, int8_t(TMP))) { + readd_arg(set_l(PC, PC+int8_t(TMP))); + } + PC += int8_t(TMP); + } + prefetchd(); + +bit_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + do_bit(readil(TMP)); + prefetchd(); + +bit_mtu_zpg + TMP = readd_pc(); + do_bit(readd(TMP)); + prefetchd(); + +bmi_mtu_rel + TMP = readd_pc(); + if(P & F_N) { + readd_pc_noinc(); + if(page_changing(PC, int8_t(TMP))) { + readd_arg(set_l(PC, PC+int8_t(TMP))); + } + PC += int8_t(TMP); + } + prefetchd(); + +bne_mtu_rel + TMP = readd_pc(); + if(!(P & F_Z)) { + readd_pc_noinc(); + if(page_changing(PC, int8_t(TMP))) { + readd_arg(set_l(PC, PC+int8_t(TMP))); + } + PC += int8_t(TMP); + } + prefetchd(); + +bpl_mtu_rel + TMP = readd_pc(); + if(!(P & F_N)) { + readd_pc_noinc(); + if(page_changing(PC, int8_t(TMP))) { + readd_arg(set_l(PC, PC+int8_t(TMP))); + } + PC += int8_t(TMP); + } + prefetchd(); + +brk_mtu_imp + // The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_pending) + if(irq_taken) { + readd_pc_noinc(); + } else { + readd_pc(); + } + writed(SP, PC >> 8); + dec_SP(); + writed(SP, PC); + dec_SP(); + writed(SP, irq_taken ? P & ~F_B : P); + dec_SP(); + // Interrupt taken is detected by the sequence of three writes, so is active now + interrupt_mode_on(); + if(nmi_pending) { + PC = readd_arg(0xfffa); + PC = set_h(PC, readd_arg(0xfffb)); + nmi_pending = false; + standard_irq_callback(NMI_LINE); + } else { + PC = readd_arg(0xfffe); + PC = set_h(PC, readd_arg(0xffff)); + if(irq_taken) + standard_irq_callback(IRQ_LINE); + } + irq_taken = false; + P |= F_I; // Do *not* move after the prefetch + prefetchd(); + inst_state = -1; + +bvc_mtu_rel + TMP = readd_pc(); + if(!(P & F_V)) { + readd_pc_noinc(); + if(page_changing(PC, int8_t(TMP))) { + readd_arg(set_l(PC, PC+int8_t(TMP))); + } + PC += int8_t(TMP); + } + prefetchd(); + +bvs_mtu_rel + TMP = readd_pc(); + if(P & F_V) { + readd_pc_noinc(); + if(page_changing(PC, int8_t(TMP))) { + readd_arg(set_l(PC, PC+int8_t(TMP))); + } + PC += int8_t(TMP); + } + prefetchd(); + +clc_mtu_imp + readd_pc_noinc(); + P &= ~F_C; + prefetchd(); + +cld_mtu_imp + readd_pc_noinc(); + P &= ~F_D; + prefetchd(); + +cli_mtu_imp + readd_pc_noinc(); + prefetchd(); + P &= ~F_I; // Do *not* move it before the prefetch + +clv_mtu_imp + readd_pc_noinc(); + P &= ~F_V; + prefetchd(); + +cmp_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + do_cmp(A, TMP2); + prefetchd(); + +cmp_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, X)) { + readil(set_l(TMP, TMP+X)); + } + TMP += X; + TMP2 = readil(TMP); + do_cmp(A, TMP2); + prefetchd(); + +cmp_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, Y)) { + readil(set_l(TMP, TMP+Y)); + } + TMP += Y; + TMP2 = readil(TMP); + do_cmp(A, TMP2); + prefetchd(); + +cmp_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + do_cmp(A, readi(TMP)); + prefetchd(); + +cmp_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + if(page_changing(TMP, Y)) { + readi(set_l(TMP, TMP+Y)); + } + do_cmp(A, readi(TMP+Y)); + prefetchd(); + +cmp_mtu_imm + TMP = readd_pc(); + do_cmp(A, TMP); + prefetchd(); + +cmp_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + do_cmp(A, TMP2); + prefetchd(); + +cmp_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP2 = readd(uint8_t(TMP+X)); + do_cmp(A, TMP2); + prefetchd(); + +cpx_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + do_cmp(X, TMP2); + prefetchd(); + +cpx_mtu_imm + TMP = readd_pc(); + do_cmp(X, TMP); + prefetchd(); + +cpx_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + do_cmp(X, TMP2); + prefetchd(); + +cpy_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + do_cmp(Y, TMP2); + prefetchd(); + +cpy_mtu_imm + TMP = readd_pc(); + do_cmp(Y, TMP); + prefetchd(); + +cpy_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + do_cmp(Y, TMP2); + prefetchd(); + +dec_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2--; + set_nz(TMP2); + writeil(TMP, TMP2); + prefetchd(); + +dec_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+X)); + TMP += X; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2--; + set_nz(TMP2); + writeil(TMP, TMP2); + prefetchd(); + +dec_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2--; + set_nz(TMP2); + writed(TMP, TMP2); + prefetchd(); + +dec_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP = uint8_t(TMP+X); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2--; + set_nz(TMP2); + writed(TMP, TMP2); + prefetchd(); + +dex_mtu_imp + readd_pc_noinc(); + X--; + set_nz(X); + prefetchd(); + +dey_mtu_imp + readd_pc_noinc(); + Y--; + set_nz(Y); + prefetchd(); + +eor_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + A ^= readil(TMP); + set_nz(A); + prefetchd(); + +eor_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, X)) { + readil(set_l(TMP, TMP+X)); + } + TMP += X; + A ^= readil(TMP); + set_nz(A); + prefetchd(); + +eor_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, Y)) { + readil(set_l(TMP, TMP+Y)); + } + TMP += Y; + A ^= readil(TMP); + set_nz(A); + prefetchd(); + +eor_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + A ^= readi(TMP); + set_nz(A); + prefetchd(); + +eor_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + if(page_changing(TMP, Y)) { + readi(set_l(TMP, TMP+Y)); + } + A ^= readi(TMP+Y); + set_nz(A); + prefetchd(); + +eor_mtu_imm + A ^= readd_pc(); + set_nz(A); + prefetchd(); + +eor_mtu_zpg + TMP = readd_pc(); + A ^= readd(TMP); + set_nz(A); + prefetchd(); + +eor_mtu_zpx + TMP = readd_pc(); + readd(TMP); + A ^= readd(uint8_t(TMP+X)); + set_nz(A); + prefetchd(); + +inc_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2++; + set_nz(TMP2); + writeil(TMP, TMP2); + prefetchd(); + +inc_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+X)); + TMP += X; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2++; + set_nz(TMP2); + writeil(TMP, TMP2); + prefetchd(); + +inc_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2++; + set_nz(TMP2); + writed(TMP, TMP2); + prefetchd(); + +inc_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP = uint8_t(TMP+X); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2++; + set_nz(TMP2); + writed(TMP, TMP2); + prefetchd(); + +inx_mtu_imp + readd_pc_noinc(); + X++; + set_nz(X); + prefetchd(); + +iny_mtu_imp + readd_pc_noinc(); + Y++; + set_nz(Y); + prefetchd(); + +jmp_mtu_adr + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + PC = TMP; + prefetchd(); + +jmp_mtu_ind + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + PC = readd(TMP); + PC = set_h(PC, readd(set_l(TMP, TMP+1))); + prefetchd(); + +jsr_mtu_adr + TMP = readd_pc(); + readd(SP); + writed(SP, PC>>8); + dec_SP(); + writed(SP, PC); + dec_SP(); + TMP = set_h(TMP, readd_pc()); + PC = TMP; + prefetchd(); + +lda_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + A = readil(TMP); + set_nz(A); + prefetchd(); + +lda_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, X)) { + readil(set_l(TMP, TMP+X)); + } + A = readil(TMP + X); + set_nz(A); + prefetchd(); + +lda_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, Y)) { + readil(set_l(TMP, TMP+Y)); + } + A = readil(TMP + Y); + set_nz(A); + prefetchd(); + +lda_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + A = readi(TMP); + set_nz(A); + prefetchd(); + +lda_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + if(page_changing(TMP, Y)) { + readi(set_l(TMP, TMP+Y)); + } + A = readi(TMP+Y); + set_nz(A); + prefetchd(); + +lda_mtu_imm + A = readd_pc(); + set_nz(A); + prefetchd(); + +lda_mtu_zpg + TMP = readd_pc(); + A = readd(TMP); + set_nz(A); + prefetchd(); + +lda_mtu_zpx + TMP = readd_pc(); + readd(TMP); + A = readd(uint8_t(TMP+X)); + set_nz(A); + prefetchd(); + +ldx_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + X = readil(TMP); + set_nz(X); + prefetchd(); + +ldx_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, Y)) { + readil(set_l(TMP, TMP+Y)); + } + X = readil(TMP + Y); + set_nz(X); + prefetchd(); + +ldx_mtu_imm + X = readd_pc(); + set_nz(X); + prefetchd(); + +ldx_mtu_zpg + TMP = readd_pc(); + X = readd(TMP); + set_nz(X); + prefetchd(); + +ldx_mtu_zpy + TMP = readd_pc(); + readd(TMP); + X = readd(uint8_t(TMP+Y)); + set_nz(X); + prefetchd(); + +ldy_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + Y = readil(TMP); + set_nz(Y); + prefetchd(); + +ldy_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, X)) { + readil(set_l(TMP, TMP+X)); + } + TMP += X; + Y = readil(TMP); + set_nz(Y); + prefetchd(); + +ldy_mtu_imm + Y = readd_pc(); + set_nz(Y); + prefetchd(); + +ldy_mtu_zpg + TMP = readd_pc(); + Y = readd(TMP); + set_nz(Y); + prefetchd(); + +ldy_mtu_zpx + TMP = readd_pc(); + readd(TMP); + Y = readd(uint8_t(TMP+X)); + set_nz(Y); + prefetchd(); + +lsr_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_lsr(TMP2); + writeil(TMP, TMP2); + prefetchd(); + +lsr_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+X)); + TMP += X; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_lsr(TMP2); + writeil(TMP, TMP2); + prefetchd(); + +lsr_mtu_acc + readd_pc_noinc(); + A = do_lsr(A); + prefetchd(); + +lsr_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_lsr(TMP2); + writed(TMP, TMP2); + prefetchd(); + +lsr_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP = uint8_t(TMP+X); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_lsr(TMP2); + writed(TMP, TMP2); + prefetchd(); + +nop_mtu_imp + readd_pc_noinc(); + prefetchd(); + +ora_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + A |= readil(TMP); + set_nz(A); + prefetchd(); + +ora_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, X)) { + readil(set_l(TMP, TMP+X)); + } + TMP += X; + A |= readil(TMP); + set_nz(A); + prefetchd(); + +ora_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, Y)) { + readil(set_l(TMP, TMP+Y)); + } + TMP += Y; + A |= readil(TMP); + set_nz(A); + prefetchd(); + +ora_mtu_imm + A |= readd_pc(); + set_nz(A); + prefetchd(); + +ora_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + A |= readi(TMP); + set_nz(A); + prefetchd(); + +ora_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + if(page_changing(TMP, Y)) { + readi(set_l(TMP, TMP+Y)); + } + A |= readi(TMP+Y); + set_nz(A); + prefetchd(); + +ora_mtu_zpg + TMP = readd_pc(); + A |= readd(TMP); + set_nz(A); + prefetchd(); + +ora_mtu_zpx + TMP = readd_pc(); + readd(TMP); + A |= readd(uint8_t(TMP+X)); + set_nz(A); + prefetchd(); + +pha_mtu_imp + readd_pc_noinc(); + writed(SP, A); + dec_SP(); + prefetchd(); + +php_mtu_imp + readd_pc_noinc(); + writed(SP, P); + dec_SP(); + prefetchd(); + +pla_mtu_imp + readd_pc_noinc(); + readd(SP); + inc_SP(); + A = readd(SP); + set_nz(A); + prefetchd(); + +plp_mtu_imp + readd_pc_noinc(); + readd(SP); + inc_SP(); + TMP = readd(SP) | (F_B|F_E); + prefetchd(); + P = TMP; // Do *not* move it before the prefetch + +rol_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_rol(TMP2); + writeil(TMP, TMP2); + prefetchd(); + +rol_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+X)); + TMP += X; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_rol(TMP2); + writeil(TMP, TMP2); + prefetchd(); + +rol_mtu_acc + readd_pc_noinc(); + A = do_rol(A); + prefetchd(); + +rol_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_rol(TMP2); + writed(TMP, TMP2); + prefetchd(); + +rol_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP = uint8_t(TMP+X); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_rol(TMP2); + writed(TMP, TMP2); + prefetchd(); + +ror_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_ror(TMP2); + writeil(TMP, TMP2); + prefetchd(); + +ror_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+X)); + TMP += X; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_ror(TMP2); + writeil(TMP, TMP2); + prefetchd(); + +ror_mtu_acc + readd_pc_noinc(); + A = do_ror(A); + prefetchd(); + +ror_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_ror(TMP2); + writed(TMP, TMP2); + prefetchd(); + +ror_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP = uint8_t(TMP+X); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_ror(TMP2); + writed(TMP, TMP2); + prefetchd(); + +rti_mtu_imp + interrupt_mode_off(); + readd_pc_noinc(); + readd(SP); + inc_SP(); + P = readd(SP) | (F_B|F_E); + inc_SP(); + PC = readd(SP); + inc_SP(); + PC = set_h(PC, readd(SP)); + prefetchd(); + +rts_mtu_imp + readd_pc_noinc(); + readd(SP); + inc_SP(); + PC = readd(SP); + inc_SP(); + PC = set_h(PC, readd(SP)); + readd_pc(); + prefetchd(); + +sbc_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + do_sbc(TMP2); + prefetchd(); + +sbc_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, X)) { + readil(set_l(TMP, TMP+X)); + } + TMP += X; + TMP2 = readil(TMP); + do_sbc(TMP2); + prefetchd(); + +sbc_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, Y)) { + readil(set_l(TMP, TMP+Y)); + } + TMP += Y; + TMP2 = readil(TMP); + do_sbc(TMP2); + prefetchd(); + +sbc_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + do_sbc(readi(TMP)); + prefetchd(); + +sbc_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + if(page_changing(TMP, Y)) { + readi(set_l(TMP, TMP+Y)); + } + do_sbc(readi(TMP+Y)); + prefetchd(); + +sbc_mtu_imm + TMP = readd_pc(); + do_sbc(TMP); + prefetchd(); + +sbc_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + do_sbc(TMP2); + prefetchd(); + +sbc_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP2 = readd(uint8_t(TMP+X)); + do_sbc(TMP2); + prefetchd(); + +sec_mtu_imp + readd_pc_noinc(); + P |= F_C; + prefetchd(); + +sed_mtu_imp + readd_pc_noinc(); + P |= F_D; + prefetchd(); + +sei_mtu_imp + readd_pc_noinc(); + prefetchd(); + P |= F_I; // Do *not* move it before the prefetch + +sta_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + writeil(TMP, A); + prefetchd(); + +sta_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+X)); + writeil(TMP+X, A); + prefetchd(); + +sta_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+Y)); + writeil(TMP+Y, A); + prefetchd(); + +sta_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + writei(TMP, A); + prefetchd(); + +sta_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + readi(set_l(TMP, TMP+Y)); + writei(TMP+Y, A); + prefetchd(); + +sta_mtu_zpg + TMP = readd_pc(); + writed(TMP, A); + prefetchd(); + +sta_mtu_zpx + TMP = readd_pc(); + readd(TMP); + writed(uint8_t(TMP+X), A); + prefetchd(); + +stx_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + writeil(TMP, X); + prefetchd(); + +stx_mtu_zpg + TMP = readd_pc(); + writed(TMP, X); + prefetchd(); + +stx_mtu_zpy + TMP = readd_pc(); + readd(TMP); + writed(uint8_t(TMP+Y), X); + prefetchd(); + +sty_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + writeil(TMP, Y); + prefetchd(); + +sty_mtu_zpg + TMP = readd_pc(); + writed(TMP, Y); + prefetchd(); + +sty_mtu_zpx + TMP = readd_pc(); + readd(TMP); + writed(uint8_t(TMP+X), Y); + prefetchd(); + +tax_mtu_imp + readd_pc_noinc(); + X = A; + set_nz(X); + prefetchd(); + +tay_mtu_imp + readd_pc_noinc(); + Y = A; + set_nz(Y); + prefetchd(); + +tsx_mtu_imp + readd_pc_noinc(); + X = SP; + set_nz(X); + prefetchd(); + +txa_mtu_imp + readd_pc_noinc(); + A = X; + set_nz(A); + prefetchd(); + +txs_mtu_imp + readd_pc_noinc(); + SP = set_l(SP, X); + prefetchd(); + +tya_mtu_imp + readd_pc_noinc(); + A = Y; + set_nz(A); + prefetchd(); + +# exceptions +reset_mtu + readd_pc_noinc(); + readd_pc_noinc(); + readd(SP); dec_SP(); + readd(SP); dec_SP(); + readd(SP); dec_SP(); + P |= F_I; PC = readd_arg(0xfffc); + PC = set_h(PC, readd_arg(0xfffd)); + prefetchd(); + inst_state = -1; + + +# undocumented reliable instructions +dcp_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2--; + writeil(TMP, TMP2); + do_cmp(A, TMP2); + prefetchd(); + +dcp_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+X)); + TMP += X; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2--; + writeil(TMP, TMP2); + do_cmp(A, TMP2); + prefetchd(); + +dcp_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+Y)); + TMP += Y; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2--; + writeil(TMP, TMP2); + do_cmp(A, TMP2); + prefetchd(); + +dcp_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + TMP2 = readd(TMP); + writei(TMP, TMP2); + TMP2--; + writei(TMP, TMP2); + do_cmp(A, TMP2); + prefetchd(); + +dcp_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + readd(set_l(TMP, TMP+Y)); + TMP += Y; + TMP2 = readi(TMP); + writei(TMP, TMP2); + TMP2--; + writei(TMP, TMP2); + do_cmp(A, TMP2); + prefetchd(); + +dcp_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2--; + writed(TMP, TMP2); + do_cmp(A, TMP2); + prefetchd(); + +dcp_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP = uint8_t(TMP+X); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2--; + writed(TMP, TMP2); + do_cmp(A, TMP2); + prefetchd(); + +isb_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2++; + writeil(TMP, TMP2); + do_sbc(TMP2); + prefetchd(); + +isb_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+X)); + TMP += X; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2++; + writeil(TMP, TMP2); + do_sbc(TMP2); + prefetchd(); + +isb_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+Y)); + TMP += Y; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2++; + writeil(TMP, TMP2); + do_sbc(TMP2); + prefetchd(); + +isb_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + TMP2 = readi(TMP); + writei(TMP, TMP2); + TMP2++; + writei(TMP, TMP2); + do_sbc(TMP2); + prefetchd(); + +isb_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + readd(set_l(TMP, TMP+Y)); + TMP += Y; + TMP2 = readi(TMP); + writei(TMP, TMP2); + TMP2++; + writei(TMP, TMP2); + do_sbc(TMP2); + prefetchd(); + +isb_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2++; + writed(TMP, TMP2); + do_sbc(TMP2); + prefetchd(); + +isb_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP = uint8_t(TMP+X); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2++; + writed(TMP, TMP2); + do_sbc(TMP2); + prefetchd(); + +lax_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + A = X = readil(TMP); + set_nz(A); + prefetchd(); + +lax_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, Y)) { + readil(set_l(TMP, TMP+Y)); + } + A = X = readil(TMP+Y); + set_nz(A); + prefetchd(); + +lax_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + A = X = readi(TMP); + set_nz(A); + prefetchd(); + +lax_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + if(page_changing(TMP, Y)) { + readi(set_l(TMP, TMP+Y)); + } + A = X = readi(TMP+Y); + set_nz(A); + prefetchd(); + +lax_mtu_zpg + TMP = readd_pc(); + A = X = readd(TMP); + set_nz(A); + prefetchd(); + +lax_mtu_zpy + TMP = readd_pc(); + readd(TMP); + TMP = uint8_t(TMP+Y); + A = X = readd(TMP); + set_nz(A); + prefetchd(); + +rla_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_rol(TMP2); + writeil(TMP, TMP2); + A &= TMP2; + set_nz(A); + prefetchd(); + +rla_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+X)); + TMP += X; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_rol(TMP2); + writeil(TMP, TMP2); + A &= TMP2; + set_nz(A); + prefetchd(); + +rla_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+Y)); + TMP += Y; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_rol(TMP2); + writeil(TMP, TMP2); + A &= TMP2; + set_nz(A); + prefetchd(); + +rla_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + TMP2 = readi(TMP); + writei(TMP, TMP2); + TMP2 = do_rol(TMP2); + writei(TMP, TMP2); + A &= TMP2; + set_nz(A); + prefetchd(); + +rla_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + readd(set_l(TMP, TMP+Y)); + TMP += Y; + TMP2 = readi(TMP); + writei(TMP, TMP2); + TMP2 = do_rol(TMP2); + writei(TMP, TMP2); + A &= TMP2; + set_nz(A); + prefetchd(); + +rla_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_rol(TMP2); + writed(TMP, TMP2); + A &= TMP2; + set_nz(A); + prefetchd(); + +rla_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP = uint8_t(TMP+X); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_rol(TMP2); + writed(TMP, TMP2); + A &= TMP2; + set_nz(A); + prefetchd(); + +rra_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_ror(TMP2); + writeil(TMP, TMP2); + do_adc(TMP2); + prefetchd(); + +rra_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+X)); + TMP += X; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_ror(TMP2); + writeil(TMP, TMP2); + do_adc(TMP2); + prefetchd(); + +rra_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+Y)); + TMP += Y; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_ror(TMP2); + writeil(TMP, TMP2); + do_adc(TMP2); + prefetchd(); + +rra_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + TMP2 = readi(TMP); + writei(TMP, TMP2); + TMP2 = do_ror(TMP2); + writei(TMP, TMP2); + do_adc(TMP2); + prefetchd(); + +rra_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + readd(set_l(TMP, TMP+Y)); + TMP += Y; + TMP2 = readi(TMP); + writei(TMP, TMP2); + TMP2 = do_ror(TMP2); + writei(TMP, TMP2); + do_adc(TMP2); + prefetchd(); + +rra_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_ror(TMP2); + writed(TMP, TMP2); + do_adc(TMP2); + prefetchd(); + +rra_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP = uint8_t(TMP+X); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_ror(TMP2); + writed(TMP, TMP2); + do_adc(TMP2); + prefetchd(); + +sax_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = A & X; + writeil(TMP, TMP2); + prefetchd(); + +sax_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + TMP2 = A & X; + writei(TMP, TMP2); + prefetchd(); + +sax_mtu_zpg + TMP = readd_pc(); + TMP2 = A & X; + writed(TMP, TMP2); + prefetchd(); + +sax_mtu_zpy + TMP = readd_pc(); + readd(TMP); + TMP = uint8_t(TMP+Y); + TMP2 = A & X; + writed(TMP, TMP2); + prefetchd(); + +sbx_mtu_imm + TMP2 = readd_pc(); + X &= A; + if(X < TMP2) + P &= ~F_C; + else + P |= F_C; + X -= TMP2; + set_nz(X); + prefetchd(); + +sha_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+Y)); + TMP2 = A & X & ((TMP >> 8)+1); + if(page_changing(TMP, Y)) + TMP = set_h(TMP+Y, TMP2); + else + TMP += Y; + writeil(TMP, TMP2); + prefetchd(); + +sha_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + readi(set_l(TMP, TMP+Y)); + TMP2 = A & X & ((TMP >> 8)+1); + if(page_changing(TMP, Y)) + TMP = set_h(TMP+Y, TMP2); + else + TMP += Y; + writei(TMP, TMP2); + prefetchd(); + +shs_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+Y)); + SP = set_l(SP, A & X); + TMP2 = A & X & ((TMP >> 8)+1); + if(page_changing(TMP, Y)) + TMP = set_h(TMP+Y, TMP2); + else + TMP += Y; + writeil(TMP, TMP2); + prefetchd(); + +shx_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+Y)); + TMP2 = X & ((TMP >> 8)+1); + if(page_changing(TMP, Y)) + TMP = set_h(TMP+Y, TMP2); + else + TMP += Y; + writeil(TMP, TMP2); + prefetchd(); + +shy_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+X)); + TMP2 = Y & ((TMP >> 8)+1); + if(page_changing(TMP, X)) + TMP = set_h(TMP+X, TMP2); + else + TMP += X; + writeil(TMP, TMP2); + prefetchd(); + +slo_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_asl(TMP2); + writeil(TMP, TMP2); + A |= TMP2; + set_nz(A); + prefetchd(); + +slo_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+X)); + TMP += X; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_asl(TMP2); + writeil(TMP, TMP2); + A |= TMP2; + set_nz(A); + prefetchd(); + +slo_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+Y)); + TMP += Y; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_asl(TMP2); + writeil(TMP, TMP2); + A |= TMP2; + set_nz(A); + prefetchd(); + +slo_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + TMP2 = readi(TMP); + writei(TMP, TMP2); + TMP2 = do_asl(TMP2); + writei(TMP, TMP2); + A |= TMP2; + set_nz(A); + prefetchd(); + +slo_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + readd(set_l(TMP, TMP+Y)); + TMP += Y; + TMP2 = readi(TMP); + writei(TMP, TMP2); + TMP2 = do_asl(TMP2); + writei(TMP, TMP2); + A |= TMP2; + set_nz(A); + prefetchd(); + +slo_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_asl(TMP2); + writed(TMP, TMP2); + A |= TMP2; + set_nz(A); + prefetchd(); + +slo_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP = uint8_t(TMP+X); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_asl(TMP2); + writed(TMP, TMP2); + A |= TMP2; + set_nz(A); + prefetchd(); + +sre_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_lsr(TMP2); + writeil(TMP, TMP2); + A ^= TMP2; + set_nz(A); + prefetchd(); + +sre_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+X)); + TMP += X; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_lsr(TMP2); + writeil(TMP, TMP2); + A ^= TMP2; + set_nz(A); + prefetchd(); + +sre_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(set_l(TMP, TMP+Y)); + TMP += Y; + TMP2 = readil(TMP); + writeil(TMP, TMP2); + TMP2 = do_lsr(TMP2); + writeil(TMP, TMP2); + A ^= TMP2; + set_nz(A); + prefetchd(); + +sre_mtu_idx + TMP2 = readd_pc(); + readd(TMP2); + TMP2 += X; + TMP = readd(TMP2 & 0xff); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + TMP2 = readi(TMP); + writei(TMP, TMP2); + TMP2 = do_lsr(TMP2); + writei(TMP, TMP2); + A ^= TMP2; + set_nz(A); + prefetchd(); + +sre_mtu_idy + TMP2 = readd_pc(); + TMP = readd(TMP2); + TMP = set_h(TMP, readd((TMP2+1) & 0xff)); + readd(set_l(TMP, TMP+Y)); + TMP += Y; + TMP2 = readi(TMP); + writei(TMP, TMP2); + TMP2 = do_lsr(TMP2); + writei(TMP, TMP2); + A ^= TMP2; + set_nz(A); + prefetchd(); + +sre_mtu_zpg + TMP = readd_pc(); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_lsr(TMP2); + writed(TMP, TMP2); + A ^= TMP2; + set_nz(A); + prefetchd(); + +sre_mtu_zpx + TMP = readd_pc(); + readd(TMP); + TMP = uint8_t(TMP+X); + TMP2 = readd(TMP); + writed(TMP, TMP2); + TMP2 = do_lsr(TMP2); + writed(TMP, TMP2); + A ^= TMP2; + set_nz(A); + prefetchd(); + +# undocumented unreliable instructions +anc_mtu_imm + A &= readd_pc(); + set_nz(A); + if(A & 0x80) + P |= F_C; + else + P &= ~F_C; + prefetchd(); + +ane_mtu_imm + TMP2 = readd_pc(); + A &= TMP2 & X; + set_nz(A); + prefetchd(); + +asr_mtu_imm + A &= readd_pc(); + A = do_lsr(A); + prefetchd(); + +arr_mtu_imm + A &= readd_pc(); + do_arr(); + prefetchd(); + +las_mtu_aby + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, Y)) { + readil(set_l(TMP, TMP+Y)); + } + TMP2 = readil(TMP+Y); + A = TMP2 | 0x51; + X = 0xff; + set_nz(TMP2); + prefetchd(); + +lxa_mtu_imm + A = X = readd_pc(); + set_nz(A); + prefetchd(); + +# nop variants +nop_mtu_aba + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + readil(TMP); + prefetchd(); + +nop_mtu_abx + TMP = readd_pc(); + TMP = set_h(TMP, readd_pc()); + if(page_changing(TMP, X)) { + readil(set_l(TMP, TMP+X)); + } + readil(TMP + X); + prefetchd(); + +nop_mtu_imm + readd_pc(); + prefetchd(); + +nop_mtu_zpg + TMP = readd_pc(); + readd(TMP); + prefetchd(); + +nop_mtu_zpx + TMP = readd_pc(); + readd(TMP); + readd(uint8_t(TMP+X)); + prefetchd(); + +# system killers +kil_mtu_non + readd_pc(); + readd(0xffff); + readd(0xfffe); + readd(0xfffe); + for(;;) { + readd(0xffff); + } diff --git a/src/devices/machine/upd765.cpp b/src/devices/machine/upd765.cpp index 4996093e0bd..acf4182fecc 100644 --- a/src/devices/machine/upd765.cpp +++ b/src/devices/machine/upd765.cpp @@ -548,6 +548,8 @@ uint8_t upd765_family_device::fifo_r() uint8_t r = 0xff; switch(main_phase) { case PHASE_CMD: + if(machine().side_effects_disabled()) + return 0x00; if(command_pos) fifo_w(0xff); LOGFIFO("fifo_r in command phase\n"); diff --git a/src/emu/xtal.cpp b/src/emu/xtal.cpp index fea0239d53a..e6d4ab3fe9a 100644 --- a/src/emu/xtal.cpp +++ b/src/emu/xtal.cpp @@ -102,6 +102,7 @@ const double XTAL::known_xtals[] = { 3'579'000, /* 3.579_MHz_XTAL BeebOPL */ 3'579'545, /* 3.579545_MHz_XTAL NTSC color subcarrier, extremely common, used on 100's of PCBs (Keytronic custom part #48-300-010 is equivalent) */ 3'579'575, /* 3.579575_MHz_XTAL Atari 2600 NTSC */ + 3'680'000, /* 3.68_MHz_XTAL Resonator - Baud rate clock for the 6551 in the MTU-130 */ 3'686'400, /* 3.6864_MHz_XTAL Baud rate clock for MC68681 and similar UARTs */ 3'840'000, /* 3.84_MHz_XTAL Fairlight CMI Alphanumeric Keyboard */ 3'900'000, /* 3.9_MHz_XTAL Resonator - Used on some Fidelity boards */ diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 1c2fc0298fb..01811cee6dd 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -44838,3 +44838,6 @@ sc203 // SC203 - Modular Z180 Computer @source:vtech/phusion.cpp phusion // + +@source:misc/mtu130.cpp +mtu130 diff --git a/src/mame/misc/mtu130.cpp b/src/mame/misc/mtu130.cpp new file mode 100644 index 00000000000..490ca2a5049 --- /dev/null +++ b/src/mame/misc/mtu130.cpp @@ -0,0 +1,590 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// Micro Technology Unlimited MTU-130 + +// Silently boots to floppy, so nothing will happen if you don't have +// a bootable disk in the drive. + +// Unimplemented: +// - MTUTAPE, a kind of digital tape? +// - MTUNET, some proprietary network +// - EPROM support (we don't have any image, maps at c000+) +// - Sound on user via cb2, it's weird +// - Light pen, need working demo code + +// Unimplemented extension boards: +// - DATAMOVER, a 68k-based board, used by BASIC 1.5 to accelerate floating point operations +// - PROGRAMMOVER, a z80-based board + +// Need to add the extra PROMs once they're dumped. + +// Note that we hardcoded the ram in bank 3 BASIC 1.5 needs, it should +// be added by DATAMOVER (or PROGRAMMOVER after some reconfiguration). + +// Probable bug somewhere making the BASIC (light pen, game) demos +// fail in the demonstration disk, possibly in the customized 6502 +// core. + +#include "emu.h" +#include "cpu/m6502/m6502mtu.h" +#include "imagedev/floppy.h" +#include "machine/6522via.h" +#include "machine/input_merger.h" +#include "machine/mos6551.h" +#include "machine/upd765.h" +#include "bus/rs232/rs232.h" +#include "sound/dac.h" +#include "emupal.h" +#include "screen.h" +#include "speaker.h" + +class mtu130_state: public driver_device +{ +public: + mtu130_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_user_6522(*this, "user_6522"), + m_sys1_6522(*this, "sys1_6522"), + m_sys2_6522(*this, "sys2_6522"), + m_acia(*this, "acia"), + m_irq_merger(*this, "irq_merger"), + m_rs232(*this, "rs232"), + m_fdc(*this, "fdc"), + m_floppy(*this, "fdc:%d", 0U), + m_screen(*this, "screen"), + m_palette(*this, "palette"), + m_dac(*this, "dac"), + m_speaker(*this, "mono"), + m_io_view(*this, "io_view"), + m_se_view(*this, "sw_view"), + m_rom_view(*this, "rom_view"), + m_rof_view(*this, "rof_view"), + m_mainram(*this, "mainram"), + m_fdcram(*this, "fdcram"), + m_videoram(*this, "videoram"), + m_keyboard(*this, "K%X", 0L), + m_keyboard_meta(*this, "KM") + { } + + void mtu130(machine_config &config); + + DECLARE_INPUT_CHANGED_MEMBER(nmi_w); + DECLARE_INPUT_CHANGED_MEMBER(reset_w); + DECLARE_INPUT_CHANGED_MEMBER(break_w); + +protected: + virtual void machine_start() override; + virtual void video_start() override; + +private: + required_device m_maincpu; + required_device m_user_6522; + required_device m_sys1_6522; + required_device m_sys2_6522; + required_device m_acia; + required_device m_irq_merger; + required_device m_rs232; + required_device m_fdc; + required_device_array m_floppy; + required_device m_screen; + required_device m_palette; + required_device m_dac; + required_device m_speaker; + + memory_view m_io_view; + memory_view m_se_view; + memory_view m_rom_view; + memory_view m_rof_view; + required_shared_ptr m_mainram; + required_shared_ptr m_fdcram; + required_shared_ptr m_videoram; + + required_ioport_array<16> m_keyboard; + required_ioport m_keyboard_meta; + + uint16_t m_dma_adr; + u8 m_keyboard_col; + u8 m_dac_level; + u8 m_cpuid; + bool m_dma_direction; + bool m_video_unblank; + bool m_video_bw; + bool m_fdc_irq_enabled; + + static void floppies(device_slot_interface &device); + void map(address_map &map); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + u8 fdc_ctrl_r(); + void fdc_ctrl_w(u8 data); + void fdc_irq_w(int state); + void dma_adr_w(u8 data); + DECLARE_WRITE_LINE_MEMBER(dma_drq_w); + + void keyboard_col_clear_w(u8); + void user_cb2_w(int line); + void sys1_pb_w(u8 data); + u8 sys1_pa_r(); + void sys1_ca2_w(int line); + void sys2_pa_w(u8 data); + + void cpuid_reset_w(u8); + u8 cpuid_r(); + + void io_enable_w(u8); + void io_disable_w(u8); +}; + +void mtu130_state::machine_start() +{ + m_dma_adr = 0; + m_dma_direction = false; + m_keyboard_col = 0; + m_dac_level = 0x80; + m_cpuid = 0; + m_video_unblank = true; + m_video_bw = true; + m_fdc_irq_enabled = false; + + save_item(NAME(m_dma_adr)); + save_item(NAME(m_dma_direction)); + save_item(NAME(m_keyboard_col)); + save_item(NAME(m_dac_level)); + save_item(NAME(m_cpuid)); + save_item(NAME(m_video_unblank)); + save_item(NAME(m_video_bw)); + save_item(NAME(m_fdc_irq_enabled)); + + m_fdc->set_rate(500000); + m_io_view.select(1); + m_se_view.select(0); + m_rom_view.disable(); + m_rof_view.disable(); +} + +void mtu130_state::video_start() +{ + m_palette->set_pen_color(0, 0, 0, 0); + m_palette->set_pen_color(1, 85, 85, 85); + m_palette->set_pen_color(2, 170, 170, 170); + m_palette->set_pen_color(3, 255, 255, 255); +} + +uint32_t mtu130_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + if(m_video_unblank && m_video_bw) { + int x0 = cliprect.left() - 120; + int x1 = cliprect.right() - 120; + for(int y = cliprect.top(); y <= cliprect.bottom(); y++) { + const u8 *src = m_videoram + 60 * y + (x0 >> 3); + u16 *dest = &bitmap.pix(y, cliprect.left()); + u8 v = 0; + if(x0 & 7) + v = *src++; + for(int x = x0; x <= x1; x++) { + if(!(x & 7)) + v = *src++; + *dest++ = ((v >> (7 - (x & 7))) & 1) ? 3 : 0; + } + } + + } else if(m_video_unblank) { + int x0 = cliprect.left() - 120; + int x1 = cliprect.right() - 120; + for(int y = cliprect.top(); y <= cliprect.bottom(); y++) { + const u8 *src = m_videoram + 60 * y + (x0 >> 4); + u16 *dest = &bitmap.pix(y, cliprect.left()); + u8 v = 0; + if(x0 & 15) + v = *src++; + for(int x = x0; x <= x1; x++) { + if(!(x & 15)) + v = *src++; + *dest++ = (v >> (6 - 2*((x >> 1) & 3))) & 3; + } + } + + } else + bitmap.fill(0, cliprect); + + return 0; +} + +u8 mtu130_state::fdc_ctrl_r() +{ + return m_fdc->get_irq() ? 0x00 : 0x80; +} + +void mtu130_state::fdc_ctrl_w(u8 data) +{ + m_dma_direction = data & 1; + if(data & 2) + m_rof_view.select(1); + else + m_rof_view.disable(); + m_fdc_irq_enabled = data & 4; + m_irq_merger->in_w<0>(m_fdc_irq_enabled && m_fdc->get_irq()); +} + +void mtu130_state::fdc_irq_w(int state) +{ + m_irq_merger->in_w<0>(m_fdc_irq_enabled && state); +} + +void mtu130_state::dma_adr_w(u8 data) +{ + m_dma_adr = data << 6; +} + +WRITE_LINE_MEMBER(mtu130_state::dma_drq_w) +{ + while(m_fdc->get_drq()) { + if(m_dma_direction) { + // Read from floppy + u8 data = m_fdc->dma_r(); + m_fdcram[m_dma_adr & 0x3fff] = data; + m_dma_adr ++; + + } else { + // Write to floppy + u8 data = m_fdcram[m_dma_adr & 0x3fff]; + m_fdc->dma_w(data); + m_dma_adr ++; + } + } +} + +void mtu130_state::cpuid_reset_w(u8) +{ + m_cpuid = 0; +} + +u8 mtu130_state::cpuid_r() +{ + static u8 cpuid[] = { 0, + 0, 0, 0, 0, 0, // Vendor + 0, 0, 0, 0, 0, // Group + 0, 0, 1, 7, 5, // User, BASIC and others tend to check that one + }; + u8 res = cpuid[m_cpuid & 15]; + m_cpuid++; + return res; +} + +void mtu130_state::user_cb2_w(int line) +{ + logerror("%s user cb2 %d\n", machine().time().to_string(), line); +} + +void mtu130_state::sys1_pb_w(u8 data) +{ + m_maincpu->set_dbank((~data) & 3); + m_maincpu->set_pbank((~data >> 2) & 3); + + if(data & 0x80) + m_rom_view.disable(); + else + m_rom_view.select(1); + + bool video_bw = data & 0x10; + bool video_unblank = data & 0x20; + + if(video_bw != m_video_bw || video_unblank != m_video_unblank) { + m_screen->update_now(); + + m_video_bw = video_bw; + m_video_unblank = video_unblank; + } +} + +u8 mtu130_state::sys1_pa_r() +{ + // A capacitor is used to pretend the MOD key is pressed at power-on time. + return m_keyboard[m_keyboard_col & 0xf]->read() | + ((m_keyboard_meta->read() & 0x04) || (machine().time().as_double() < 0.1) ? 1 : 0); +} + +void mtu130_state::sys2_pa_w(u8 data) +{ + m_dac_level = data; + m_dac->write(data); +} + +void mtu130_state::sys1_ca2_w(int state) +{ + if(state) + m_keyboard_col ++; +} + +void mtu130_state::io_enable_w(u8) +{ + m_io_view.select(1); +} + +void mtu130_state::io_disable_w(u8) +{ + m_io_view.disable(); +} + +INPUT_CHANGED_MEMBER(mtu130_state::nmi_w) +{ + m_maincpu->set_input_line(m6502_device::NMI_LINE, newval ? ASSERT_LINE : CLEAR_LINE); +} + +INPUT_CHANGED_MEMBER(mtu130_state::reset_w) +{ + if(newval == 0) + reset(); +} + +INPUT_CHANGED_MEMBER(mtu130_state::break_w) +{ + m_sys1_6522->write_ca1(newval); +} + +void mtu130_state::keyboard_col_clear_w(u8) +{ + m_keyboard_col = 0; +} + + +void mtu130_state::map(address_map &map) +{ + map(0x00000, 0x0bfff).ram().share(m_mainram); // Main ram, in a single block + map(0x08000, 0x0bfff).view(m_rom_view); // View to write-protect the top of the main ram + m_rom_view[1](0x08000, 0x0bfff).nopw(); + + map(0x0be00, 0x0bfff).view(m_io_view); // I/O dynamically overrides part of the main ram + m_io_view[1](0x0be00, 0x0bfff).unmaprw(); // Fully mask out the ram when active + m_io_view[1](0x0bfc3, 0x0bfc3).r(FUNC(mtu130_state::cpuid_r)); + m_io_view[1](0x0bfc5, 0x0bfc5).w(FUNC(mtu130_state::keyboard_col_clear_w)); + m_io_view[1](0x0bfc7, 0x0bfc7).w(FUNC(mtu130_state::cpuid_reset_w)); + m_io_view[1](0x0bfc8, 0x0bfcb).rw(m_acia, FUNC(mos6551_device::read), FUNC(mos6551_device::write)); + m_io_view[1](0x0bfd0, 0x0bfdf).m(m_user_6522, FUNC(via6522_device::map)); + m_io_view[1](0x0bfe0, 0x0bfef).m(m_sys1_6522, FUNC(via6522_device::map)); + m_io_view[1](0x0bff0, 0x0bfff).m(m_sys2_6522, FUNC(via6522_device::map)); + + map(0x0c000, 0x0ffff).view(m_se_view); // System (fdc)/External view + m_se_view[0](0x0c000, 0x0ffff).ram().share(m_fdcram); // FDC ram is a single 16K block, fully adressible by the dma + m_se_view[0](0x0e000, 0x0ffff).view(m_rof_view); // View to write-protect the top half of the fdc ram + m_rof_view[1](0x0e000, 0x0ffff).nopw(); + + m_se_view[0](0x0ff00, 0x0ffff).rom().region("ipl", 0).unmapw(); // Bootrom overrides the end of the ram + m_se_view[0](0x0ffe8, 0x0ffef).unmaprw(); // Hole in the prom access for floppy i/o + m_se_view[0](0x0ffe8, 0x0ffe8).rw(FUNC(mtu130_state::fdc_ctrl_r), FUNC(mtu130_state::fdc_ctrl_w)); + m_se_view[0](0x0ffea, 0x0ffea).w(FUNC(mtu130_state::dma_adr_w)); + m_se_view[0](0x0ffee, 0x0ffef).m(m_fdc, FUNC(upd765a_device::map)); + + map(0x0fffe, 0x0fffe).w(FUNC(mtu130_state::io_enable_w)); + map(0x0ffff, 0x0ffff).w(FUNC(mtu130_state::io_disable_w)); + + map(0x1c000, 0x1ffff).ram().share(m_videoram); // 16k of video ram + + map(0x30000, 0x3ffff).ram(); // Basic 1.5 wants more ram, comes from an extension board +} + +void mtu130_state::floppies(device_slot_interface &device) +{ + device.option_add("8ssdd", FLOPPY_8_SSDD); + device.option_add("8dsdd", FLOPPY_8_DSDD); +} + +void mtu130_state::mtu130(machine_config &config) +{ + M6502MTU(config, m_maincpu, 10_MHz_XTAL/10); + m_maincpu->set_addrmap(AS_PROGRAM, &mtu130_state::map); + + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + // HSync is between 40 and 79, VSync between 256 and 259, boundaries included + m_screen->set_raw(10_MHz_XTAL, 620, 120, 600, 269, 0, 256); + m_screen->set_screen_update(FUNC(mtu130_state::screen_update)); + m_screen->set_palette(m_palette); + m_screen->screen_vblank().set(m_sys2_6522, FUNC(via6522_device::write_ca2)); + + PALETTE(config, m_palette).set_entries(4); + + MOS6522(config, m_user_6522, 10_MHz_XTAL/10); + m_user_6522->irq_handler().set(m_irq_merger, FUNC(input_merger_device::in_w<1>)); + m_user_6522->cb2_handler().set(FUNC(mtu130_state::user_cb2_w)); + + MOS6522(config, m_sys1_6522, 10_MHz_XTAL/10); + m_sys1_6522->irq_handler().set(m_irq_merger, FUNC(input_merger_device::in_w<2>)); + m_sys1_6522->readpa_handler().set(FUNC(mtu130_state::sys1_pa_r)); + m_sys1_6522->writepb_handler().set(FUNC(mtu130_state::sys1_pb_w)); + m_sys1_6522->ca2_handler().set(FUNC(mtu130_state::sys1_ca2_w)); + + MOS6522(config, m_sys2_6522, 10_MHz_XTAL/10); + m_sys2_6522->irq_handler().set(m_irq_merger, FUNC(input_merger_device::in_w<3>)); + m_sys2_6522->writepa_handler().set(FUNC(mtu130_state::sys2_pa_w)); + + MOS6551(config, m_acia, 3.68_MHz_XTAL/2); + m_acia->irq_handler().set(m_irq_merger, FUNC(input_merger_device::in_w<4>)); + m_acia->txd_handler().set(m_rs232, FUNC(rs232_port_device::write_txd)); + + RS232_PORT(config, m_rs232, default_rs232_devices, nullptr); + m_rs232->rxd_handler().set(m_acia, FUNC(mos6551_device::write_rxd)); + m_rs232->dcd_handler().set(m_acia, FUNC(mos6551_device::write_dcd)); + m_rs232->dsr_handler().set(m_acia, FUNC(mos6551_device::write_dsr)); + m_rs232->cts_handler().set(m_acia, FUNC(mos6551_device::write_cts)); + + INPUT_MERGER_ANY_HIGH(config, m_irq_merger).output_handler().set_inputline(m_maincpu, m6502_device::IRQ_LINE); + + UPD765A(config, m_fdc, 10_MHz_XTAL/10*8, true, true); // *8 done through a PLL + m_fdc->intrq_wr_callback().set(FUNC(mtu130_state::fdc_irq_w)); + m_fdc->drq_wr_callback().set(FUNC(mtu130_state::dma_drq_w)); + + FLOPPY_CONNECTOR(config, m_floppy[0], mtu130_state::floppies, "8dsdd", floppy_image_device::default_mfm_floppy_formats); + FLOPPY_CONNECTOR(config, m_floppy[1], mtu130_state::floppies, "8dsdd", floppy_image_device::default_mfm_floppy_formats); + FLOPPY_CONNECTOR(config, m_floppy[2], mtu130_state::floppies, nullptr, floppy_image_device::default_mfm_floppy_formats); + FLOPPY_CONNECTOR(config, m_floppy[3], mtu130_state::floppies, nullptr, floppy_image_device::default_mfm_floppy_formats); + + DAC_8BIT_R2R(config, m_dac, 0).add_route(ALL_OUTPUTS, m_speaker, 1.0); + SPEAKER(config, m_speaker).front_center(); +} + + +static INPUT_PORTS_START(mtu130) + PORT_START("K0") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_2) PORT_NAME("RIGHT SHIFT") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_NAME("LEFT SHIFT") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_NAME("CTRL") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("REPEAT") + + PORT_START("K1") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("Keypad -") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) + + PORT_START("K2") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Keypad 6") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + + PORT_START("K3") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_PLUS_PAD) PORT_NAME("Keypad +") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + + PORT_START("K4") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH_PAD) PORT_NAME("Keypad /") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + + PORT_START("K5") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Keypad 5") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + + PORT_START("K6") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_NAME("Keypad *") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + + PORT_START("K7") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("Keypad 9") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') + + PORT_START("K8") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("PF2") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + + PORT_START("K9") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Keypad 1") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + + PORT_START("KA") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Keypad 4") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + + PORT_START("KB") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Keypad 3") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Keypad ENTER") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + + PORT_START("KC") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("Keypad 7") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR(']') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + + PORT_START("KD") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("PF1") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('{') PORT_CHAR('}') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + + PORT_START("KE") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("Keypad 8") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("RETURN") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LINE FEED") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') + + PORT_START("KF") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Keypad 2") + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("Keypad 0") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("Keypad .") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RUBOUT") + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + + PORT_START("KM") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("INT") PORT_CHANGED_MEMBER(DEVICE_SELF, mtu130_state, nmi_w, 0) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("MOD") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RESET") PORT_CHANGED_MEMBER(DEVICE_SELF, mtu130_state, reset_w, 0) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("BREAK") PORT_CHANGED_MEMBER(DEVICE_SELF, mtu130_state, break_w, 0) +INPUT_PORTS_END + +ROM_START(mtu130) + ROM_REGION(0x800, "ipl", 0) + ROM_LOAD("ipl_prom.u6", 0, 0x100, CRC(edb1525a) SHA1(a16cce3b096f0fea9ac5c6993ee4241e4af1efde)) +ROM_END + +COMP(1981, mtu130, 0, 0, mtu130, mtu130, mtu130_state, empty_init, "Micro Technology Unlimited", "MTU-130", MACHINE_SUPPORTS_SAVE|MACHINE_IMPERFECT_SOUND) + -- cgit v1.2.3-70-g09d2