summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/m6502/dm6502mtu.lst20
-rw-r--r--src/devices/cpu/m6502/m6502.cpp14
-rw-r--r--src/devices/cpu/m6502/m6502mtu.cpp76
-rw-r--r--src/devices/cpu/m6502/m6502mtu.h151
-rw-r--r--src/devices/cpu/m6502/om6502mtu.lst2007
-rw-r--r--src/devices/machine/upd765.cpp2
-rw-r--r--src/emu/xtal.cpp1
-rw-r--r--src/mame/mame.lst3
-rw-r--r--src/mame/misc/mtu130.cpp590
9 files changed, 2858 insertions, 6 deletions
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<m6502mtu_device> m_maincpu;
+ required_device<via6522_device> m_user_6522;
+ required_device<via6522_device> m_sys1_6522;
+ required_device<via6522_device> m_sys2_6522;
+ required_device<mos6551_device> m_acia;
+ required_device<input_merger_device> m_irq_merger;
+ required_device<rs232_port_device> m_rs232;
+ required_device<upd765a_device> m_fdc;
+ required_device_array<floppy_connector, 4> m_floppy;
+ required_device<screen_device> m_screen;
+ required_device<palette_device> m_palette;
+ required_device<dac_byte_interface> m_dac;
+ required_device<speaker_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<u8> m_mainram;
+ required_shared_ptr<u8> m_fdcram;
+ required_shared_ptr<u8> 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)
+