/*------------------------------------------------------------------------- | SAE - Scripted Amiga Emulator | https://github.com/naTmeg/ScriptedAmigaEmulator | | Copyright (C) 2012-2016 Rupert Hausberger | | This program is free software; you can redistribute it and/or | modify it under the terms of the GNU General Public License | as published by the Free Software Foundation; either version 2 | of the License, or (at your option) any later version. | | This program is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | Notes: This file consists of two parts: high-level functions, | ported from WinUAE 3.2.x and low-level functions, written from scratch. -------------------------------------------------------------------------*/ /* global constants */ /*---------------------------------*/ /* global references */ var SAER_CPU_regs = null; var SAER_CPU_setPC = null; var SAER_CPU_getPC = null; var SAER_CPU_exception = null; var SAER_CPU_run_func = null; var SAER_CPU_fill_prefetch = null; /*---------------------------------*/ /* global variables */ var SAEV_CPU_cycles = 0; /*---------------------------------*/ function SAEO_CPU() { /* Exception 2/3 error */ function Exception23(num) { this.num = num; } Exception23.prototype = new Error; /* Exception 3 info */ var last_op_for_exception_3 = 0;/* Opcode of faulting instruction */ var last_addr_for_exception_3 = 0;/* PC at fault time */ var last_fault_for_exception_3 = 0;/* Address that generated the exception */ var last_writeaccess_for_exception_3 = false;/* read (0) or write (1) access */ var last_instructionaccess_for_exception_3 = false;/* instruction (1) or data (0) access */ var last_notinstruction_for_exception_3 = false;/* not instruction */ var exception_in_exception = 0; /* set when writing exception stack frame */ var bus_error_offset = 0; /* 68020 cache */ const CACR020_C = 1 << 3; /* Clear Cache */ const CACR020_CE = 1 << 2; /* Clear Entry in Cache */ const CACR020_F = 1 << 1; /* Freeze Cache */ const CACR020_E = 1 << 0; /* Enable Cache */ const CACR020_RMASK = 0x3; const CACR020_WMASK = 0xf; const CACHELINES020 = 64; const CACHELINE020_IM = CACHELINES020 - 1; const CACHELINE020_TM = ~((CACHELINES020 << 2) - 1) >>> 0; function cache020() { this.data = 0; this.tag = 0; this.valid = false; } var caches020 = new Array(CACHELINES020); for (var vi = 0; vi < CACHELINES020; vi++) caches020[vi] = new cache020(); /* 68030 cache */ const CACR030_WA = 1 << 13; /* Write Allocate */ const CACR030_DBE = 1 << 12; /* Data Burst Enable */ const CACR030_CD = 1 << 11; /* Clear Data Cache */ const CACR030_CED = 1 << 10; /* Clear Entry in Data Cache */ const CACR030_FD = 1 << 9; /* Freeze Data Cache */ const CACR030_ED = 1 << 8; /* Enable Data Cache */ const CACR030_IBE = 1 << 4; /* Instruction Burst Enable */ const CACR030_CI = 1 << 3; /* Clear Instruction Cache */ const CACR030_CEI = 1 << 2; /* Clear Entry in Instruction Cache */ const CACR030_FI = 1 << 1; /* Freeze Instruction Cache */ const CACR030_EI = 1 << 0; /* Enable Instruction Cache */ const CACR030_RMASK = 0x3313; const CACR030_WMASK = 0x3f1f; const CACHELINES030 = 16; const CACHELINE030_IM = CACHELINES030 - 1; const CACHELINE030_TM = ~((CACHELINES030 << 4) - 1) >>> 0; function cache030() { this.data = new Uint32Array(4); this.valid = [false, false, false, false]; this.tag = 0; } var icaches030 = new Array(CACHELINES030); for (var vi = 0; vi < CACHELINES030; vi++) icaches030[vi] = new cache030(); var dcaches030 = new Array(CACHELINES030); for (var vi = 0; vi < CACHELINES030; vi++) dcaches030[vi] = new cache030(); /* 68040 cache */ /*#define CACHESETS040 64 #define CACHELINES040 4 struct cache040 { uae_u32 data[CACHELINES040][4]; bool dirty[CACHELINES040][4]; bool valid[CACHELINES040]; uae_u32 tag[CACHELINES040]; }; static struct cache040 icaches040[CACHESETS040]; static struct cache040 dcaches040[CACHESETS040]; var icachelinecnt = 0, dcachelinecnt = 0;*/ /* 68030 fake MMU */ //var fake_srp_030 = 0, fake_crp_030 = 0; //64 var fake_srp_030_hi = 0, fake_srp_030_lo = 0; var fake_crp_030_hi = 0, fake_crp_030_lo = 0; var fake_tt0_030 = 0, fake_tt1_030 = 0, fake_tc_030 = 0; //32 var fake_mmusr_030 = 0; //16 /* shared CPU registers */ function regstruct() { this.a = new Uint32Array(8); this.d = new Uint32Array(8); this.pc = 0; //u32 this.pc_p = 0; //u8 * this.pc_oldp = 0; //u8 * this.opcode = 0; //u16 this.instruction_pc = 0; //u32 this.db = 0; //u16 this.irc = 0, this.ir = 0; //u16 //this.chipset_latch_rw = 0; //u32 //this.chipset_latch_read = 0; //u32 //this.chipset_latch_write = 0; //u32 this.usp = 0, this.isp = 0, this.msp = 0; this.t1 = false; this.t0 = false; this.s = false; this.m = false; this.intmask = 0; this.x = false; this.n = false; this.z = false; this.v = false; this.c = false; this.stopped = false; this.halted = 0; this.vbr = 0, this.sfc = 0, this.dfc = 0; //u32 this.cacr = 0, this.caar = 0; //u32 //uae_u32 itt0, itt1, dtt0, dtt1; //uae_u32 tcr, mmusr, urp, srp, buscr; this.prefetch020 = new Uint32Array(4); this.prefetch020addr = 0; //u32 this.cacheholdingdata020 = 0; //u32 this.cacheholdingaddr020 = 0; //u32 }; var regs = new regstruct(); SAER_CPU_regs = regs; const CYCLES_DIV = 8192; var cycles_mult = 0; var cpucycleunit = 0; var cpu_cycles = 0; var illegal_warned = 0; /*-----------------------------------------------------------------------*/ const PC_OFFSET = 2; var pc_offset = PC_OFFSET; //, pc_offset_old = 0; var coreGetPC = null; var coreSetPC = null; var coreSyncPC = null; var coreNext16 = null; var coreNext32 = null; var coreGetInst16 = null; var coreGetInst32 = null; var coreGet8 = null; var coreGet16 = null; var coreGet32 = null; var corePut8 = null; var corePut16 = null; var corePut32 = null; /*---------------------------------*/ const M_rdd = 1; /* Register Direct Data */ const M_rda = 2; /* Register Direct Address */ const M_ria = 3; /* Register Indirect Address */ const M_ripo = 4; /* Register Indirect Address with Postincrement */ const M_ripr = 5; /* Register Indirect Address with Predecrement */ const M_rid = 6; /* Register Indirect Address with Displacement */ const M_rii = 7; /* Address Register Indirect, with Index (8-Bit Displacement) */ const M_pcid = 8; /* Program Counter Indirect with Displacement */ const M_pcii = 9; /* Program Counter Indirect with Index (8-Bit Displacement) */ const M_absw = 10; /* Absolute Data Addressing */ const M_absl = 11; /* Absolute Data Addressing */ const M_imm = 12; /* Immediate Data */ const ccNames = ["T", "F", "HI", "LS", "CC", "CS", "NE", "EQ", "VC", "VS", "PL", "MI", "GE", "LT", "GT", "LE"]; var iTab = []; var ccTab = []; var exEAtab = []; var ldEA8tab = [], stEA8tab = []; var ldEA16tab = [], stEA16tab = []; var ldEA32tab = [], stEA32tab = []; var model = 0; /*-----------------------------------------------------------------------*/ /* SECT core high-level, ported from WinUAE */ /*-----------------------------------------------------------------------*/ this.setup = function() { //init_m68k() /*switch (SAEV_config.cpu.model) { case SAEC_Config_CPU_Model_68030: cpucycleunit = SAEC_Events_CYCLE_UNIT >> 3; break; case SAEC_Config_CPU_Model_68020: cpucycleunit = SAEC_Events_CYCLE_UNIT >> 2; break; default: cpucycleunit = SAEC_Events_CYCLE_UNIT >> 1; }*/ update_cycles(); if (SAEV_config.cpu.model < SAEC_Config_CPU_Model_68020) SAER_CPU_run_func = SAEV_config.cpu.compatible ? runPrefetch000 : runNormal; else SAER_CPU_run_func = SAEV_config.cpu.compatible ? runPrefetch020 : runNormal; setup_functions(); if (!iTab.length || model != SAEV_config.cpu.model) { //SAEF_log("cpu.setup_core() no/invalid instruction table, generating..."); model = SAEV_config.cpu.model; if (!mkITab()) return SAEE_CPU_Internal; } else SAEF_log("cpu.setup_core() instruction table is cached"); if (!ccTab.length) mkCCTab(); if (!exEAtab.length) mkEATabs(); return SAEE_None; } /*-----------------------------------------------------------------------*/ this.reset = function(hardreset) { regs.a[7] = SAER_Memory_get32(0); this.setPC_normal(SAER_Memory_get32(4)); regs.t1 = false; regs.t0 = false; regs.s = true; regs.m = false; regs.intmask = 7; regs.x = regs.n = regs.z = regs.v = regs.c = false; regs.vbr = regs.sfc = regs.dfc = 0; regs.irc = 0xffff; regs.db = 0; if (SAEV_config.cpu.model == SAEC_Config_CPU_Model_68020) { regs.caar = 0; regs.cacr = CACR020_C; coreSetCaches(false); } else if (SAEV_config.cpu.model == SAEC_Config_CPU_Model_68030) { //OWN regs.caar = 0; regs.cacr = CACR030_CD|CACR030_CI; coreSetCaches(false); } { SAER.memory.a3000_fakekick(false); /* only (E)nable bit is zeroed when CPU is reset, A3000 SuperKickstart expects this */ fake_tc_030 &= ~0x80000000; fake_tt0_030 &= ~0x80000000; fake_tt1_030 &= ~0x80000000; if (hardreset || regs.halted) { //fake_srp_030 = fake_crp_030 = 0; fake_srp_030_hi = fake_srp_030_lo = 0; fake_crp_030_hi = fake_crp_030_lo = 0; fake_tt0_030 = fake_tt1_030 = fake_tc_030 = 0; } fake_mmusr_030 = 0; } fill_prefetch(); illegal_warned = 0; } /*-----------------------------------------------------------------------*/ this.dump = function() { var i, j, out = ""; for (i = 0; i < 8; i++) out += sprintf("D%d $%08x ", i, regs.d[i]); out += "\n"; for (i = 0; i < 8; i++) out += sprintf("A%d $%08x ", i, regs.a[i]); out += "\n"; if (!regs.s) regs.usp = regs.a[7]; if (regs.s && regs.m) regs.msp = regs.a[7]; if (regs.s && !regs.m) regs.isp = regs.a[7]; out += sprintf("PC $%08x USP $%08x ISP $%08x ", getPC(), regs.usp, regs.isp); if (model >= SAEC_Config_CPU_Model_68020) out += sprintf("MSP $%08x ", regs.msp); if (model >= SAEC_Config_CPU_Model_68010) out += sprintf("SFC $%08x DFC $%08x VBR $%08x", regs.sfc, regs.dfc, regs.vbr); out += "\n"; out += sprintf("SR T=%d%d S=%d M=%d IMASK=%d X=%d N=%d Z=%d V=%d C=%d\n", regs.t1?1:0, regs.t0?1:0, regs.s?1:0, regs.m?1:0, regs.intmask, regs.x?1:0, regs.n?1:0, regs.z?1:0, regs.v?1:0, regs.c?1:0); if (model >= SAEC_Config_CPU_Model_68020) out += dump_cache(); SAEF_log(out); } /*-----------------------------------------------------------------------*/ /* caches */ function dump_cache() { if (!SAEV_config.cpu.compatible) return "CACHE disabled\n"; var out = sprintf("CACR $%08x CAAR $%08x\n", regs.cacr, regs.caar); if (SAEV_config.cpu.model == SAEC_Config_CPU_Model_68020) { out += "68020 inst-cache:\n"; for (var i = 0; i < CACHELINES020; i += 4) { for (var j = 0; j < 4; j++) { var s = i + j; var c = caches020[s]; var addr = c.tag & ~1; addr |= s << 2; out += sprintf("%08X:%08X%s ", addr, c.data, c.valid ? "*" : " "); } out += "\n"; } } else if (SAEV_config.cpu.model == SAEC_Config_CPU_Model_68030) { out += "68030 inst-cache: ["+((regs.cacr & CACR030_EI) ? "enabled" : "disabled") +"]\n"; for (var i = 0; i < CACHELINES030; i++) { var c = icaches030[i]; var addr = c.tag & ~1; addr |= i << 4; out += sprintf("%02d %08X: ", i, addr); for (var j = 0; j < 4; j++) out += sprintf("%08X%s ", c.data[j], c.valid[j] ? '*' : ' '); out += "\n"; } out += "68030 data-cache: ["+((regs.cacr & CACR030_ED) ? "enabled" : "disabled") +"]\n"; for (var i = 0; i < CACHELINES030; i++) { var c = dcaches030[i]; var addr = c.tag & ~1; addr |= i << 4; out += sprintf("%02d %08X: ", i, addr); for (var j = 0; j < 4; j++) out += sprintf("%08X%s ", c.data[j], c.valid[j] ? '*' : ' '); out += "\n"; } } return out; } function flush_caches(force) { //flush_cpu_caches() var doflush = SAEV_config.cpu.compatible; if (SAEV_config.cpu.model == SAEC_Config_CPU_Model_68020) { if (regs.cacr & CACR020_C) { for (var i = 0; i < CACHELINES020; i++) caches020[i].valid = false; regs.cacr &= ~CACR020_C; } if (regs.cacr & CACR020_CE) { caches020[(regs.caar >>> 2) & CACHELINE020_IM].valid = false; regs.cacr &= ~CACR020_CE; } } else if (SAEV_config.cpu.model == SAEC_Config_CPU_Model_68030) { if (regs.cacr & CACR030_CI) { if (doflush) { for (var i = 0; i < CACHELINES030; i++) { icaches030[i].valid[0] = false; icaches030[i].valid[1] = false; icaches030[i].valid[2] = false; icaches030[i].valid[3] = false; } } regs.cacr &= ~CACR030_CI; } if (regs.cacr & CACR030_CEI) { icaches030[(regs.caar >>> 4) & CACHELINE030_IM].valid[(regs.caar >>> 2) & 3] = 0; regs.cacr &= ~CACR030_CEI; } if (regs.cacr & CACR030_CD) { if (doflush) { for (var i = 0; i < CACHELINES030; i++) { dcaches030[i].valid[0] = false; dcaches030[i].valid[1] = false; dcaches030[i].valid[2] = false; dcaches030[i].valid[3] = false; } } regs.cacr &= ~CACR030_CD; } if (regs.cacr & CACR030_CED) { dcaches030[(regs.caar >>> 4) & CACHELINE030_IM].valid[(regs.caar >>> 2) & 3] = 0; regs.cacr &= ~CACR030_CED; } } /*else if (SAEV_config.cpu.model >= SAEC_Config_CPU_Model_68040) { icachelinecnt = 0; dcachelinecnt = 0; if (doflush) { for (var i = 0; i < CACHESETS040; i++) { icaches040[i].valid[0] = 0; icaches040[i].valid[1] = 0; icaches040[i].valid[2] = 0; icaches040[i].valid[3] = 0; } } }*/ } /*function flush_cpu_caches_040(opcode) { var cache = (opcode >> 6) & 3; if (cache & 2) flush_caches(true); }*/ function coreSetCaches(flush) { //set_cpu_caches() /*if (SAEV_config.cpu.model == SAEC_Config_CPU_Model_68020) { SAEF_log("cpu.set_caches_68020() C%d CE%d F%d E%d", (regs.cacr & CACR020_C )?1:0, (regs.cacr & CACR020_CE)?1:0, (regs.cacr & CACR020_F )?1:0, (regs.cacr & CACR020_E )?1:0 ); } else if (SAEV_config.cpu.model == SAEC_Config_CPU_Model_68030) { SAEF_log("cpu.set_caches_68030() WA%d DBE%d CD%d CED%d FD%d ED%d IBE%d CI%d CEI%d FI%d EI%d", (regs.cacr & CACR030_WA )?1:0, (regs.cacr & CACR030_DBE)?1:0, (regs.cacr & CACR030_CD )?1:0, (regs.cacr & CACR030_CED)?1:0, (regs.cacr & CACR030_FD )?1:0, (regs.cacr & CACR030_ED )?1:0, (regs.cacr & CACR030_IBE)?1:0, (regs.cacr & CACR030_CI )?1:0, (regs.cacr & CACR030_CEI)?1:0, (regs.cacr & CACR030_FI )?1:0, (regs.cacr & CACR030_EI )?1:0 ); }*/ regs.prefetch020addr = 0xffffffff; regs.cacheholdingaddr020 = 0xffffffff; flush_caches(flush); } /*---------------------------------*/ function fill_icache020(addr) { addr = (addr & ~3) >>> 0; if (regs.cacheholdingaddr020 != addr) { var index = (addr >>> 2) & CACHELINE020_IM; var tag = ((addr & CACHELINE020_TM) | (regs.s ? 1 : 0)) >>> 0; var c = caches020[index]; if (c.valid && c.tag == tag) { // cache hit regs.cacheholdingaddr020 = addr; regs.cacheholdingdata020 = c.data; } else { // cache miss //var data = SAER_Memory_getInst32(addr); var data = SAER_Memory_banks[addr >>> 16].getInst32(addr); if (!(regs.cacr & CACR020_F)) { c.tag = tag; c.valid = (regs.cacr & CACR020_E) != 0; c.data = data; } regs.cacheholdingaddr020 = addr; regs.cacheholdingdata020 = data; } } } /*---------------------------------*/ function getcache030(cp, addr, p) { addr = (addr & ~3) >>> 0; var index = (addr >>> 4) & CACHELINE030_IM; p.tag = ((addr & CACHELINE030_TM) | (regs.s ? 1 : 0)) >>> 0; p.lws = (addr >>> 2) & 3; return cp[index]; } function update_cache030(c, val, tag, lws) { if (c.tag != tag) c.valid[0] = c.valid[1] = c.valid[2] = c.valid[3] = false; c.tag = tag; c.valid[lws] = true; c.data[lws] = val; } function fill_icache030(addr) { addr = (addr & ~3) >>> 0; if (regs.cacheholdingaddr020 == addr) return; var p = {}; var c = getcache030(icaches030, addr, p); if (c.valid[p.lws] && c.tag == p.tag) { // cache hit regs.cacheholdingaddr020 = addr; regs.cacheholdingdata020 = c.data[p.lws]; return; } // cache miss //var data = SAER_Memory_getInst32(addr); var data = SAER_Memory_banks[addr >>> 16].getInst32(addr); if ((regs.cacr & (CACR030_FI|CACR030_EI)) == CACR030_EI) // not frozen and enabled update_cache030(c, data, p.tag, p.lws); // do burst fetch if cache enabled, not frozen, all slots invalid, no chip ram if ((regs.cacr & (CACR030_IBE|CACR030_EI)) == (CACR030_IBE|CACR030_EI) && p.lws == 0 && !c.valid[1] && !c.valid[2] && !c.valid[3] && SAER_Memory_banktype[addr >>> 16] == SAEC_Memory_banktype_FAST32 ) { /*c.data[1] = SAER_Memory_getInst32(addr + 4); c.data[2] = SAER_Memory_getInst32(addr + 8); c.data[3] = SAER_Memory_getInst32(addr + 12);*/ c.data[1] = SAER_Memory_banks[(addr + 4) >>> 16].getInst32(addr + 4); c.data[2] = SAER_Memory_banks[(addr + 8) >>> 16].getInst32(addr + 8); c.data[3] = SAER_Memory_banks[(addr + 12) >>> 16].getInst32(addr + 12); c.valid[1] = c.valid[2] = c.valid[3] = true; } regs.cacheholdingaddr020 = addr; regs.cacheholdingdata020 = data; } /*function get16_icache030(addr) { //get_word_icache030() fill_icache030(addr); if (addr & 2) return regs.cacheholdingdata020 & 0xffff; else return regs.cacheholdingdata020 >>> 16; } function get32_icache030(addr) { //get_long_icache030() fill_icache030(addr); if ((addr & 2) == 0) return regs.cacheholdingdata020; else { var v = regs.cacheholdingdata020 << 16; fill_icache030(addr + 4); v |= regs.cacheholdingdata020 >>> 16; return v >>> 0; } }*/ function read_dcache030x(addr, size) { var aligned = addr & 3; var v1, v2; var p1 = {}; var c1 = getcache030(dcaches030, addr, p1); addr = (addr & ~3) >>> 0; if (!c1.valid[p1.lws] || c1.tag != p1.tag) { v1 = SAER_Memory_get32(addr); update_cache030(c1, v1, p1.tag, p1.lws); } else { v1 = c1.data[p1.lws]; if (SAEV_AutoConf_boot_rom_type > 0) { var tv = SAER_Memory_get32(addr); if (tv != v1) { SAEF_warn("cpu.read_dcache030x() data cache mismatch %d %d %08x %08x != %08x %08x %d PC=%08x", size, aligned, addr, tv, v1, p1.tag, p1.lws, getPC()); v1 = tv; } } } // only one long fetch needed? if (size == 0) { v1 >>>= (3 - aligned) * 8; return v1 & 0xff; } else if (size == 1 && aligned <= 2) { v1 >>>= (2 - aligned) * 8; return v1 & 0xffff; } else if (size == 2 && aligned == 0) { // do burst fetch if cache enabled, not frozen, all slots invalid, no chip ram if ((regs.cacr & (CACR030_DBE|CACR030_ED)) == (CACR030_DBE|CACR030_ED) && p1.lws == 0 && !c1.valid[1] && !c1.valid[2] && !c1.valid[3] && SAER_Memory_banktype[addr >> 16] == SAEC_Memory_banktype_FAST32 ) { c1.data[1] = SAER_Memory_get32(addr + 4); c1.data[2] = SAER_Memory_get32(addr + 8); c1.data[3] = SAER_Memory_get32(addr + 12); c1.valid[1] = c1.valid[2] = c1.valid[3] = true; } return v1 >>> 0; } // no, need another one addr += 4; var p2 = {}; var c2 = getcache030(dcaches030, addr, p2); if (!c2.valid[p2.lws] || c2.tag != p2.tag) { v2 = SAER_Memory_get32(addr); update_cache030(c2, v2, p2.tag, p2.lws); } else { v2 = c2.data[p2.lws]; if (SAEV_AutoConf_boot_rom_type > 0) { var tv = SAER_Memory_get32(addr); if (tv != v2) { SAEF_warn("cpu.read_dcache030x() data cache mismatch %d %d %08x %08x != %08x %08x %d PC=%08x", size, aligned, addr, tv, v2, p2.tag, p2.lws, getPC()); v2 = tv; } } } if (size == 1 && aligned == 3) return ((v1 << 8) | (v2 >>> 24)) & 0xffff; else if (size == 2 && aligned == 1) return ((v1 << 8) | (v2 >>> 24)) >>> 0; else if (size == 2 && aligned == 2) return ((v1 << 16) | (v2 >>> 16)) >>> 0; else if (size == 2 && aligned == 3) return ((v1 << 24) | (v2 >>> 8)) >>> 0; SAEF_warn("cpu.read_dcache030x() weirdness!?"); return 0; } function write_dcache030x(addr, val, size) { var aligned = addr & 3; var wa = (regs.cacr & CACR030_WA) != 0; var p1 = {}; var c1 = getcache030(dcaches030, addr, p1); // easy one if (size == 2 && aligned == 0 && wa) { update_cache030(c1, val, p1.tag, p1.lws); return; } var hit = (c1.tag == p1.tag && c1.valid[p1.lws]); if (hit || wa) { if (size == 2) { if (hit) { c1.data[p1.lws] &= ~(0xffffffff >>> (aligned * 8)); c1.data[p1.lws] |= val >>> (aligned * 8); } else c1.valid[p1.lws] = false; } else if (size == 1) { if (hit) { c1.data[p1.lws] &= ~(0xffff0000 >>> (aligned * 8)); c1.data[p1.lws] |= (val << 16) >>> (aligned * 8); } else c1.valid[p1.lws] = false; } else if (size == 0) { if (hit) { c1.data[p1.lws] &= ~(0xff000000 >>> (aligned * 8)); c1.data[p1.lws] |= (val << 24) >>> (aligned * 8); } else c1.valid[p1.lws] = false; } } // do we need to update a 2nd cache entry ? if ((size == 0) || (size == 1 && aligned <= 2) || (size == 2 && aligned == 0)) return; var p2 = {}; var c2 = getcache030(dcaches030, addr + 4, p2); hit = (c2.tag == p2.tag && c2.valid[p2.lws]); if (hit || wa) { if (size == 2) { if (hit) { c2.data[p2.lws] &= 0xffffffff >>> (aligned * 8); c2.data[p2.lws] |= val << ((4 - aligned) * 8); } else c2.valid[p2.lws] = false; } else if (size == 1) { if (hit) { c2.data[p2.lws] &= 0x00ffffff; c2.data[p2.lws] |= val << 24; } else c2.valid[p2.lws] = false; } } } function cancache030(addr) { return SAER_Memory_cachable[addr >>> 16] != 0; } function read_dcache030(addr, size) { if ((regs.cacr & CACR030_ED) && cancache030(addr)) return read_dcache030x(addr, size); if (size == 2) return SAER_Memory_get32(addr); else if (size == 1) return SAER_Memory_get16(addr); else return SAER_Memory_get8(addr); } function get32_dcache030(addr) { //get_long_030() return read_dcache030(addr, 2); } function get16_dcache030(addr) { //get_word_030() return read_dcache030(addr, 1); } function get8_dcache030(addr) { //get_byte_030() return read_dcache030(addr, 0); } function write_dcache030(addr, v, size) { if ((regs.cacr & CACR030_ED) && cancache030(addr)) write_dcache030x(addr, v, size); if (size == 2) SAER_Memory_put32(addr, v); else if (size == 1) SAER_Memory_put16(addr, v); else SAER_Memory_put8(addr, v); } function put32_dcache030(addr, v) { //put_long_030() write_dcache030(addr, v, 2); } function put16_dcache030(addr, v) { //put_word_030() write_dcache030(addr, v, 1); } function put8_dcache030(addr, v) { //put_byte_030() write_dcache030(addr, v, 0); } /*---------------------------------*/ /* prefetch */ function getInst16_icache020_prefetch(o) { //get_word_020_prefetch() var pc = getPC() + o; var v; if (pc & 2) { v = regs.prefetch020[0] & 0xffff; regs.prefetch020[0] = regs.prefetch020[1]; fill_icache020(pc + 2 + 4); regs.prefetch020[1] = regs.cacheholdingdata020; regs.db = regs.prefetch020[0] >>> 16; } else { v = regs.prefetch020[0] >>> 16; regs.db = regs.prefetch020[0]; } return v; } function getInst32_icache020_prefetch(o) { //get_long_020_prefetch() return ((getInst16_icache020_prefetch(o) << 16) | getInst16_icache020_prefetch(o + 2)) >>> 0; } function getInst16_icache030_prefetch(o) { //get_word_030_prefetch() var pc = getPC() + o; var v; if (pc & 2) { v = regs.prefetch020[0] & 0xffff; regs.prefetch020[0] = regs.prefetch020[1]; fill_icache030(pc + 2 + 4); regs.prefetch020[1] = regs.cacheholdingdata020; } else v = regs.prefetch020[0] >>> 16; return v; } function getInst32_icache030_prefetch(o) { //get_long_030_prefetch() return ((getInst16_icache030_prefetch(o) << 16) | getInst16_icache030_prefetch(o + 2)) >>> 0; } function fill_prefetch_020() { var pc = (getPC() & ~3) >>> 0; fill_icache020(pc); regs.prefetch020[0] = regs.cacheholdingdata020; fill_icache020(pc + 4); regs.prefetch020[1] = regs.cacheholdingdata020; regs.irc = getInst16_icache020_prefetch(0); } function fill_prefetch_030() { var pc = (getPC() & ~3) >>> 0; fill_icache030(pc); regs.prefetch020[0] = regs.cacheholdingdata020; fill_icache030(pc + 4); regs.prefetch020[1] = regs.cacheholdingdata020; regs.irc = getInst16_icache030_prefetch(0); } function fill_prefetch() { //regs.pipeline_pos = 0; if (!SAEV_config.cpu.compatible) return; /*if (SAEV_config.cpu.model >= SAEC_Config_CPU_Model_68040) { if (SAEV_config.cpu.compatible || currprefs.cpu_memory_cycle_exact) { fill_icache040(getPC() + 16); fill_icache040(getPC()); } } else*/ if (SAEV_config.cpu.model == SAEC_Config_CPU_Model_68030) fill_prefetch_030(); else if (SAEV_config.cpu.model == SAEC_Config_CPU_Model_68020) fill_prefetch_020(); else if (SAEV_config.cpu.model <= SAEC_Config_CPU_Model_68010) { var pc = getPC(); //regs.ir = SAER_Memory_getInst16(pc); //regs.irc = SAER_Memory_getInst16(pc + 2); regs.ir = SAER_Memory_banks[pc >>> 16].getInst16(pc); regs.irc = SAER_Memory_banks[(pc + 2) >>> 16].getInst16(pc + 2); } } SAER_CPU_fill_prefetch = fill_prefetch; /*-----------------------------------------------------------------------*/ /* PC direct (regs.pc_p) access */ function setPC(newpc) { //m68k_setpc() regs.instruction_pc = regs.pc = newpc; regs.pc_p = regs.pc_oldp = newpc; } SAER_CPU_setPC = setPC; function getPC() { //m68k_getpc() return regs.pc + (regs.pc_p - regs.pc_oldp); } SAER_CPU_getPC = getPC; function incPC(o) { //m68k_incpc() regs.pc_p += o; } function syncPC() { setPC(getPC()); } /*function setPC_default(pc) { setPC(pc); pc_offset = PC_OFFSET; } function getPC_default() { return getPC() + pc_offset; } function syncPC_default() { //pc_offset_old = pc_offset; incPC(pc_offset); pc_offset = PC_OFFSET; } function syncPC_default_noreset() { //sync_m68k_pc_noreset() coreSyncPC(); pc_offset = pc_offset_old; } function clrPC_default() { //clear_m68k_offset() pc_offset = 0; }*/ /*---------------------------------*/ /* PC indirect (regs.pc) access */ function setPCi(newpc) { //m68k_setpci() regs.instruction_pc = regs.pc = newpc; } function getPCi() { //m68k_getpci() return regs.pc; } function incPCi(o) { //m68k_incpci() regs.pc += o; } //function syncPCi() {} function getPC_prefetch() { return getPCi() + pc_offset; } function setPC_prefetch(pc) { setPCi(pc); pc_offset = PC_OFFSET; fill_prefetch(); } function syncPC_prefetch() { //pc_offset_old = pc_offset; incPCi(pc_offset); pc_offset = PC_OFFSET; regs.ir = getInst16_prefetch(2); } function syncPC_icache020_prefetch() { //pc_offset_old = pc_offset; incPCi(pc_offset); pc_offset = PC_OFFSET; regs.irc = getInst16_icache020_prefetch(0); } function syncPC_icache030_prefetch() { //pc_offset_old = pc_offset; incPCi(pc_offset); pc_offset = PC_OFFSET; regs.irc = getInst16_icache030_prefetch(0); } /*-----------------------------------------------------------------------*/ /* PC common access */ this.setPC_normal = function(pc) { //m68k_setpc_normal() if (SAEV_config.cpu.compatible) { regs.pc_p = regs.pc_oldp = 0; setPCi(pc); } else setPC(pc); } this.getPC_normal = function() { //m68k_getpc_normal() if (SAEV_config.cpu.compatible) return getPCi(); else return getPC(); } this.incPC_normal = function(o) { //m68k_incpc_normal() if (SAEV_config.cpu.compatible) incPCi(o); else incPC(o); } /*-----------------------------------------------------------------------*/ /* next instruction direct (regs.pc_p) */ function nextInst16_default() { //next_diword() //var r = SAER_Memory_getInst16(regs.pc_p); var r = SAER_Memory_banks[regs.pc_p >>> 16].getInst16(regs.pc_p); regs.pc_p += 2; //incPC(2); return r; } function nextInst32_default() { //next_dilong() //var r = SAER_Memory_getInst32(regs.pc_p); var r = SAER_Memory_banks[regs.pc_p >>> 16].getInst32(regs.pc_p); regs.pc_p += 4; //incPC(4); return r; } /*function nextInst16_default() { var r = pc_offset; pc_offset += 2; return SAER_Memory_getInst16(regs.pc_p + r); } function nextInst32_default() { var r = pc_offset; pc_offset += 4; return SAER_Memory_getInst32(regs.pc_p + r); }*/ function getInst16_default(o) { //get_diword() //return SAER_Memory_getInst16(regs.pc_p + o); return SAER_Memory_banks[(regs.pc_p + o) >>> 16].getInst16(regs.pc_p + o); } function getInst32_default(o) { //get_dilong() //return SAER_Memory_getInst32(regs.pc_p + o); return SAER_Memory_banks[(regs.pc_p + o) >>> 16].getInst32(regs.pc_p + o); } /*function m68k_do_bsr(oldpc, offset) { regs.a[7] -= 4; SAER_Memory_put32(regs.a[7], oldpc); incPC(offset); } function m68k_do_rts() { uae_u32 newpc = SAER_Memory_get32(regs.a[7]); setPC(newpc); regs.a[7] += 4; }*/ /*-----------------------------------------------------------------------*/ /* next instruction indirect (regs.pc) */ /*function next_iibyte() { var r = get_iibyte(0); incPCi(2); return r; } function next_iiword() { var r = get_iiword(0); incPCi(2); return r; } function next_iilong() { var r = get_iilong(0); incPCi(4); return r; } function next_iiwordi() { var r = SAER_Memory_getInst16(getPCi()); incPCi(2); return r; } function next_iilongi() { var r = SAER_Memory_getInst32(getPCi()); incPCi(4); return r; } function get_iibyte(o) { return SAER_Memory_getInst16(getPCi() + o) & 0xff; } function get_iiword(o) { return SAER_Memory_getInst16(getPCi() + o); } function get_iilong(o) { return SAER_Memory_getInst32(getPCi() + o); } function void m68k_do_bsri(oldpc, offset) { regs.a[7] -= 4; SAER_Memory_put32(regs.a[7], oldpc); incPCi(offset); } function void m68k_do_rtsi() { uae_u32 newpc = SAER_Memory_get32(regs.a[7]); setPCi(newpc); regs.a[7] += 4; }*/ /*-----------------------------------------------------------------------*/ /* 68000/68010 prefetch */ function getInst16_prefetch(o) { //get_word_000_prefetch() var v = regs.irc; //regs.irc = regs.db = SAER_Memory_getInst16(getPCi() + o); //regs.irc = regs.db = SAER_Memory_getInst16(regs.pc + o); regs.irc = regs.db = SAER_Memory_banks[(regs.pc + o) >>> 16].getInst16(regs.pc + o); return v; } function getInst32_prefetch(o) { //get_long_000_prefetch() return ((getInst16_prefetch(o) << 16) | getInst16_prefetch(o + 2)) >>> 0; } /*function nextInst16_prefetch() { //OWN var r = getInst16_prefetch(0); incPCi(2); return r; } function nextInst32_prefetch() { //OWN return ((nextInst16_prefetch() << 16) | nextInst16_prefetch()) >>> 0; }*/ function nextInst16_prefetch() { var r = pc_offset; pc_offset += 2; return getInst16_prefetch(r + 2); } function nextInst32_prefetch() { var r = pc_offset; pc_offset += 4; return getInst32_prefetch(r + 2); } function get8_prefetch(addr) { //get_byte_000() var v = SAER_Memory_get8(addr); regs.db = (v << 8) | v; return v; } function get16_prefetch(addr) { //get_word_000() var v = SAER_Memory_get16(addr); regs.db = v; return v; } function get32_prefetch(addr) { //OWN return ((get16_prefetch(addr) << 16) | get16_prefetch(addr + 2)) >>> 0; } function put8_prefetch(addr, v) { //put_byte_000() regs.db = (v << 8) | v; SAER_Memory_put8(addr, v); } function put16_prefetch(addr, v) { //put_word_000() regs.db = v; SAER_Memory_put16(addr, v); } function put32_prefetch(addr, v) { //OWN put16_prefetch(addr, v >>> 16); put16_prefetch(addr + 2, v & 0xffff); } /*---------------------------------*/ /* 68020 prefetch */ /*function nextInst16_icache020_prefetch() { //next_iword_020_prefetch() var r = getInst16_icache020_prefetch(0); incPCi(2); return r; } function nextInst32_icache020_prefetch() { //next_ilong_020_prefetch() return ((nextInst16_icache020_prefetch() << 16) | nextInst16_icache020_prefetch()) >>> 0; }*/ function nextInst16_icache020_prefetch() { var r = pc_offset; pc_offset += 2; return getInst16_icache020_prefetch(r); } function nextInst32_icache020_prefetch() { var r = pc_offset; pc_offset += 4; return getInst32_icache020_prefetch(r); } /*---------------------------------*/ /* 68030 prefetch */ /*function nextInst16_icache030_prefetch() { //next_iword_030_prefetch() var r = getInst16_icache030_prefetch(0); incPCi(2); return r; } function nextInst32_icache030_prefetch() { //next_ilong_030_prefetch() var r = getInst32_icache030_prefetch(0); incPCi(4); return r; }*/ function nextInst16_icache030_prefetch() { var r = pc_offset; pc_offset += 2; return getInst16_icache030_prefetch(r); } function nextInst32_icache030_prefetch() { var r = pc_offset; pc_offset += 4; return getInst32_icache030_prefetch(r); } /*function m68k_do_bsr_030(oldpc, offset) { regs.a[7] -= 4; dcachePut32(regs.a[7], oldpc); incPCi(offset); } function m68k_do_rts_030() { setPC(dcacheGet32(regs.a[7])); regs.a[7] += 4; }*/ /*---------------------------------*/ function setup_functions() { if (SAEV_config.cpu.compatible) { coreGetPC = getPC_prefetch; coreSetPC = setPC_prefetch; if (SAEV_config.cpu.model < SAEC_Config_CPU_Model_68020) { coreSyncPC = syncPC_prefetch; coreNext16 = nextInst16_prefetch; coreNext32 = nextInst32_prefetch; coreGetInst16 = getInst16_prefetch; coreGetInst32 = getInst32_prefetch; coreGet8 = get8_prefetch; coreGet16 = get16_prefetch; coreGet32 = get32_prefetch; corePut8 = put8_prefetch; corePut16 = put16_prefetch; corePut32 = put32_prefetch; } else if (SAEV_config.cpu.model == SAEC_Config_CPU_Model_68020) { coreSyncPC = syncPC_icache020_prefetch; coreNext16 = nextInst16_icache020_prefetch; coreNext32 = nextInst32_icache020_prefetch; coreGetInst16 = getInst16_icache020_prefetch; coreGetInst32 = getInst32_icache020_prefetch; coreGet32 = SAER_Memory_get32; corePut32 = SAER_Memory_put32; coreGet16 = SAER_Memory_get16; corePut16 = SAER_Memory_put16; coreGet8 = SAER_Memory_get8; corePut8 = SAER_Memory_put8; } else if (SAEV_config.cpu.model == SAEC_Config_CPU_Model_68030) { coreSyncPC = syncPC_icache030_prefetch; coreNext16 = nextInst16_icache030_prefetch; coreNext32 = nextInst32_icache030_prefetch; coreGetInst32 = getInst32_icache030_prefetch; coreGetInst16 = getInst16_icache030_prefetch; coreGet8 = get8_dcache030; coreGet16 = get16_dcache030; coreGet32 = get32_dcache030; corePut8 = put8_dcache030; corePut16 = put16_dcache030; corePut32 = put32_dcache030; } } else { //coreGetPC = getPC_default; //coreSetPC = setPC_default; //coreSyncPC = syncPC_default; coreGetPC = getPC; coreSetPC = setPC; coreSyncPC = syncPC; coreNext16 = nextInst16_default; coreNext32 = nextInst32_default; coreGetInst32 = getInst32_default; coreGetInst16 = getInst16_default; coreGet32 = SAER_Memory_get32; corePut32 = SAER_Memory_put32; coreGet16 = SAER_Memory_get16; corePut16 = SAER_Memory_put16; coreGet8 = SAER_Memory_get8; corePut8 = SAER_Memory_put8; } } /*-----------------------------------------------------------------------*/ function coreReset() { SAER.m68k.cpureset(); } function coreStop() { SAER.m68k.m68k_setstopped(); } /*-----------------------------------------------------------------------*/ function coreGetCCR() { return (((regs.x ? 1 : 0) << 4) | ((regs.n ? 1 : 0) << 3) | ((regs.z ? 1 : 0) << 2) | ((regs.v ? 1 : 0) << 1) | (regs.c ? 1 : 0)); } function coreSetCCR(ccr) { regs.x = ((ccr >> 4) & 1) == 1; regs.n = ((ccr >> 3) & 1) == 1; regs.z = ((ccr >> 2) & 1) == 1; regs.v = ((ccr >> 1) & 1) == 1; regs.c = (ccr & 1) == 1; } /*-----------------------------------------------------------------------*/ function coreGetSR() { return ( ((regs.t1 ? 1 : 0) << 15) | ((regs.t0 ? 1 : 0) << 14) | ((regs.s ? 1 : 0) << 13) | ((regs.m ? 1 : 0) << 12) | (regs.intmask << 8) | ((regs.x ? 1 : 0) << 4) | ((regs.n ? 1 : 0) << 3) | ((regs.z ? 1 : 0) << 2) | ((regs.v ? 1 : 0) << 1) | (regs.c ? 1 : 0) ); } function coreSetSR(sr) { var oldm = regs.m; var olds = regs.s; regs.x = ((sr >> 4) & 1) == 1; regs.n = ((sr >> 3) & 1) == 1; regs.z = ((sr >> 2) & 1) == 1; regs.v = ((sr >> 1) & 1) == 1; regs.c = (sr & 1) == 1; var t1 = ((sr >> 15) & 1) == 1; var t0 = ((sr >> 14) & 1) == 1; var s = ((sr >> 13) & 1) == 1; var m = ((sr >> 12) & 1) == 1; var intmask = ((sr >> 8) & 7); if (regs.t1 == t1 && regs.t0 == t0 && regs.s == s && regs.m == m && regs.intmask == intmask) { //SAEF_log("cpu.coreSetSR() mode ok!"); return; } regs.t1 = t1; regs.t0 = t0; regs.s = s; regs.m = m; regs.intmask = intmask; if (SAEV_config.cpu.model >= SAEC_Config_CPU_Model_68020) { if (olds != regs.s) { if (olds) { if (oldm) regs.msp = regs.a[7]; else regs.isp = regs.a[7]; regs.a[7] = regs.usp; } else { regs.usp = regs.a[7]; regs.a[7] = regs.m ? regs.msp : regs.isp; } } else if (olds && oldm != regs.m) { if (oldm) { regs.msp = regs.a[7]; regs.a[7] = regs.isp; } else { regs.isp = regs.a[7]; regs.a[7] = regs.msp; } } } else { regs.t0 = regs.m = 0; if (olds != regs.s) { if (olds) { regs.isp = regs.a[7]; regs.a[7] = regs.usp; } else { regs.usp = regs.a[7]; regs.a[7] = regs.isp; } } } SAER.m68k.doint_trace(regs.t1 || regs.t0); /*{ if (regs.t1 || regs.t0) SAEF_setSpcFlags(SAEC_spcflag_TRACE); else SAEF_clrSpcFlags(SAEC_spcflag_TRACE); }*/ } /*-----------------------------------------------------------------------*/ /* exception */ function exception_trace(nr) { SAEF_clrSpcFlags(SAEC_spcflag_TRACE | SAEC_spcflag_DOTRACE); if (regs.t1 && !regs.t0) { if (nr == 5 || nr == 6 || nr == 7 || (nr >= 32 && nr <= 47)) SAEF_setSpcFlags(SAEC_spcflag_DOTRACE); } regs.t1 = regs.t0 = regs.m = false; } function exception_pc(nr) { // bus error, address error, illegal instruction, privilege violation, a-line, f-line if (nr == 2 || nr == 3 || nr == 4 || nr == 8 || nr == 10 || nr == 11) return regs.instruction_pc; return getPC(); } function add_approximate_exception_cycles(nr) { var cycles; if (SAEV_config.cpu.model > SAEC_Config_CPU_Model_68000) return; if (nr >= 24 && nr <= 31) { /* Interrupts */ cycles = 44 + 4; } else if (nr >= 32 && nr <= 47) { /* Trap (total is 34, but cpuemux.c already adds 4) */ cycles = 34; //- 4; } else { switch (nr) { case 2: cycles = 50; break; /* Bus error */ case 3: cycles = 50; break; /* Address error */ case 4: cycles = 34; break; /* Illegal instruction */ case 5: cycles = 38; break; /* Division by zero */ case 6: cycles = 40; break; /* CHK */ case 7: cycles = 34; break; /* TRAPV */ case 8: cycles = 34; break; /* Privilege violation */ case 9: cycles = 34; break; /* Trace */ case 10: cycles = 34; break; /* Line-A */ case 11: cycles = 34; break; /* Line-F */ default: cycles = 4; } } //SAEF_log("cpu.add_approximate_exception_cycles() nr %d, cycles %d", nr, cycles); //cycles = cycles * cpucycleunit; //cycles = adjust_cycles(cycles * SAEC_Events_CYCLE_UNIT / 2); cycles = adjust_cycles((cycles * SAEC_Events_CYCLE_UNIT) >> 1); SAER.events.do_cycles(cycles); } function add_approximate_exception_cycles_020(nr) { //OWN var cycles; if (nr >= 24 && nr <= 31) { /* Interrupts */ cycles = regs.m ? 41 : 26; } else if (nr >= 32 && nr <= 47) { /* Trap */ cycles = 20; } else { switch (nr) { case 2: cycles = 50; break; /* Bus error */ case 3: cycles = 50; break; /* Address error */ case 4: cycles = 20; break; /* Illegal instruction */ case 5: cycles = 20; break; /* Division by zero */ case 6: cycles = 20; break; /* CHK */ case 7: cycles = 23; break; /* TRAPV */ case 8: cycles = 20; break; /* Privilege violation */ case 9: cycles = 25; break; /* Trace */ case 10: cycles = 20; break; /* Line-A */ case 11: cycles = 20; break; /* Line-F */ default: cycles = 4; } } //SAEF_log("cpu.add_approximate_exception_cycles_020() nr %d, cycles %d", nr, cycles); cycles = cycles * cpucycleunit; SAER.events.do_cycles(cycles); } function exception(nr) { var currpc; var sv = regs.s; var vector_nr = nr; var kludge_me_do = true; var interrupt = nr >= 24 && nr < 24 + 8; if (interrupt && SAEV_config.cpu.model <= SAEC_Config_CPU_Model_68010) vector_nr = coreGet8(0x00fffff1 | ((nr - 24) << 1)); var sr = coreGetSR(); if (!regs.s) { regs.usp = regs.a[7]; if (SAEV_config.cpu.model >= SAEC_Config_CPU_Model_68020) { regs.a[7] = regs.m ? regs.msp : regs.isp; } else { regs.a[7] = regs.isp; } regs.s = true; } if ((regs.a[7] & 1) && SAEV_config.cpu.model < SAEC_Config_CPU_Model_68020) { if (nr == 2 || nr == 3) SAER.m68k.cpu_halt(SAEC_CPU_halt_DOUBLE_FAULT); else exception3_notinstruction(regs.ir, regs.a[7]); return; } if ((nr == 2 || nr == 3) && exception_in_exception < 0) { SAER.m68k.cpu_halt(SAEC_CPU_halt_DOUBLE_FAULT); return; } if (SAEV_config.cpu.model > SAEC_Config_CPU_Model_68000) { /*if (SAEV_config.cpu.model >= SAEC_Config_CPU_Model_68020) //OWN add_approximate_exception_cycles_020(nr); else add_approximate_exception_cycles(nr);*/ currpc = exception_pc(nr); if (nr == 2 || nr == 3) { var ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1); ssw |= last_writeaccess_for_exception_3 ? 0 : 0x40; ssw |= 0x20; /*for (var i = 0 ; i < 36; i++) { regs.a[7] -= 2; corePut16(regs.a[7], 0); } regs.a[7] -= 4; corePut32(regs.a[7], last_fault_for_exception_3); regs.a[7] -= 2; corePut16(regs.a[7], 0); regs.a[7] -= 2; corePut16(regs.a[7], 0); regs.a[7] -= 2; corePut16(regs.a[7], 0); regs.a[7] -= 2; corePut16(regs.a[7], ssw); regs.a[7] -= 2; corePut16(regs.a[7], 0xb000 + vector_nr * 4);*/ for (var i = 0 ; i < 36; i++) stackPut16(0); stackPut32(last_fault_for_exception_3); stackPut16(0); stackPut16(0); stackPut16(0); stackPut16(ssw); stackPut16(0xb000 + vector_nr * 4); SAEF_log("cpu.exception() %d (%x) at %x -> %x!", nr, regs.instruction_pc, currpc, SAER_Memory_get32(regs.vbr + 4 * vector_nr)); } else if (nr == 5 || nr == 6 || nr == 7 || nr == 9) { //regs.a[7] -= 4; corePut32(regs.a[7], regs.instruction_pc); //regs.a[7] -= 2; corePut16(regs.a[7], 0x2000 + vector_nr * 4); stackPut32(regs.instruction_pc); stackPut16(0x2000 + vector_nr * 4); } else if (regs.m && interrupt) { // M + Interrupt //regs.a[7] -= 2; corePut16(regs.a[7], vector_nr * 4); //regs.a[7] -= 4; corePut32(regs.a[7], currpc); //regs.a[7] -= 2; corePut16(regs.a[7], sr); stackPut16(vector_nr * 4); stackPut32(currpc); stackPut16(sr); //sr |= (1 << 13); regs.s = true; regs.msp = regs.a[7]; regs.m = false; regs.a[7] = regs.isp; //regs.a[7] -= 2; corePut16(regs.a[7], 0x1000 + vector_nr * 4); stackPut16(0x1000 + vector_nr * 4); } else { //regs.a[7] -= 2; corePut16(regs.a[7], vector_nr * 4); stackPut16(vector_nr * 4); } } else { add_approximate_exception_cycles(nr); //currpc = getPC(); currpc = exception_pc(nr); if (nr == 2 || nr == 3) { var mode = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1); mode |= last_writeaccess_for_exception_3 ? 0 : 16; mode |= last_notinstruction_for_exception_3 ? 8 : 0; mode |= last_op_for_exception_3 & ~31;// undocumented bits seem to contain opcode exception_in_exception = -1; /*regs.a[7] -= 14; corePut16(regs.a[7] + 0, mode); corePut32(regs.a[7] + 2, last_fault_for_exception_3); corePut16(regs.a[7] + 6, last_op_for_exception_3); corePut16(regs.a[7] + 8, sr); corePut32(regs.a[7] + 10, last_addr_for_exception_3);*/ stackPut32(last_addr_for_exception_3); stackPut16(sr); stackPut16(last_op_for_exception_3); stackPut32(last_fault_for_exception_3); stackPut16(mode); SAEF_log("cpu.exception() %d (%x) at %x -> %x!", nr, last_fault_for_exception_3, currpc, SAER_Memory_get32(regs.vbr + 4 * vector_nr)); //goto kludge_me_do; kludge_me_do = false; } //else //SAEF_log("cpu.exception() %d at %x -> %x!", nr, currpc, SAER_Memory_get32(regs.vbr + 4 * vector_nr)); } if (kludge_me_do) { //regs.a[7] -= 4; corePut32(regs.a[7], currpc); //regs.a[7] -= 2; corePut16(regs.a[7], sr); stackPut32(currpc); stackPut16(sr); } //kludge_me_do: var newpc = coreGet32(regs.vbr + 4 * vector_nr); //SAEF_log("cpu.exception() %08x -> %08x", currpc, newpc); exception_in_exception = 0; if (newpc & 1) { if (nr == 2 || nr == 3) SAER.m68k.cpu_halt(SAEC_CPU_halt_DOUBLE_FAULT); else exception3_notinstruction(regs.ir, newpc); return; } setPC(newpc); fill_prefetch(); exception_trace(nr); } SAER_CPU_exception = exception; function coreException(nr) { if (!(nr == 2 || nr == 3 || nr == 4 || nr == 8 || nr == 10 || nr == 11)) coreSyncPC(); exception(nr); return [0,0,0]; } function exception3f(opcode, addr, writeaccess, instructionaccess, notinstruction, pc, plus2) { if (SAEV_config.cpu.model >= SAEC_Config_CPU_Model_68020) { if (pc == 0xffffffff) last_addr_for_exception_3 = regs.instruction_pc; else last_addr_for_exception_3 = pc; } else if (pc == 0xffffffff) { last_addr_for_exception_3 = getPC(); if (plus2) last_addr_for_exception_3 += 2; } else { last_addr_for_exception_3 = pc; } last_fault_for_exception_3 = addr; last_op_for_exception_3 = opcode; last_writeaccess_for_exception_3 = writeaccess; last_instructionaccess_for_exception_3 = instructionaccess; last_notinstruction_for_exception_3 = notinstruction; exception(3); } function exception3_notinstruction(opcode, addr) { exception3f(opcode, addr, true, false, true, 0xffffffff, false); } function exception3i(opcode, addr) { exception3f(opcode, addr, 0, 1, false, 0xffffffff, true); } /*this.exception3b = function(opcode, addr, w, i, pc) { exception3f(opcode, addr, w, i, false, pc, true); } this.exception3_read = function(opcode, addr) { exception3f(opcode, addr, false, 0, false, 0xffffffff, false); } this.exception3_write = function(opcode, addr) { exception3f(opcode, addr, true, 0, false, 0xffffffff, false); }*/ function coreException3i(opcode, addr) { exception3i(opcode, addr) return [0,0,0]; } this.exception2 = function(addr, read, size, fc) { last_addr_for_exception_3 = getPC() + bus_error_offset; last_fault_for_exception_3 = addr; last_writeaccess_for_exception_3 = read == 0; last_instructionaccess_for_exception_3 = (fc & 1) == 0; last_op_for_exception_3 = regs.opcode; last_notinstruction_for_exception_3 = exception_in_exception != 0; throw new Exception23(2); } /*-----------------------------------------------------------------------*/ /* illegal instruction */ function munge24(x) { return (x & (SAEV_config.cpu.addressSpace24 ? 0x00ffffff : 0xffffffff)) >>> 0; } function in_rom(pc) { return (munge24(pc) & 0xFFF80000) >>> 0 == 0xF80000; } function in_rtarea(pc) { return (munge24(pc) & 0xFFFF0000) >>> 0 == SAEV_AutoConf_base && SAEV_AutoConf_boot_rom_type; } this.pc_in_rom = function() { /* used in cia.ciab_checkalarm() */ var pc = getPC(); return (munge24(pc) & 0xFFF80000) == 0xF80000; } function illegal(opcode) { var pc = getPC(); var inrom = in_rom(pc); var inrt = in_rtarea(pc); if (SAEV_Memory_cloantoRom && (opcode & 0xF100) == 0x7100) { regs.d[(opcode >> 9) & 7] = extByte(opcode & 0xFF); SAER.cpu.incPC_normal(2); fill_prefetch(); return true; } if (opcode == 0x4E7B && inrom) { if (SAER_Memory_get32(0x10) == 0) { SAEF_fatal(SAEE_CPU_Requires68020, "The selected kickstart-rom does require a 68020 and 32bit address-space"); //notify_user (NUMSG_KS68020); //uae_restart(-1, null); } } //#ifdef AUTOCONFIG if (opcode == 0xFF0D && inrt) { // User-mode STOP replacement SAEF_log("cpu.illegal() STOP replacement, pc %08x", pc); m68k_setstopped(); return true; } if ((opcode & 0xF000) == 0xA000 && inrt) { // Calltrap. SAEF_log("cpu.illegal() Trap %03X at %08X, call...", opcode & 0xFFF, pc); SAER.cpu.incPC_normal(2); SAER.autoconf.m68k_handle_trap(opcode & 0xFFF); fill_prefetch(); return true; } //#endif if ((opcode & 0xF000) == 0xF000) { if (++illegal_warned < 20) SAEF_log("cpu.illegal() B-Trap %04X at %08X -> %08X (VBR %08X)", opcode, pc, SAER_Memory_get32(regs.vbr + 0x2c), regs.vbr); coreException(0xB); return false; } if ((opcode & 0xF000) == 0xA000) { if (++illegal_warned < 20) SAEF_log("cpu.illegal() A-Trap %04X at %08X -> %08X (VBR %08X)", opcode, pc, SAER_Memory_get32(regs.vbr + 0x28), regs.vbr); coreException(0xA); return false; } if (++illegal_warned < 20) SAEF_log("cpu.illegal() op %04x, pc %08x -> %08x", opcode, pc, SAER_Memory_get32(regs.vbr + 0x10)); coreException(4); return false; } function coreIllegal(op) { coreSyncPC(); if (illegal(op)) return [4,0,0]; /* no exception */ else return [0,0,0]; } /*-----------------------------------------------------------------------*/ /* core-loop */ function update_cycles() { //update_68k_cycles() cycles_mult = 0; if (SAEV_config.cpu.speed != SAEC_Config_CPU_Speed_Maximum) { //&& !currprefs.cpu_cycle_exact) { if (SAEV_config.cpu.speedThrottle < 0.0) cycles_mult = Math.floor(CYCLES_DIV * 1000 / (1000 + SAEV_config.cpu.speedThrottle)); else if (SAEV_config.cpu.speedThrottle > 0) cycles_mult = Math.floor(CYCLES_DIV * 1000 / (1000 + SAEV_config.cpu.speedThrottle)); } /*if (SAEV_config.cpu.speed == SAEC_Config_CPU_Speed_Original) { //if (SAEV_config.cpu.model >= SAEC_Config_CPU_Model_68040) { if (SAEV_config.cpu.model >= SAEC_Config_CPU_Model_68030) { if (!cycles_mult) cycles_mult = CYCLES_DIV / 8; // == 1024 else cycles_mult = Math.floor(cycles_mult / 8); } else if (SAEV_config.cpu.model >= SAEC_Config_CPU_Model_68020) { if (!cycles_mult) cycles_mult = CYCLES_DIV / 4; // == 2048 else cycles_mult = Math.floor(cycles_mult / 4); } else { //OWN if (!cycles_mult) cycles_mult = CYCLES_DIV / 2; // == 4096 else cycles_mult = Math.floor(cycles_mult / 2); } }*/ cpucycleunit = SAEC_Events_CYCLE_UNIT / 2; if (SAEV_config.cpu.clock.multiplier) { if (SAEV_config.cpu.clock.multiplier >= 256) cpucycleunit = SAEC_Events_CYCLE_UNIT / (SAEV_config.cpu.clock.multiplier >> 8); else cpucycleunit = SAEC_Events_CYCLE_UNIT * SAEV_config.cpu.clock.multiplier; //if (SAEV_config.cpu.model >= SAEC_Config_CPU_Model_68040) cpucycleunit >>= 1; } else if (SAEV_config.cpu.clock.frequency) { var baseclock = (SAEV_config.chipset.ntsc ? SAEC_Playfield_CLOCK_NTSC : SAEC_Playfield_CLOCK_PAL) * 8; //28 MHz cpucycleunit = Math.floor(SAEC_Events_CYCLE_UNIT * baseclock / SAEV_config.cpu.clock.frequency); } /*else if (currprefs.cpu_cycle_exact && SAEV_config.cpu.clock.multiplier == 0) { if (SAEV_config.cpu.model >= 68040) cpucycleunit = SAEC_Events_CYCLE_UNIT / 16; if (SAEV_config.cpu.model == 68030) cpucycleunit = SAEC_Events_CYCLE_UNIT / 8; else if (SAEV_config.cpu.model == 68020) cpucycleunit = SAEC_Events_CYCLE_UNIT / 4; else cpucycleunit = SAEC_Events_CYCLE_UNIT / 2; }*/ if (cpucycleunit < 1) cpucycleunit = 1; SAEF_log("cpu.update_cycles() cycleunit: %d (%.3f), cycles_mult %d", cpucycleunit, cpucycleunit / SAEC_Events_CYCLE_UNIT, cycles_mult); } function adjust_cycles(cycles) { if (cycles_mult == 0 || SAEV_config.cpu.speed == SAEC_Config_CPU_Speed_Maximum) return cycles; /*cycles *= cycles_mult; cycles /= CYCLES_DIV; return cycles;*/ return Math.floor((cycles * cycles_mult) / CYCLES_DIV); } function bus_error() { SAEF_warn("cpu.bus_error() PC %08x", getPC()); try { exception(2); } catch(e) { if (e instanceof Exception23) SAER.m68k.cpu_halt(SAEC_CPU_halt_BUS_ERROR_DOUBLE_FAULT); else throw e; } } function runPrefetch000() { //m68k_run_2p() var exit = false; while (!exit) { try { while (!exit) { regs.instruction_pc = getPC(); regs.opcode = regs.ir; SAER.events.do_cycles(cpu_cycles); //regs.instruction_pc = getPC(); var orw_cycles = iTab[regs.opcode].f(iTab[regs.opcode].p); cpu_cycles = orw_cycles[0] * cpucycleunit; //cpu_cycles = adjust_cycles(orw_cycles[0] * cpucycleunit); SAEV_CPU_cycles = cpu_cycles; if (SAEV_spcflags) { if (SAER.m68k.do_specialties(cpu_cycles)) exit = true; } } } catch(e) { if (e instanceof Exception23) { bus_error(); if (SAEV_spcflags) { if (SAER.m68k.do_specialties(cpu_cycles)) exit = true; } } else throw e; } } } function runPrefetch020() { //m68k_run_2p() var exit = false; while (!exit) { try { while (!exit) { regs.instruction_pc = getPC(); regs.opcode = regs.irc; SAER.events.do_cycles(cpu_cycles); var orw_cycles = iTab[regs.opcode].f(iTab[regs.opcode].p); cpu_cycles = orw_cycles[0] * cpucycleunit; //cpu_cycles = adjust_cycles(orw_cycles[0] * cpucycleunit); SAEV_CPU_cycles = cpu_cycles; if (SAEV_spcflags) { if (SAER.m68k.do_specialties(cpu_cycles)) exit = true; } } } catch(e) { if (e instanceof Exception23) { bus_error(); if (SAEV_spcflags) { if (SAER.m68k.do_specialties(cpu_cycles)) exit = true; } } else throw e; } } } function runNormal() { //m68k_run_2() var exit = false; while (!exit) { try { while (!exit) { regs.instruction_pc = getPC(); //regs.opcode = getInst16_default(0); regs.opcode = nextInst16_default(); SAER.events.do_cycles(cpu_cycles); var orw_cycles = iTab[regs.opcode].f(iTab[regs.opcode].p); cpu_cycles = orw_cycles[0] * cpucycleunit; //cpu_cycles = adjust_cycles(orw_cycles[0] * cpucycleunit); SAEV_CPU_cycles = cpu_cycles; if (SAEV_spcflags) { if (SAER.m68k.do_specialties(cpu_cycles)) exit = true; } } } catch(e) { if (e instanceof Exception23) { bus_error(); if (SAEV_spcflags) { if (SAER.m68k.do_specialties(cpu_cycles)) exit = true; } } else throw e; } } } /*-----------------------------------------------------------------------*/ /* SECT core support functions, ported from WinUAE */ /*-----------------------------------------------------------------------*/ /* MULx/DIVx >= 68020 */ function mul64(src1, src2) { var r0 = (src1 & 0xffff) * (src2 & 0xffff); var r1 = ((src1 >>> 16) & 0xffff) * (src2 & 0xffff); var r2 = (src1 & 0xffff) * ((src2 >>> 16) & 0xffff); var r3 = ((src1 >>> 16) & 0xffff) * ((src2 >>> 16) & 0xffff); var lo = r0 + (((r1 << 16) & 0xffff0000) >>> 0); if (lo > 0xffffffff) lo -= 0x100000000; if (lo < r0) r3++; r0 = lo; lo = r0 + (((r2 << 16) & 0xffff0000) >>> 0); if (lo > 0xffffffff) lo -= 0x100000000; if (lo < r0) r3++; r3 += ((r1 >>> 16) & 0xffff) + ((r2 >>> 16) & 0xffff); if (r3 > 0xffffffff) r3 -= 0x100000000; return [lo, r3]; } function divu64(hi, lo, div) { var i, quo = 0, cbit = false; if (div <= hi) return [1,0,0]; for (i = 0 ; i < 32 ; i++) { cbit = (hi & 0x80000000) != 0; hi = (hi << 1) >>> 0; if (lo & 0x80000000) hi++; lo = (lo << 1) >>> 0; quo = (quo << 1) >>> 0; if (cbit || div <= hi) { quo = (quo | 1) >>> 0; hi -= div; } } return [0, quo, hi]; } /*---------------------------------*/ /* Bitfield >= 68020 */ const ID_BFCHG = 1; /* {offset:width} */ const ID_BFCLR = 2; /* {offset:width} */ const ID_BFEXTS = 3; /* {offset:width},Dn */ const ID_BFEXTU = 4; /* {offset:width},Dn */ const ID_BFFFO = 5; /* {offset:width},Dn */ const ID_BFINS = 6; /* Dn, {offset:width} */ const ID_BFSET = 7; /* {offset:width} */ const ID_BFTST = 8; /* {offset:width} */ function bfName(id) { switch (id) { case ID_BFCHG: return "BFCHG"; case ID_BFCLR: return "BFCLR"; case ID_BFEXTS: return "BFEXTS"; case ID_BFEXTU: return "BFEXTU"; case ID_BFFFO: return "BFFFO"; case ID_BFINS: return "BFINS"; case ID_BFSET: return "BFSET"; case ID_BFTST: return "BFTST"; } } function getBitfield(addr, offset, width) { var tmp, res, mask; var data = [0,0]; offs = offset & 7; mask = (0xffffffff << (32 - width)) >>> 0; switch ((offs + width + 7) >> 3) { case 1: tmp = coreGet8(addr); res = tmp << (24 + offs); data[0] = tmp & ~(mask >>> (24 + offs)); //SAEF_log(("get_bitfield_1 {%d:%d}, data $%08x $%08x, val $%x\n", offset,width, data[0],data[1],res >>> 0)); break; case 2: tmp = coreGet16(addr); res = tmp << (16 + offs); data[0] = tmp & ~(mask >>> (16 + offs)); //SAEF_log(("get_bitfield_2 {%d:%d}, data $%08x $%08x, val $%x\n", offset,width, data[0],data[1],res >>> 0)); break; case 3: tmp = coreGet16(addr); res = tmp << (16 + offs); data[0] = tmp & ~(mask >>> (16 + offs)); tmp = coreGet8(addr + 2); res |= tmp << (8 + offs); data[1] = tmp & ~(mask >>> (8 + offs)); //SAEF_log(("get_bitfield_3 {%d:%d}, data $%08x $%08x, val $%x\n", offset,width, data[0],data[1],res >>> 0)); break; case 4: tmp = coreGet32(addr); res = tmp << offs; data[0] = tmp & ~(mask >>> offs); //SAEF_log(("get_bitfield_4 {%d:%d}, data $%08x $%08x, val $%x\n", offset,width, data[0],data[1],res >>> 0)); break; case 5: tmp = coreGet32(addr); res = tmp << offs; data[0] = tmp & ~(mask >>> offs); tmp = coreGet8(addr + 4); res |= tmp >> (8 - offs); data[1] = tmp & ~(mask << (8 - offs)); //SAEF_log(("get_bitfield_5 {%d:%d}, data $%08x $%08x, val $%x\n", offset,width, data[0],data[1],res >>> 0)); break; default: //SAEF_log(("get_bitfield2() cant happen %d\n", (offs + width + 7) >> 3)); SAEF_fatal(SAEE_CPU_Internal, "cpu.get_bitfield2() invalid mode (%d)", (offs + width + 7) >> 3); } return [res >>> 0, data]; } function putBitfield(addr, offset, width, data, val) { var out8, out16, out32; offs = (offset & 7) + width; switch ((offs + 7) >> 3) { case 1: out8 = ((data[0] | (val << (8 - offs))) >>> 0) & 0xff; corePut8(addr, out8); //data[0] | (val << (8 - offs))); //SAEF_log(("put_bitfield_1 {%d:%d}, data $%08x $%08x, val $%x, out8 $%x\n", offset,width, data[0],data[1],val, out8)); break; case 2: out16 = ((data[0] | (val << (16 - offs))) >>> 0) & 0xffff; corePut16(addr, out16); //data[0] | (val << (16 - offs))); //SAEF_log(("put_bitfield_2 {%d:%d}, data $%08x $%08x, val $%x, out16 $%x\n", offset,width, data[0],data[1],val, out16)); break; case 3: out16 = ((data[0] | (val >> (offs - 16))) >>> 0) & 0xffff; out8 = ((data[1] | (val << (24 - offs))) >>> 0) & 0xff; corePut16(addr, out16); //data[0] | (val >> (offs - 16))); corePut8(addr + 2, out8); //data[1] | (val << (24 - offs))); //SAEF_log(("put_bitfield_3 {%d:%d}, data $%08x $%08x, val $%x, out16 $%x out8 $%x\n", offset,width, data[0],data[1],val, out16,out8)); break; case 4: out32 = (data[0] | (val << (32 - offs))) >>> 0; corePut32(addr, out32); //data[0] | (val << (32 - offs))); //SAEF_log(("put_bitfield_4 {%d:%d}, data $%08x $%08x, val $%x, out32 $%x\n", offset,width, data[0],data[1],val, out32)); break; case 5: out32 = (data[0] | (val >> (offs - 32))) >>> 0; out8 = ((data[1] | (val << (40 - offs))) >>> 0) & 0xff; corePut32(addr, out32); //data[0] | (val >> (offs - 32))); corePut8(addr + 4, out8); //data[1] | (val << (40 - offs))); //SAEF_log(("put_bitfield_5 {%d:%d}, data $%08x $%08x, val $%x, out32 $%x out8 $%x\n", offset,width, data[0],data[1],val, out32,out8)); break; default: //SAEF_log(("put_bitfield() cant happen %d\n", (offs + 7) >> 3)); SAEF_fatal(SAEE_CPU_Internal, "cpu.put_bitfield2() invalid mode (%d)", (offs + 7) >> 3); } } /*---------------------------------*/ /* MOVEC >= 68010 */ function movecRegName(cr) { switch (cr) { //68010/68020/68030/68040 case 0x000: return "SFC"; //Source Function Code case 0x001: return "DFC"; //Destination Function Code case 0x800: return "USP"; //User Stack Pointer case 0x801: return "VBR"; //Vector Base Register //68020/68030/68040 case 0x002: return "CACR"; //Cache Control Register case 0x802: return "CAAR"; //Cache Address Register case 0x803: return "MSP"; //Master Stack Pointer case 0x804: return "ISP"; //Interrupt Stack Pointer //68040/68LC040 case 0x003: return "TC"; //MMU Translation Control Register case 0x004: return "ITT0"; //Instruction Transparent Translation Register 0 case 0x005: return "ITT1"; //Instruction Transparent Translation Register 1 case 0x006: return "DTT0"; //Data Transparent Translation Register 0 case 0x007: return "DTT1"; //Data Transparent Translation Register 1 case 0x805: return "MMUSR"; //MMU Status Register case 0x806: return "URP"; //User Root Pointer case 0x807: return "SRP"; //Supervisor Root Pointer //68EC040 only //case 0x004: return "IACR0"; //Instruction Access Control Register 0 //case 0x005: return "IACR1"; //Instruction Access Control Register 1 //case 0x006: return "DACR1"; //Data Access Control Register 0 //case 0x007: return "DACR1"; //Data Access Control Register 1 } return "???"; } /*function movec_illg(regno) { var regno2 = regno & 0x7ff; if (model == 68010) { if (regno2 < 2) return 0; return 1; } else if (model == 68020) { if (regno == 3) return 1; //68040/060 only if (regno2 < 4 || regno == 0x804) //4 is >=68040, but 0x804 is in 68020 return 0; return 1; } else if (model == 68030) { if (regno2 <= 2) return 0; if (regno == 0x803 || regno == 0x804) return 0; return 1; } else if (model == 68040) { if (regno == 0x802) return 1; //68020/030 only if (regno2 < 8) return 0; return 1; } else if (model == 68060) { if (regno <= 8) return 0; if (regno == 0x800 || regno == 0x801 || regno == 0x806 || regno == 0x807 || regno == 0x808) return 0; return 1; } return 1; }*/ function movecValid(r) { switch (r) { //MC68010/MC68020/MC68030/MC68040 case 0x000: return model >= 68010; //Source Function Code (SFC) case 0x001: return model >= 68010; //Destination Function Code (DFC) case 0x800: return model >= 68010; //User Stack Pointer (USP) case 0x801: return model >= 68010; //Vector Base Register (VBR) //MC68020/MC68030/MC68040 case 0x002: return model >= 68020; //Cache Control Register (CACR) case 0x802: return model == 68020 || model == 68030; //Cache Address Register (CAAR) !MC68040 case 0x803: return model >= 68020; //Master Stack Pointer (MSP) case 0x804: return model >= 68020; //Interrupt Stack Pointer (ISP) //MC68040/MC68LC040 /*case 0x003: return model >= 68040; //MMU Translation Control Register (TC) case 0x004: return model >= 68040; //Instruction Transparent Translation Register 0 (ITT0) case 0x005: return model >= 68040; //Instruction Transparent Translation Register 1 (ITT1) case 0x006: return model >= 68040; //Data Transparent Translation Register 0 (DTT0) case 0x007: return model >= 68040; //Data Transparent Translation Register 1 (DTT1) case 0x805: return model >= 68040; //MMU Status Register (MMUSR) case 0x806: return model >= 68040; //User Root Pointer (URP) case 0x807: return model >= 68040; //Supervisor Root Pointer (SRP) //MC68EC040 only case 0x004: return model >= 68040; //Instruction Access Control Register 0 (IACR0) case 0x005: return model >= 68040; //Instruction Access Control Register 1 (IACR1) case 0x006: return model >= 68040; //Data Access Control Register 0 (DACR1) case 0x007: return model >= 68040; //Data Access Control Register 1 (DACR1) */ } return false; } function movec2C(cr, data) { switch (cr) { case 0: regs.sfc = data & 7; break; case 1: regs.dfc = data & 7; break; case 2: { switch (model) { case 68020: regs.cacr = data & CACR020_WMASK; break; case 68030: regs.cacr = data & CACR030_WMASK; break; //case 68040: regs.cacr = (data & 0x80008000) >>> 0; break; //case 68060: regs.cacr = (data & 0xf8e0e000) >>> 0; break; default: regs.cacr = 0; } coreSetCaches(false); break; } /*case 3: { regs.tcr = data & (model == 68060 ? 0xfffe : 0xc000); if (currprefs.mmu_model) mmu_set_tc(regs.tcr); break; } case 4: regs.itt0 = data & 0xffffe364; mmu_tt_modified(); break; case 5: regs.itt1 = data & 0xffffe364; mmu_tt_modified(); break; case 6: regs.dtt0 = data & 0xffffe364; mmu_tt_modified(); break; case 7: regs.dtt1 = data & 0xffffe364; mmu_tt_modified(); break; case 8: regs.buscr = data & 0xf0000000; break;*/ case 0x800: regs.usp = data; break; case 0x801: regs.vbr = data; break; case 0x802: regs.caar = data; break; case 0x803: regs.msp = data; if ( regs.m) regs.a[7] = regs.msp; break; case 0x804: regs.isp = data; if (!regs.m) regs.a[7] = regs.isp; break; /*case 0x805: regs.mmusr = data; break; case 0x806: regs.urp = data & 0xfffffe00; break; case 0x807: regs.srp = data & 0xfffffe00; break; case 0x808: { var opcr = regs.pcr; regs.pcr &= ~(0x40 | 2 | 1); regs.pcr |= data & (0x40 | 2 | 1); if (currprefs.fpu_model <= 0) regs.pcr |= 2; if (((opcr ^ regs.pcr) & 2) == 2) { SAEF_log("68060 FPU state: %s", regs.pcr & 2 ? "disabled" : "enabled"); //flush possible already translated FPU instructions flush_icache(0, 3); } break; }*/ default: SAEF_fatal(SAEE_CPU_Internal, "cpu.movec2C() invalid register %d", cr); } } function movecC2(cr) { var data = null; switch (cr) { case 0: data = regs.sfc; break; case 1: data = regs.dfc; break; case 2: { switch (model) { case 68020: data = regs.cacr & CACR020_RMASK; break; case 68030: data = regs.cacr & CACR030_RMASK; break; //case 68040: data = (regs.cacr & 0x80008000) >>> 0; break; //case 68060: data = (regs.cacr & 0xf880e000) >>> 0; break; default: data = 0; } break; } //case 3: data = regs.tcr; break; //case 4: data = regs.itt0; break; //case 5: data = regs.itt1; break; //case 6: data = regs.dtt0; break; //case 7: data = regs.dtt1; break; //case 8: data = regs.buscr; break; case 0x800: data = regs.usp; break; case 0x801: data = regs.vbr; break; case 0x802: data = regs.caar; break; case 0x803: data = regs.m == 1 ? regs.a[7] : regs.msp; break; case 0x804: data = regs.m == 0 ? regs.a[7] : regs.isp; break; //case 0x805: data = regs.mmusr; break; //case 0x806: data = regs.urp; break; //case 0x807: data = regs.srp; break; //case 0x808: data = regs.pcr; break; default: SAEF_fatal(SAEE_CPU_Internal, "cpu.movecC2() invalid register %d", cr); } return data; } /*---------------------------------*/ /* 68030 fake MMU */ const MMUOP_DEBUG = false; function mmu_op30fake_pmove(pc, op, ext, addr) { var preg = (ext >> 10) & 31; var rw = (ext >> 9) & 1; var fd = (ext >> 8) & 1; var reg = null; var otc = fake_tc_030; var siz; switch (preg) { case 0x10: reg = "TC"; siz = 4; if (rw) corePut32(addr, fake_tc_030); else fake_tc_030 = coreGet32(addr); break; case 0x12: reg = "SRP"; siz = 8; if (rw) { //corePut32(addr, fake_srp_030 >> 32); //corePut32(addr + 4, (uae_u32)fake_srp_030); corePut32(addr, fake_srp_030_hi); corePut32(addr + 4, fake_srp_030_lo); } else { //fake_srp_030 = (uae_u64)coreGet32(addr) << 32; //fake_srp_030 |= coreGet32(addr + 4); fake_srp_030_hi = coreGet32(addr); fake_srp_030_lo = coreGet32(addr + 4); } break; case 0x13: reg = "CRP"; siz = 8; if (rw) { //corePut32(addr, fake_crp_030 >> 32); //corePut32(addr + 4, (uae_u32)fake_crp_030); corePut32(addr, fake_crp_030_hi); corePut32(addr + 4, fake_crp_030_lo); } else { //fake_crp_030 = (uae_u64)coreGet32(addr) << 32; //fake_crp_030 |= coreGet32(addr + 4); fake_crp_030_hi = coreGet32(addr); fake_crp_030_lo = coreGet32(addr + 4); } break; case 0x18: reg = "MMUSR"; siz = 2; if (rw) corePut16(addr, fake_mmusr_030); else fake_mmusr_030 = coreGet16(addr); break; case 0x02: reg = "TT0"; siz = 4; if (rw) corePut32(addr, fake_tt0_030); else fake_tt0_030 = coreGet32(addr); break; case 0x03: reg = "TT1"; siz = 4; if (rw) corePut32(addr, fake_tt1_030); else fake_tt1_030 = coreGet32(addr); break; } if (reg === null) return true; if (MMUOP_DEBUG) { if (siz == 8) { var val2 = coreGet32(addr); var val = coreGet32(addr + 4); if (rw) SAEF_log("I_MMU_PMOVE %s,%08X%08X PC=%08X", reg, val2, val, pc); else SAEF_log("I_MMU_PMOVE %08X%08X,%s PC=%08X", val2, val, reg, pc); } else { if (siz == 4) var val = coreGet32(addr); else var val = coreGet16(addr); if (rw) SAEF_log("I_MMU_PMOVE %s,%08X PC=%08X", reg, val, pc); else SAEF_log("I_MMU_PMOVE %08X,%s PC=%08X", val, reg, pc); } } if ((SAEV_config.chipset.mbdmac & 1) && SAEV_config.memory.ramsey.lowSize > 0) { if (otc != fake_tc_030) SAER.memory.a3000_fakekick((fake_tc_030 & 0x80000000) != 0); } return false; } function mmu_op30fake_ptest(pc, op, ext, addr) { if (MMUOP_DEBUG) { var tmp = ""; if ((ext >> 8) & 1) tmp = sprintf(",A%d", (ext >> 4) & 15); SAEF_log("I_MMU_PTEST%c %02X,%08X,#%X%s PC=%08X", ((ext >> 9) & 1) ? 'W' : 'R', (ext & 15), addr, (ext >> 10) & 7, tmp, pc); } fake_mmusr_030 = 0; return false; } function mmu_op30fake_pflush(pc, op, ext, addr) { var flushmode = (ext >> 10) & 7; var fc = ext & 31; var mask = (ext >> 5) & 3; var fname = ""; switch (flushmode) { case 6: fname = sprintf("FC=%x MASK=%x EA=%08x", fc, mask, 0); break; case 4: fname = sprintf("FC=%x MASK=%x", fc, mask); break; case 1: fname = "ALL"; break; default: return true; } if (MMUOP_DEBUG) SAEF_log("I_MMU_PFLUSH %s PC=%08X", fname, pc); return false; } function mmu_op30(pc, opcode, ext, addr) { /*if (currprefs.mmu_model) { if (ext & 0x8000) return mmu_op30_ptest(pc, opcode, ext, addr); else if ((ext & 0xE000) == 0x2000 && (ext & 0x1C00)) return mmu_op30_pflush(pc, opcode, ext, addr); else if ((ext & 0xE000) == 0x2000 && !(ext & 0x1C00)) return mmu_op30_pload(pc, opcode, ext, addr); else return mmu_op30_pmove(pc, opcode, ext, addr); }*/ var type = ext >> 13; switch (type) { case 0: case 2: case 3: return mmu_op30fake_pmove(pc, opcode, ext, addr); case 1: return mmu_op30fake_pflush(pc, opcode, ext, addr); case 4: return mmu_op30fake_ptest(pc, opcode, ext, addr); default: return true; } } /*-----------------------------------------------------------------------*/ /* SECT dissassembling */ /*-----------------------------------------------------------------------*/ const D_RDD = 1; const D_RDA = 2; const D_RIPR = 3; const D_RIPO = 4; const D_RID = 5; const D_IMD = 6; const D_IME = 7; const D_IME_DP = 8; const D_EA = 10; const D_CCR = 11; const D_SR = 12; const D_USP = 13; const D_EXT_BITFIELD = 20; const D_EXT_MOVEM = 21; const D_EXT_MOVEC = 22; const D_EXT_MUL64 = 23; const D_EXT_DIV64 = 24; const D_EXT_MMU = 25; function regs_da_def() { this.memory = null; this.pc = 0; this.io = 0; this.fmt8 = "%x"; this.fmt16 = "%x"; this.fmt32 = "%x"; } var regs_da = new regs_da_def(); var inst_mn = null; function config_da_def() { this.code = ""; this.offset = 0; this.limit = 32; this.radix = 16; this.prefx = "$"; this.width = 0; this.reloc = true; } config_da = new config_da_def(); function setPC_da(pc) { regs_da.pc = pc; regs_da.io = 0; } function getPC_da() { return regs_da.pc + regs_da.io; } function incPC_da(o) { regs_da.io += o; } function syncPC_da() { regs_da.pc += regs_da.io; regs_da.io = 0; } function get16_da(addr) { return (regs_da.memory[addr] << 8) | regs_da.memory[addr+1]; } function get32_da(addr) { return ((regs_da.memory[addr] << 24) | (regs_da.memory[addr+1] << 16) | (regs_da.memory[addr+2] << 8) | regs_da.memory[addr+3]) >>> 0; } function next16_da() { var r = get16_da(regs_da.pc + regs_da.io); incPC_da(2); return r; } function next32_da() { var r = get32_da(regs_da.pc + regs_da.io); incPC_da(4); return r; } function szChr(z) { switch (z) { case 0: return "s"; case 1: return "b"; case 2: return "w"; case 4: return "l"; //default: SAEF_fatal(SAEE_CPU_Internal, "cpu.szChr() invalid size (%d)", z); default: return "?"; } } function printMovec(ext, dir) { var o; var xn = (ext >> 12) & 7; var reg = movecRegName(ext & 0xfff); reg = reg.toLowerCase(); if (dir) { if (ext & 0x8000) o = reg+",a"+xn; else o = reg+",d"+xn; } else { if (ext & 0x8000) o = "a"+xn+","+reg; else o = "d"+xn+","+reg; } return o; } function printMovem(ext, inv) { var d = [0,0,0,0,0,0,0,0]; var a = [0,0,0,0,0,0,0,0]; var i, o = ""; for (i = 0; i < 16; i++) { if (ext & (1 << (inv ? 15-i : i))) { if (i < 8) d[i] = 1; else a[i - 8] = 1; } } var fi = d.indexOf(1); var li = d.lastIndexOf(1); if (fi != -1) { o += "d"+fi; if (li != fi) o += "-d"+li; } fi = a.indexOf(1); li = a.lastIndexOf(1); if (fi != -1) { if (o.length) o += "/"; o += "a"+fi; if (li != fi) o += "-a"+li; } return o; } function printMul64(ext) { var Dl = (ext >> 12) & 7; var Dh = ext & 7; inst_mn = (ext & 0x800) ? "muls" : "mulu"; return (ext & 0x400) ? "d"+Dh+"-d"+Dl : "d"+Dl; } function printDiv64(ext) { var Dq = (ext >> 12) & 7; var Dr = ext & 7; inst_mn = (ext & 0x800) ? "divs" : "divu"; return (ext & 0x400) ? "d"+Dr+":d"+Dq : "d"+Dq; } function printMMU(ext) { return "FIXME"; //FIX not implemented } function printII(base, dp, ar) { var o = ""; var reg = (dp >> 12) & 7; var cycles = 0; var v; var regd = (dp & 0x8000) ? regs.a[reg] : regs.d[reg]; var scale = (dp >> 9) & 3; if ((dp & 0x800) == 0) regd = extWord(regd & 0xffff); if (scale) regd = ((regd << scale) & 0xffffffff) >>> 0; if (dp & 0x100) { var outer = 0; if (dp & 0x80) base = 0; if (dp & 0x40) regd = 0; if ((dp & 0x30) == 0x20) { base = add32(base, extWord(next16_da())); cycles++; } if ((dp & 0x30) == 0x30) { base = add32(base, next32_da()); cycles++; } if ((dp & 0x3) == 0x2) { outer = extWord(next16_da()); cycles++; } if ((dp & 0x3) == 0x3) { outer = next32_da(); cycles++; } if ((dp & 0x4) == 0) { base = add32(base, regd); cycles++; } if (dp & 0x3) { base = get32_da(base); cycles++; } if (dp & 0x4) { base = add32(base, regd); cycles++; } v = add32(base, outer); } else v = add32(add32(base, extByte(dp & 0xff)), regd); /*if (ar != -1) o += sprintf("(%d,A%d,%s%d.%s*%d)[$%08x]", castByte(dp & 0xff), ar, (dp & 0x8000)?"A":"D",reg, (dp & 0x800)?"L":"W", 1 << scale, v); else o += sprintf("(%d,PC,%s%d.%s*%d)[$%08x]", castByte(dp & 0xff), (dp & 0x8000)?"A":"D",reg, (dp & 0x800)?"L":"W", 1 << scale, v); */ if (ar != -1) o += sprintf("(%d,a%d,%s%d.%s*%d)", castByte(dp & 0xff), ar, (dp & 0x8000)?"a":"d",reg, (dp & 0x800)?"l":"w", 1 << scale); else o += sprintf("(%d,pc,%s%d.%s*%d)", castByte(dp & 0xff), (dp & 0x8000)?"a":"d",reg, (dp & 0x800)?"l":"w", 1 << scale); return o; } function printEA(ea, z) { var m = ea >> 3; if (m == 7) { switch (ea & 7) { case 0: { //absw var dp = next16_da(); return sprintf(config_da.radix == 10 ? "(%d)" : "("+regs_da.fmt16+")", dp); } case 1: { //absl var dp = next32_da(); return sprintf(config_da.radix == 10 ? "(%d)" : "("+regs_da.fmt32+")", dp); } case 2: { //pcid var pc = getPC_da(); var dp = extWord(next16_da()); if (config_da.reloc) return sprintf(regs_da.fmt32, add32(pc, dp)); else return sprintf(config_da.radix == 10 ? "%d(pc)" : regs_da.fmt32+"(pc)", castLong(dp)); } case 3: { //pcii var pc = getPC_da(); var dp = next16_da(); return printII(pc, dp, -1); } case 4: { //imm var dp = 0; switch (z) { case 1: dp = next16_da() & 0xff; return sprintf(config_da.radix == 10 ? "#%d" : "#"+regs_da.fmt8, castByte(dp)); case 2: dp = next16_da(); return sprintf(config_da.radix == 10 ? "#%d" : "#"+regs_da.fmt16, castWord(dp)); case 4: dp = next32_da(); return sprintf(config_da.radix == 10 ? "#%d" : "#"+regs_da.fmt32, castLong(dp)); } } } } else { var r = ea & 7; switch (m) { case 0: return sprintf("d%d", r); //rdd case 1: return sprintf("a%d", r); //rda case 2: return sprintf("(a%d)", r); //ria case 3: return sprintf("(a%d)+", r); //ripo case 4: return sprintf("-(a%d)", r); //ripr case 5: { //rid var dp = extWord(next16_da()); //return sprintf(config_da.radix == 10 ? "%d(A%d)[$%08x]" : "$%08x(A%d)[$%08x]", castLong(dp), r, add32(regs.a[r], dp)); return sprintf(config_da.radix == 10 ? "%d(a%d)" : regs_da.fmt32+"(a%d)", dp, r); } case 6: { //rii var dp = next16_da(); return printII(regs.a[r], dp, r); } } } return "???"; } function printI2(ext, mode, value, z) { switch (mode) { case D_RDD: return sprintf("d%d", value); case D_RDA: return sprintf("a%d", value); case D_RIPR: return sprintf("-(a%d)", value); case D_RIPO: return sprintf("(a%d)+", value); case D_RID: { var dp = castLong(extWord(next16_da())); //return sprintf("%d(A%d)[$%08x]", dp, value, regs.a[value] + dp); return sprintf("%d(A%d)", dp, value); } case D_IMD: return sprintf(config_da.radix == 10 ? "#%d" : "#"+regs_da.fmt8, value); case D_IME: { var imm = value == 1 ? next16_da() : next32_da(); return sprintf(config_da.radix == 10 ? "#%d" : (value == 1 ? "#"+regs_da.fmt16 : "#"+regs_da.fmt32), imm); } case D_IME_DP: { var pc = getPC_da(); if (value == 0) dp = castLong(extWord(next16_da())); else if (value == 255) dp = castLong(next32_da()); else dp = castLong(extByte(value)); if (config_da.reloc) return sprintf("<"+regs_da.fmt32+">", pc + dp); else return sprintf("<%d>", dp); } case D_EA: return printEA(value, z); case D_CCR: return "ccr"; case D_SR: return "sr"; case D_USP: return "usp"; case D_EXT_BITFIELD: { var offset = (ext & 0x800) ? regs.d[(ext >> 6) & 7] : (ext >> 6) & 0x1f; var width = (ext & 0x20) ? regs.d[ext & 7] & 0x1f : ext & 0x1f; if (width == 0) width = 32; return sprintf("{%d:%d}", offset, width); } case D_EXT_MOVEM: return printMovem(ext, value); case D_EXT_MOVEC: return printMovec(ext, value); case D_EXT_MUL64: return printMul64(ext); case D_EXT_DIV64: return printDiv64(ext); case D_EXT_MMU: return printMMU(ext); } } function printI(i) { var mn = i.mn; mn = mn.toLowerCase(); if (mn == "illegal") return mn; inst_mn = null; var o = ""; if (i.d) { var ext = i.d.ext == 0 ? false : (i.d.ext == 1 ? next16_da() : next32_da()); if (i.d.z) o += "." + szChr(i.d.z); else if (1 && i.d.z2) o += "." + szChr(i.d.z2); if (i.d.sm && i.d.dm) { o += " "; o += printI2(ext, i.d.sm, i.d.s, i.d.z); o += ","; o += printI2(ext, i.d.dm, i.d.d, i.d.z); } else if (i.d.dm) { o += " "; o += printI2(ext, i.d.dm, i.d.d, i.d.z); } } if (inst_mn !== null) return inst_mn + o; else return mn + o; } this.getConfig_da = function() { return config_da; } this.setup_da = function(m) { model = m; if (!mkITab()) return SAEE_CPU_Internal; mkCCTab(); mkEATabs(); return SAEE_None; } function fixup_da() { if (config_da.code.length > 0) { regs_da.memory = new Uint8Array(config_da.code.length); regs_da.memory.set(SAEF_String2Array(config_da.code, 0, config_da.code.length)); config_da.code = ""; } if (regs_da.memory === null) throw 1; if (getPC_da() >= regs_da.memory.length) regs_da.pc = regs_da.io = 0x0; if (config_da.limit <= 0) config_da.limit = 8; regs_da.fmt8 = regs_da.fmt16 = regs_da.fmt32 = config_da.prefx; if (config_da.width == 0) { regs_da.fmt8 += "%x"; regs_da.fmt16 += "%x"; regs_da.fmt32 += "%x"; } else { regs_da.fmt8 += "%02x"; regs_da.fmt16 += "%04x"; regs_da.fmt32 += config_da.width == 24 ? "%06x" : "%08x"; } } this.disassemble = function() { fixup_da(); setPC_da(config_da.offset); var op, addr, code, words, inst; var out = []; var cnt = 0; while (cnt++ < config_da.limit) { addr = regs_da.pc; code = []; for (var i = 0; i < 5; i++) code.push(get16_da(addr + i * 2)); op = next16_da(); inst = printI(iTab[op]); words = regs_da.io >> 1; out.push([addr, code, words, inst]); syncPC_da(); } return out; } this.diss = function(addr, limit) { if (typeof addr == "undefined") addr = coreGetPC(); if (typeof limit == "undefined" || limit == 0) limit = 8; var bank = SAER_Memory_getBank(addr); regs_da.memory = bank.baseaddr; setPC_da(addr - bank.start); var cnt = 0; while (cnt++ < limit) { var o = ""; if (1) { o += sprintf("$%08x: ", regs_da.pc + bank.start); for (var i = 0; i < 5; i++) o += sprintf("$%04x ", get16_da(regs_da.pc + i * 2)); } var op = next16_da(); o += printI(iTab[op]); o += sprintf(" (%d)", regs_da.io >> 1); SAEF_log(o); syncPC_da(); } }; /*-----------------------------------------------------------------------*/ /* SECT instruction core. Implementation based on M68000PRM.pdf */ /*-----------------------------------------------------------------------*/ function stackPut16(v) { regs.a[7] -= 2; /* pre-decrement */ corePut16(regs.a[7], v); } function stackPut32(v) { regs.a[7] -= 4; /* pre-decrement */ corePut32(regs.a[7], v); } function stackGet16() { var v = coreGet16(regs.a[7]); regs.a[7] += 2; /* post-increment */ return v; } function stackGet32() { var v = coreGet32(regs.a[7]); regs.a[7] += 4; /* post-increment */ return v; } /*-----------------------------------------------------------------------*/ const aIncDec = [ [], [1,1,1,1,1,1,1,2], [2,2,2,2,2,2,2,2], [], [4,4,4,4,4,4,4,4] ]; function castByte(v) { return (v & 0x80) ? (v - 0x100) : v; } function castWord(v) { return (v & 0x8000) ? (v - 0x10000) : v; } function castLong(v) { return (v & 0x80000000) ? (v - 0x100000000) : v; } function extByteToWord(v) { return (v & 0x80) ? (0xff00 | v) : v; } function extByte(v) { return (v & 0x80) ? ((0xffffff00 | v) >>> 0) : v; } function extWord(v) { return (v & 0x8000) ? ((0xffff0000 | v) >>> 0) : v; } function add32(a, b) { var r = a + b; return r > 0xffffffff ? r - 0x100000000 : r; } function sub32(a, b) { var r = a - b; return r < 0 ? r + 0x100000000 : r; } /*-----------------------------------------------------------------------*/ /* Condition codes */ function flgAdd(S, D, R, m, isADDX) { /* ADD, ADDI, ADDQ, ADDX */ var Sn = (S & m) != 0; var Dn = (D & m) != 0; var Rn = (R & m) != 0; regs.v = (Sn && Dn && !Rn) || (!Sn && !Dn && Rn); regs.c = (Sn && Dn) || (!Rn && Dn) || (Sn && !Rn); regs.x = regs.c; regs.n = Rn; if (isADDX) { if (R != 0) regs.z = false; } else regs.z = R == 0; } function flgSub(S, D, R, m, isSUBX) { /* SUB, SUBI, SUBQ, SUBX */ var Sn = (S & m) != 0; var Dn = (D & m) != 0; var Rn = (R & m) != 0; regs.v = (!Sn && Dn && !Rn) || (Sn && !Dn && Rn); regs.c = (Sn && !Dn) || (Rn && !Dn) || (Sn && Rn); regs.x = regs.c; regs.n = Rn; if (isSUBX) { if (R != 0) regs.z = false; } else regs.z = R == 0; } function flgCmp(S, D, R, m) { /* CAS, CAS2, CMP, CMPA, CMPI, CMPM */ var Sn = (S & m) != 0; var Dn = (D & m) != 0; var Rn = (R & m) != 0; regs.v = (!Sn && Dn && !Rn) || (Sn && !Dn && Rn); regs.c = (Sn && !Dn) || (Rn && !Dn) || (Sn && Rn); regs.n = Rn; regs.z = R == 0; } function flgNeg(D, R, m, isNEGX) { /* NEG, NEGX */ var Dn = (D & m) != 0; var Rn = (R & m) != 0; regs.v = Dn && Rn; regs.c = Dn || Rn; regs.x = regs.c; regs.n = Rn; if (isNEGX) { if (R != 0) regs.z = false; } else regs.z = R == 0; } function flgLogical(R, m) { /* AND ANDI OR ORI EOR EORI MOVE MOVEQ EXT NOT TST */ regs.n = (R & m) != 0; regs.z = R == 0; regs.v = regs.c = false; } /*-----------------------------------------------------------------------*/ /* Instructions ---------------------------------------------------------*/ /*-----------------------------------------------------------------------*/ /* Data Movement */ function I_EXG_DD(p) { var t = regs.d[p.Rx]; regs.d[p.Rx] = regs.d[p.Ry]; regs.d[p.Ry] = t; //ccna coreSyncPC(); return p.cyc; } function I_EXG_AA(p) { var t = regs.a[p.Rx]; regs.a[p.Rx] = regs.a[p.Ry]; regs.a[p.Ry] = t; //ccna coreSyncPC(); return p.cyc; } function I_EXG_DA(p) { var t = regs.d[p.Rx]; regs.d[p.Rx] = regs.a[p.Ry]; regs.a[p.Ry] = t; //ccna coreSyncPC(); return p.cyc; } function I_LEA(p) { regs.a[p.An] = exEAtab[p.ea](4); //SAEF_log("I_LEA.L $%08x %d/%d", regs.a[p.An], p.ea>>3,p.ea&7); //ccna coreSyncPC(); return p.cyc; } function I_PEA(p) { var a = exEAtab[p.ea](4); stackPut32(a); //SAEF_log(("I_PEA.L $%08x", a)); //ccna coreSyncPC(); return p.cyc; } function I_LINK(p) { var dp = extWord(coreNext16()); stackPut32(regs.a[p.An]); regs.a[p.An] = regs.a[7]; regs.a[7] = add32(regs.a[7], dp); //SAEF_log(("I_LINK.W A%d, dp $%04x", p.An, dp)); //ccna coreSyncPC(); return p.cyc; } function I_LINK_32(p) { /* >= 68020 */ var dp = coreNext32(); stackPut32(regs.a[p.An]); regs.a[p.An] = regs.a[7]; regs.a[7] = add32(regs.a[7], dp); //SAEF_log(("I_LINK.L A%d, dp $%04x", p.An, dp)); //ccna coreSyncPC(); return p.cyc; } function I_UNLK(p) { regs.a[7] = regs.a[p.An]; regs.a[p.An] = stackGet32(); //SAEF_log(("I_UNLK A%d", p.An)); //ccna coreSyncPC(); return p.cyc; } function I_MOVE_8(p) { var s = ldEA8tab[p.sea](); stEA8tab[p.dea](s); flgLogical(s, p.zm); //SAEF_log(("I_MOVE.B $%08x", s)); coreSyncPC(); return p.cyc; } function I_MOVE_16(p) { var s = ldEA16tab[p.sea](); stEA16tab[p.dea](s); flgLogical(s, p.zm); //SAEF_log(("I_MOVE.W $%08x", s)); coreSyncPC(); return p.cyc; } function I_MOVE_32(p) { var s = ldEA32tab[p.sea](); stEA32tab[p.dea](s); flgLogical(s, p.zm); //SAEF_log(("I_MOVE.L $%08x", s)); coreSyncPC(); return p.cyc; } function I_MOVEA_16(p) { var s = ldEA16tab[p.ea](); regs.a[p.An] = extWord(s); //SAEF_log(("I_MOVEA.W $%08x A%d", extWord(s), p.An)); //ccna coreSyncPC(); return p.cyc; } function I_MOVEA_32(p) { var s = ldEA32tab[p.ea](); regs.a[p.An] = s; //SAEF_log(("I_MOVEA.L $%08x A%d", s, p.An)); //ccna coreSyncPC(); return p.cyc; } function I_MOVEQ(p) { var s = extByte(p.data); regs.d[p.Dn] = s; flgLogical(s, p.zm); //SAEF_log(("I_MOVEQ.L $%08x,D%d", s, p.Dn)); coreSyncPC(); return p.cyc; } function I_MOVEM_R2M_16(p) { var list = coreNext16(); var ripr = p.ea >> 3 == 4; var Xn, An = p.ea & 7; var a = exEAtab[ripr ? (2<<3|An) : p.ea](2); var pre, inv = ripr ? 15 : 0; var n = 0; if (ripr) { /* pre-decrement */ pre = 0; for (Xn = 0; Xn < 16; Xn++) { if (list & (1 << Xn)) pre += 2; } a -= pre; /* p. 4-128: The MC68000 and MC68010 write the initial register value (not decremented). */ if (model >= 68020) regs.a[An] -= pre; } for (Xn = 0; Xn < 16; Xn++) { if (list & (1 << (Xn ^ inv))) { if (Xn < 8) corePut16(a, regs.d[Xn] & 0xffff); else corePut16(a, regs.a[Xn & 7] & 0xffff); a += 2; n++; } } if (ripr && model < 68020) regs.a[An] -= pre; //ccna coreSyncPC(); return [p.cyc[0]+4*n,p.cyc[1],n]; } function I_MOVEM_R2M_32(p) { var list = coreNext16(); var ripr = p.ea >> 3 == 4; var Xn, An = p.ea & 7; var a = exEAtab[ripr ? (2<<3|An) : p.ea](4); var pre, inv = ripr ? 15 : 0; var n = 0; if (ripr) { /* pre-decrement */ pre = 0; for (Xn = 0; Xn < 16; Xn++) { if (list & (1 << Xn)) pre += 4; } a -= pre; /* p. 4-128: The MC68000 and MC68010 write the initial register value (not decremented). */ if (model >= 68020) regs.a[An] -= pre; } for (Xn = 0; Xn < 16; Xn++) { if (list & (1 << (Xn ^ inv))) { if (Xn < 8) corePut32(a, regs.d[Xn]); else corePut32(a, regs.a[Xn & 7]); a += 4; n++; } } if (ripr && model < 68020) regs.a[An] -= pre; //ccna coreSyncPC(); return [p.cyc[0]+8*n,p.cyc[1],2*n]; } function I_MOVEM_M2R_16(p) { var list = coreNext16(); var ripo = p.ea >> 3 == 3; var An = p.ea & 7; var a = exEAtab[ripo ? (2<<3|An) : p.ea](2); var n = 0; for (var Xn = 0; Xn < 16; Xn++) { if (list & (1 << Xn)) { if (Xn < 8) regs.d[Xn] = extWord(coreGet16(a)); else regs.a[Xn & 7] = extWord(coreGet16(a)); a += 2; n++; } } if (ripo) regs.a[An] = a; /* post-increment */ //ccna coreSyncPC(); return [p.cyc[0]+4*n,p.cyc[1]+n,0]; } function I_MOVEM_M2R_32(p) { var list = coreNext16(); var ripo = p.ea >> 3 == 3; var An = p.ea & 7; var a = exEAtab[ripo ? (2<<3|An) : p.ea](4); var n = 0; for (var Xn = 0; Xn < 16; Xn++) { if (list & (1 << Xn)) { if (Xn < 8) regs.d[Xn] = coreGet32(a); else regs.a[Xn & 7] = coreGet32(a); a += 4; n++; } } if (ripo) regs.a[An] = a; /* post-increment */ //ccna coreSyncPC(); return [p.cyc[0]+8*n,p.cyc[1]+2*n,0]; } function I_MOVEP_R2M_16(p) { var dp = coreNext16(); var s = regs.d[p.Dn] & 0xffff; var a = add32(regs.a[p.An], extWord(dp)); //SAEF_log("I_MOVEP_R2M_16 D%d A%d addr $%08x <- $%04x", p.Dn, p.An, a, s); corePut8(a, s >> 8); corePut8(a+2, s & 0xff); //ccna coreSyncPC(); return p.cyc; } function I_MOVEP_R2M_32(p) { var dp = coreNext16(); var s = regs.d[p.Dn]; var a = add32(regs.a[p.An], extWord(dp)); //SAEF_log("I_MOVEP_R2M_32 D%d A%d addr $%08x <- $%08x", p.Dn, p.An, a, s); corePut8(a, s >>> 24); corePut8(a+2, (s >>> 16) & 0xff); corePut8(a+4, (s >>> 8) & 0xff); corePut8(a+6, s & 0xff); //ccna coreSyncPC(); return p.cyc; } function I_MOVEP_M2R_16(p) { var dp = coreNext16(); var a = add32(regs.a[p.An], extWord(dp)); var d = (coreGet8(a) << 8) | corePut8(a+2); //SAEF_log("I_MOVEP_M2R_16 A%d D%d addr $%08x -> $%04x", p.An, p.Dn, a, d); regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | d; //ccna coreSyncPC(); return p.cyc; } function I_MOVEP_M2R_32(p) { var dp = coreNext16(); var a = add32(regs.a[p.An], extWord(dp)); var d = ((coreGet8(a) << 24) | (coreGet8(a+2) << 16) | (coreGet8(a+4) << 8) | corePut8(a+6)) >>> 0; //SAEF_log("I_MOVEP_M2R_32 A%d D%d addr $%08x -> $%08x", p.An, p.Dn, a, d); regs.d[p.Dn] = d; //ccna coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* Integer Arithmetic - Basic */ function I_ADD_ED_32(p) { var s = ldEA32tab[p.ea](); var d = regs.d[p.Dn]; var r = s + d; if (r > 0xffffffff) r -= 0x100000000; regs.d[p.Dn] = r; flgAdd(s, d, r, 0x80000000, false); //SAEF_log(("I_ADD_ED.L %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADD_DE_32(p) { var a = exEAtab[p.ea](4); var s = regs.d[p.Dn]; var d = coreGet32(a); var r = s + d; if (r > 0xffffffff) r -= 0x100000000; corePut32(a, r); flgAdd(s, d, r, 0x80000000, false); //SAEF_log(("I_ADD_DE.L %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADD_ED_16(p) { var s = ldEA16tab[p.ea](); var d = regs.d[p.Dn] & 0xffff; var r = s + d; if (r > 0xffff) r -= 0x10000; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; flgAdd(s, d, r, 0x8000, false); //SAEF_log(("I_ADD_ED.W %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADD_DE_16(p) { var a = exEAtab[p.ea](2); var s = regs.d[p.Dn] & 0xffff; var d = coreGet16(a); var r = s + d; if (r > 0xffff) r -= 0x10000; corePut16(a, r); flgAdd(s, d, r, 0x8000, false); //SAEF_log(("I_ADD_DE.W %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADD_ED_8(p) { var s = ldEA8tab[p.ea](); var d = regs.d[p.Dn] & 0xff; var r = s + d; if (r > 0xff) r -= 0x100; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffffff00) | r; flgAdd(s, d, r, 0x80, false); //SAEF_log(("I_ADD_ED.B %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADD_DE_8(p) { var a = exEAtab[p.ea](1); var s = regs.d[p.Dn] & 0xff; var d = coreGet8(a); var r = s + d; if (r > 0xff) r -= 0x100; corePut8(a, r); flgAdd(s, d, r, 0x80, false); //SAEF_log(("I_ADD_DE.B %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_SUB_ED_32(p) { var s = ldEA32tab[p.ea](); var d = regs.d[p.Dn]; var r = d - s; if (r < 0) r += 0x100000000; regs.d[p.Dn] = r; flgSub(s, d, r, 0x80000000, false); //SAEF_log(("I_SUB_ED.L %08x - %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_SUB_DE_32(p) { var a = exEAtab[p.ea](4); var s = regs.d[p.Dn]; var d = coreGet32(a); var r = d - s; if (r < 0) r += 0x100000000; corePut32(a, r); flgSub(s, d, r, 0x80000000, false); //SAEF_log(("I_SUB_DE.L %08x - %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_SUB_ED_16(p) { var s = ldEA16tab[p.ea](); var d = regs.d[p.Dn] & 0xffff; var r = d - s; if (r < 0) r += 0x10000; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; flgSub(s, d, r, 0x8000, false); //SAEF_log(("I_SUB_ED.W %08x - %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_SUB_DE_16(p) { var a = exEAtab[p.ea](2); var s = regs.d[p.Dn] & 0xffff; var d = coreGet16(a); var r = d - s; if (r < 0) r += 0x10000; corePut16(a, r); flgSub(s, d, r, 0x8000, false); //SAEF_log(("I_SUB_DE.W %08x - %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_SUB_ED_8(p) { var s = ldEA8tab[p.ea](); var d = regs.d[p.Dn] & 0xff; var r = d - s; if (r < 0) r += 0x100; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffffff00) | r; flgSub(s, d, r, 0x80, false); //SAEF_log(("I_SUB_ED.B %08x - %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_SUB_DE_8(p) { var a = exEAtab[p.ea](1); var s = regs.d[p.Dn] & 0xff; var d = coreGet8(a); var r = d - s; if (r < 0) r += 0x100; corePut8(a, r); flgSub(s, d, r, 0x80, false); //SAEF_log(("I_SUB_DE.B %08x - %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_CMP_32(p) { var s = ldEA32tab[p.ea](); var d = regs.d[p.Dn]; var r = d - s; if (r < 0) r += 0x100000000; flgCmp(s, d, r, 0x80000000); //SAEF_log(("I_CMP.L %08x - %08x", d, s)); coreSyncPC(); return p.cyc; } function I_CMP_16(p) { var s = ldEA16tab[p.ea](); var d = regs.d[p.Dn] & 0xffff; var r = d - s; if (r < 0) r += 0x10000; flgCmp(s, d, r, 0x8000); //SAEF_log(("I_CMP.W %08x - %08x", d, s)); coreSyncPC(); return p.cyc; } function I_CMP_8(p) { var s = ldEA8tab[p.ea](); var d = regs.d[p.Dn] & 0xff; var r = d - s; if (r < 0) r += 0x100; flgCmp(s, d, r, 0x80); //SAEF_log(("I_CMP.B %08x - %08x", d, s)); coreSyncPC(); return p.cyc; } function I_CLR_32(p) { stEA32tab[p.ea](0); regs.z = true; regs.n = regs.v = regs.c = false; coreSyncPC(); return p.cyc; } function I_CLR_16(p) { stEA16tab[p.ea](0); regs.z = true; regs.n = regs.v = regs.c = false; coreSyncPC(); return p.cyc; } function I_CLR_8(p) { stEA8tab[p.ea](0); regs.z = true; regs.n = regs.v = regs.c = false; coreSyncPC(); return p.cyc; } function I_NEG_D_32(p) { var d = regs.d[p.Dn]; var r = 0 - d; if (r < 0) r += 0x100000000; regs.d[p.Dn] = r; flgNeg(d, r, 0x80000000, false); //SAEF_log(("I_NEG_D.L -%08x = %08x", d, r)); coreSyncPC(); return p.cyc; } function I_NEG_D_16(p) { var d = regs.d[p.Dn] & 0xffff; var r = 0 - d; if (r < 0) r += 0x10000; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; flgNeg(d, r, 0x8000, false); //SAEF_log(("I_NEG_D.W -%08x = %08x", d, r)); coreSyncPC(); return p.cyc; } function I_NEG_D_8(p) { var d = regs.d[p.Dn] & 0xff; var r = 0 - d; if (r < 0) r += 0x100; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffffff00) | r; flgNeg(d, r, 0x80, false); //SAEF_log(("I_NEG_D.B -%08x = %08x", d, r)); coreSyncPC(); return p.cyc; } function I_NEG_E_32(p) { var a = exEAtab[p.ea](4); var d = coreGet32(a); var r = 0 - d; if (r < 0) r += 0x100000000; corePut32(a, r); flgNeg(d, r, 0x80000000, false); //SAEF_log(("I_NEG_E.L -%08x = %08x", d, r)); coreSyncPC(); return p.cyc; } function I_NEG_E_16(p) { var a = exEAtab[p.ea](2); var d = coreGet16(a); var r = 0 - d; if (r < 0) r += 0x10000; corePut16(a, r); flgNeg(d, r, 0x8000, false); //SAEF_log(("I_NEG_E.W -%08x = %08x", d, r)); coreSyncPC(); return p.cyc; } function I_NEG_E_8(p) { var a = exEAtab[p.ea](1); var d = coreGet8(a); var r = 0 - d; if (r < 0) r += 0x100; corePut8(a, r); flgNeg(d, r, 0x80, false); //SAEF_log(("I_NEG_E.B -%08x = %08x", d, r)); coreSyncPC(); return p.cyc; } function I_MULS(p) { var s = ldEA16tab[p.ea](); var d = regs.d[p.Dn] & 0xffff; var sign = s ^ d; if (s & 0x8000) s = -s + 0x10000; if (d & 0x8000) d = -d + 0x10000; var r = s * d; if (r && (sign & 0x8000)) r = -r + 0x100000000; regs.d[p.Dn] = r; regs.n = (r & 0x80000000) != 0; regs.z = r == 0; regs.v = false; regs.c = false; //if (regs.n) SAEF_log(("I_MULS.W %08x * %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_MULU(p) { var s = ldEA16tab[p.ea](); var d = regs.d[p.Dn] & 0xffff; var r = s * d; regs.d[p.Dn] = r; regs.n = (r & 0x80000000) != 0; regs.z = r == 0; regs.v = false; regs.c = false; //SAEF_log(("I_MULU.W %08x * %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_MULx(p) { /* >= 68020 */ var ext = coreNext16(); var multiplier = ldEA32tab[p.ea](); var Dl = (ext >> 12) & 7; var multiplicand = regs.d[Dl]; var productLo, productHi; var _a = multiplier, _b = multiplicand; //debug if (ext & 0x800) { var sign = ((multiplier ^ multiplicand) & 0x80000000) != 0; if (multiplier & 0x80000000) multiplier = -multiplier + 0x100000000; if (multiplicand & 0x80000000) multiplicand = -multiplicand + 0x100000000; if (multiplier < 0x8000 && multiplicand < 0x8000) { productLo = multiplier * multiplicand; productHi = 0; if (productLo && sign) { productLo = -productLo + 0x100000000; productHi = 0xffffffff; } regs.v = false; //SAEF_log("I_MULS.L $%04x, %d * %d = [%08x:%08x] | PC %08x", ext, castLong(_a),castLong(_b), productHi,productLo, getPC()); } else { var result = mul64(multiplier, multiplicand); productLo = result[0]; productHi = result[1]; if (sign) { productHi = ~productHi >>> 0; if (productLo) productLo = -productLo + 0x100000000; if (productLo == 0) { productHi++; if (productHi > 0xffffffff) productHi -= 0x100000000; } } regs.v = (ext & 0x400) == 0 && (productHi != 0 || (productLo & 0x80000000) != 0) && ((productHi & 0xffffffff) != 0xffffffff || (productLo & 0x80000000) != 0x80000000); //SAEF_log("I_MULS64.L $%04x, %d * %d = [%08x:%08x] | v %d, PC %08x", ext, castLong(_a),castLong(_b), productHi,productLo, regs.v?1:0, getPC()); } } else { if (multiplier < 0x10000 && multiplicand < 0x10000) { productLo = multiplier * multiplicand; productHi = 0; regs.v = false; //SAEF_log("I_MULU.L $%04x, %d * %d = [%08x:%08x] | PC %08x", ext, _a,_b, productHi,productLo, getPC()); } else { var result = mul64(multiplier, multiplicand); productLo = result[0]; productHi = result[1]; //SAEF_log("I_MULU64.L $%04x, %d * %d = [%08x:%08x] | PC %08x", ext, _a,_b, productHi,productLo, getPC()); } regs.v = (ext & 0x400) == 0 && productHi != 0; } regs.d[Dl] = productLo; if (ext & 0x400) regs.d[ext & 7] = productHi; regs.n = (productHi & 0x80000000) != 0; regs.z = productHi == 0 && productLo == 0; regs.c = false; coreSyncPC(); return p.cyc; } function I_DIVS(p) { var s = ldEA16tab[p.ea](); regs.c = false; if (s == 0) { //SAEF_log(("I_DIVS.W %08x / 0 (coreException 5)", regs.d[p.Dn])); //coreSyncPC(); return coreException(5); } else { var d = regs.d[p.Dn], ds = d; var sign = ((d & 0x80000000) ? 1 : 0) ^ ((s & 0x8000) ? 1 : 0); if (s & 0x8000) s = -s + 0x10000; if (d & 0x80000000) d = -d + 0x100000000; var quo = (d / s) >>> 0; if (sign ? quo > 0x8000 : quo > 0x7fff) { regs.v = true; //SAEF_log(("I_DIVS.W %d / %d = %d OVERFLOW", d,s, quo)); } else { var rem = d % s; if (quo && sign) quo = -quo + 0x10000; if (rem && (rem >> 15) != (ds >>> 31)) rem = -rem + 0x10000; regs.d[p.Dn] = (rem << 16) | quo; regs.v = false; regs.z = quo == 0; regs.n = (quo & 0x8000) != 0; //SAEF_log(("I_DIVS.W %d / %d = %d[%04x:%04x] sign %x", d,s,regs.d[p.Dn], rem,quo, sign)); } coreSyncPC(); return p.cyc; } } function I_DIVU(p) { var s = ldEA16tab[p.ea](); regs.c = false; if (s == 0) { //SAEF_log(("I_DIVU.%s %08x / 0 (coreException 5)", regs.d[p.Dn])); //coreSyncPC(); return coreException(5); } else { var d = regs.d[p.Dn]; var quo = (d / s) >>> 0; if (quo > 0xffff) { regs.v = true; //SAEF_log(("I_DIVU.W %d / %d = %d OVERFLOW", d,s, quo)); } else { var rem = d % s; regs.d[p.Dn] = (rem << 16) | quo; regs.v = false; regs.z = quo == 0; regs.n = (quo & 0x8000) != 0; //SAEF_log(("I_DIVU.W %d / %d = %d[%d:%d]", d,s,regs.d[p.Dn], rem,quo)); } coreSyncPC(); return p.cyc; } } function I_DIVx(p) { /* >= 68020 */ var ext = coreNext16(); var divisor = ldEA32tab[p.ea](); var Dq = (ext >> 12) & 7; var Dr = ext & 7; var quo, rem; //var quotient, remainder; regs.c = false; if (divisor == 0) { //SAEF_log(("I_DIV%s.L %08x / 0 (coreException 5)", (ext&0x800)?"S":"U", divisor)); //coreSyncPC(); return coreException(5); } if (ext & 0x800) { if (ext & 0x400) { var dividendLo = regs.d[Dq]; var dividendHi = regs.d[Dr], orgDividendHi = dividendHi; var sign = ((dividendHi ^ divisor) & 0x80000000) != 0; if (dividendHi & 0x80000000) { dividendHi = ~dividendHi >>> 0; if (dividendLo) dividendLo = -dividendLo + 0x100000000; if (dividendLo == 0) { dividendHi++; if (dividendHi > 0xffffffff) dividendHi -= 0x100000000; } } if (divisor & 0x80000000) divisor = -divisor + 0x100000000; var result = divu64(dividendHi, dividendLo, divisor); quo = result[1]; rem = result[2]; if (result[0] || sign ? quo > 0x80000000 : quo > 0x7fffffff) { regs.v = true; //SAEF_log("I_DIVS64.L %d:%d / %d OVERFLOW", dividendHi,dividendLo,divisor); coreSyncPC(); return p.cyc; } if (quo && sign) quo = -quo + 0x100000000; if (rem && (rem & 0x80000000) != (orgDividendHi & 0x80000000)) rem = -rem + 0x100000000; //SAEF_log("I_DIVS64.L %d:%d / %d = [%08x:%08x] | PC %08x", dividendHi,dividendLo,divisor, rem,quo, getPC()); } else { var dividend = regs.d[Dq], orgDividend = dividend; var sign = ((dividend ^ divisor) & 0x80000000) != 0; if (dividend & 0x80000000) dividend = -dividend + 0x100000000; if (divisor & 0x80000000) divisor = -divisor + 0x100000000; quo = (dividend / divisor) >>> 0; if (sign ? quo > 0x80000000 : quo > 0x7fffffff) { regs.v = true; //SAEF_log("I_DIVS.L %d / %d OVERFLOW", dividend,divisor); coreSyncPC(); return p.cyc; } rem = dividend % divisor; if (quo && sign) quo = -quo + 0x100000000; if (rem && (rem & 0x80000000) != (orgDividend & 0x80000000)) rem = -rem + 0x100000000; //SAEF_log("I_DIVS.L %d / %d = [%08x:%08x] | PC %08x", dividend,divisor, rem,quo, getPC()); } } else { if (ext & 0x400) { var result = divu64(regs.d[Dr], regs.d[Dq], divisor); if (result[0]) { regs.v = true; //SAEF_log("I_DIVU64.L %d:%d / %d OVERFLOW", regs.d[Dr],regs.d[Dq],divisor); coreSyncPC(); return p.cyc; } quo = result[1]; rem = result[2]; //SAEF_log("I_DIVU64.L %d:%d / %d = [%08x:%08x] | PC %08x", regs.d[Dr],regs.d[Dq],divisor, rem,quo, getPC()); } else { quo = (regs.d[Dq] / divisor) >>> 0; rem = regs.d[Dq] % divisor; //SAEF_log("I_DIVU.L %d / %d = [%08x:%08x] | PC %08x", regs.d[Dq],divisor, rem,quo, getPC()); } } regs.d[Dq] = quo; if (Dr != Dq) regs.d[Dr] = rem; regs.v = false; regs.z = quo == 0; regs.n = (quo & 0x80000000) != 0; coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* Integer Arithmetic - Extended */ function I_ADDX_D_32(p) { var s = regs.d[p.Ry]; var d = regs.d[p.Rx]; var r = s + d + (regs.x ? 1:0); if (r > 0xffffffff) r -= 0x100000000; regs.d[p.Rx] = r; //SAEF_log(("I_ADDX_D.L %08x + %08x + %d = %08x", s, d, regs.x?1:0, r)); flgAdd(s, d, r, 0x80000000, true); coreSyncPC(); return p.cyc; } function I_ADDX_D_16(p) { var s = regs.d[p.Ry] & 0xffff; var d = regs.d[p.Rx] & 0xffff; var r = s + d + (regs.x ? 1:0); if (r > 0xffff) r -= 0x10000; regs.d[p.Rx] = (regs.d[p.Rx] & 0xffff0000) | r; //SAEF_log(("I_ADDX_D.W %08x + %08x + %d = %08x", s, d, regs.x?1:0, r)); flgAdd(s, d, r, 0x8000, true); coreSyncPC(); return p.cyc; } function I_ADDX_D_8(p) { var s = regs.d[p.Ry] & 0xff; var d = regs.d[p.Rx] & 0xff; var r = s + d + (regs.x ? 1:0); if (r > 0xff) r -= 0x100; regs.d[p.Rx] = (regs.d[p.Rx] & 0xffffff00) | r; //SAEF_log(("I_ADDX_D.B %08x + %08x + %d = %08x", s, d, regs.x?1:0, r)); flgAdd(s, d, r, 0x80, true); coreSyncPC(); return p.cyc; } function I_ADDX_M_32(p) { regs.a[p.Ry] -= 4; var s = coreGet32(regs.a[p.Ry]); regs.a[p.Rx] -= 4; var d = coreGet32(regs.a[p.Rx]); var r = s + d + (regs.x ? 1:0); if (r > 0xffffffff) r -= 0x100000000; corePut32(regs.a[p.Rx], r); //SAEF_log(("I_ADDX_M.L %08x + %08x + %d = %08x", s, d, regs.x?1:0, r)); flgAdd(s, d, r, 0x80000000, true); coreSyncPC(); return p.cyc; } function I_ADDX_M_16(p) { regs.a[p.Ry] -= 2; var s = coreGet16(regs.a[p.Ry]); regs.a[p.Rx] -= 2; var d = coreGet16(regs.a[p.Rx]); var r = s + d + (regs.x ? 1:0); if (r > 0xffff) r -= 0x10000; corePut16(regs.a[p.Rx], r); //SAEF_log(("I_ADDX_M.W %08x + %08x + %d = %08x", s, d, regs.x?1:0, r)); flgAdd(s, d, r, 0x8000, true); coreSyncPC(); return p.cyc; } function I_ADDX_M_8(p) { regs.a[p.Ry] -= aIncDec[1][p.Ry]; var s = coreGet8(regs.a[p.Ry]); regs.a[p.Rx] -= aIncDec[1][p.Rx]; var d = coreGet8(regs.a[p.Rx]); var r = s + d + (regs.x ? 1:0); if (r > 0xff) r -= 0x100; corePut8(regs.a[p.Rx], r); //SAEF_log(("I_ADDX_M.B %08x + %08x + %d = %08x", s, d, regs.x?1:0, r)); flgAdd(s, d, r, 0x80, true); coreSyncPC(); return p.cyc; } function I_SUBX_D_32(p) { var s = regs.d[p.Rx]; var d = regs.d[p.Ry]; var r = d - s - (regs.x ? 1:0); if (r < 0) r += 0x100000000; regs.d[p.Ry] = r; //SAEF_log(("I_SUBX_D.L %08x - %08x - %d = %08x", d, s, regs.x?1:0, r)); flgSub(s, d, r, 0x80000000, true); coreSyncPC(); return p.cyc; } function I_SUBX_D_16(p) { var s = regs.d[p.Rx] & 0xffff; var d = regs.d[p.Ry] & 0xffff; var r = d - s - (regs.x ? 1:0); if (r < 0) r += 0x10000; regs.d[p.Ry] = (regs.d[p.Ry] & 0xffff0000) | r; //SAEF_log(("I_SUBX_D.W %08x - %08x - %d = %08x", d, s, regs.x?1:0, r)); flgSub(s, d, r, 0x8000, true); coreSyncPC(); return p.cyc; } function I_SUBX_D_8(p) { var s = regs.d[p.Rx] & 0xff; var d = regs.d[p.Ry] & 0xff; var r = d - s - (regs.x ? 1:0); if (r < 0) r += 0x100; regs.d[p.Ry] = (regs.d[p.Ry] & 0xffffff00) | r; //SAEF_log(("I_SUBX_D.B %08x - %08x - %d = %08x", d, s, regs.x?1:0, r)); flgSub(s, d, r, 0x80, true); coreSyncPC(); return p.cyc; } function I_SUBX_M_32(p) { regs.a[p.Rx] -= 4; var s = coreGet32(regs.a[p.Rx]); regs.a[p.Ry] -= 4; var d = coreGet32(regs.a[p.Ry]); var r = d - s - (regs.x ? 1:0); if (r < 0) r += 0x100000000; corePut32(regs.a[p.Ry], r); //SAEF_log(("I_SUBX_M.L %08x - %08x - %d = %08x", d, s, regs.x?1:0, r)); flgSub(s, d, r, 0x80000000, true); coreSyncPC(); return p.cyc; } function I_SUBX_M_16(p) { regs.a[p.Rx] -= 2; var s = coreGet16(regs.a[p.Rx]); regs.a[p.Ry] -= 2; var d = coreGet16(regs.a[p.Ry]); var r = d - s - (regs.x ? 1:0); if (r < 0) r += 0x10000; corePut16(regs.a[p.Ry], r); //SAEF_log(("I_SUBX_M.W %08x - %08x - %d = %08x", d, s, regs.x?1:0, r)); flgSub(s, d, r, 0x8000, true); coreSyncPC(); return p.cyc; } function I_SUBX_M_8(p) { regs.a[p.Rx] -= aIncDec[1][p.Rx]; var s = coreGet8(regs.a[p.Rx]); regs.a[p.Ry] -= aIncDec[1][p.Ry]; var d = coreGet8(regs.a[p.Ry]); var r = d - s - (regs.x ? 1:0); if (r < 0) r += 0x100; corePut8(regs.a[p.Ry], r); //SAEF_log(("I_SUBX_M.B %08x - %08x - %d = %08x", d, s, regs.x?1:0, r)); flgSub(s, d, r, 0x80, true); coreSyncPC(); return p.cyc; } function I_NEGX_D_32(p) { var d = regs.d[p.Dn]; var r = 0 - d - (regs.x ? 1:0); if (r < 0) r += 0x100000000; regs.d[p.Dn] = r; //SAEF_log(("I_NEGX_D.L 0 - %08x - %d = %08x", d, regs.x?1:0, r)); flgNeg(d, r, 0x80000000, true); coreSyncPC(); return p.cyc; } function I_NEGX_D_16(p) { var d = regs.d[p.Dn] & 0xffff; var r = 0 - d - (regs.x ? 1:0); if (r < 0) r += 0x10000; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; //SAEF_log(("I_NEGX_D.W 0 - %08x - %d = %08x", d, regs.x?1:0, r)); flgNeg(d, r, 0x8000, true); coreSyncPC(); return p.cyc; } function I_NEGX_D_8(p) { var d = regs.d[p.Dn] & 0xff; var r = 0 - d - (regs.x ? 1:0); if (r < 0) r += 0x100; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffffff00) | r; //SAEF_log(("I_NEGX_D.B 0 - %08x - %d = %08x", d, regs.x?1:0, r)); flgNeg(d, r, 0x80, true); coreSyncPC(); return p.cyc; } function I_NEGX_E_32(p) { var a = exEAtab[p.ea](4); var d = coreGet32(a); var r = 0 - d - (regs.x ? 1:0); if (r < 0) r += 0x100000000; corePut32(a, r); //SAEF_log(("I_NEGX_E.L 0 - %08x - %d = %08x", d, regs.x?1:0, r)); flgNeg(d, r, 0x80000000, true); coreSyncPC(); return p.cyc; } function I_NEGX_E_16(p) { var a = exEAtab[p.ea](2); var d = coreGet16(a); var r = 0 - d - (regs.x ? 1:0); if (r < 0) r += 0x10000; corePut16(a, r); //SAEF_log(("I_NEGX_E.W 0 - %08x - %d = %08x", d, regs.x?1:0, r)); flgNeg(d, r, 0x8000, true); coreSyncPC(); return p.cyc; } function I_NEGX_E_8(p) { var a = exEAtab[p.ea](1); var d = coreGet8(a); var r = 0 - d - (regs.x ? 1:0); if (r < 0) r += 0x100; corePut8(a, r); //SAEF_log(("I_NEGX_E.B 0 - %08x - %d = %08x", d, regs.x?1:0, r)); flgNeg(d, r, 0x80, true); coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* Integer Arithmetic - Address */ function I_ADDA_32(p) { var s = ldEA32tab[p.ea](); var d = regs.a[p.An]; var r = s + d; if (r > 0xffffffff) r -= 0x100000000; regs.a[p.An] = r; //SAEF_log(("I_ADDA.L %08x + %08x = %08x", s, d, r)); //ccna coreSyncPC(); return p.cyc; } function I_ADDA_16(p) { var s = extWord(ldEA16tab[p.ea]()); var d = regs.a[p.An]; var r = s + d; if (r > 0xffffffff) r -= 0x100000000; regs.a[p.An] = r; //SAEF_log(("I_ADDA.W %08x + %08x = %08x", s, d, r)); //ccna coreSyncPC(); return p.cyc; } function I_SUBA_32(p) { var s = ldEA32tab[p.ea](); var d = regs.a[p.An]; var r = d - s; if (r < 0) r += 0x100000000; regs.a[p.An] = r; //SAEF_log(("I_SUBA.L %08x - %08x = %08x", d, s, r)); //ccna coreSyncPC(); return p.cyc; } function I_SUBA_16(p) { var s = extWord(ldEA16tab[p.ea]()); var d = regs.a[p.An]; var r = d - s; if (r < 0) r += 0x100000000; regs.a[p.An] = r; //SAEF_log(("I_SUBA.W %08x - %08x = %08x", d, s, r)); //ccna coreSyncPC(); return p.cyc; } function I_CMPA_32(p) { var s = ldEA32tab[p.ea](); var d = regs.a[p.An]; var r = d - s; if (r < 0) r += 0x100000000; flgCmp(s, d, r, 0x80000000); //SAEF_log(("I_CMPA.L %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_CMPA_16(p) { var s = extWord(ldEA16tab[p.ea]()); var d = regs.a[p.An]; var r = d - s; if (r < 0) r += 0x100000000; flgCmp(s, d, r, 0x80000000); //SAEF_log(("I_CMPA.W %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* Integer Arithmetic - Immediate */ function I_ADDI_D_32(p) { var s = coreNext32(); var d = regs.d[p.Dn]; var r = s + d; if (r > 0xffffffff) r -= 0x100000000; regs.d[p.Dn] = r; flgAdd(s, d, r, 0x80000000, false); //SAEF_log(("I_ADDI_D.L %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADDI_D_16(p) { var s = coreNext16(); var d = regs.d[p.Dn] & 0xffff; var r = s + d; if (r > 0xffff) r -= 0x10000; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; flgAdd(s, d, r, 0x8000, false); //SAEF_log(("I_ADDI_D.W %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADDI_D_8(p) { var s = coreNext16() & 0xff; var d = regs.d[p.Dn] & 0xff; var r = s + d; if (r > 0xff) r -= 0x100; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffffff00) | r; flgAdd(s, d, r, 0x80, false); //SAEF_log(("I_ADDI_D.B %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADDI_E_32(p) { var s = coreNext32(); var a = exEAtab[p.ea](4); var d = coreGet32(a); var r = s + d; if (r > 0xffffffff) r -= 0x100000000; corePut32(a, r); flgAdd(s, d, r, 0x80000000, false); //SAEF_log(("I_ADDI_E.L %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADDI_E_16(p) { var s = coreNext16(); var a = exEAtab[p.ea](2); var d = coreGet16(a); var r = s + d; if (r > 0xffff) r -= 0x10000; corePut16(a, r); flgAdd(s, d, r, 0x8000, false); //SAEF_log(("I_ADDI_E.W %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADDI_E_8(p) { var s = coreNext16() & 0xff; var a = exEAtab[p.ea](1); var d = coreGet8(a); var r = s + d; if (r > 0xff) r -= 0x100; corePut8(a, r); flgAdd(s, d, r, 0x80, false); //SAEF_log(("I_ADDI_E.B %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_SUBI_D_32(p) { var s = coreNext32(); var d = regs.d[p.Dn]; var r = d - s; if (r < 0) r += 0x100000000; regs.d[p.Dn] = r; flgSub(s, d, r, 0x80000000, false); //SAEF_log(("I_SUBI_D.L %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_SUBI_D_16(p) { var s = coreNext16(); var d = regs.d[p.Dn] & 0xffff; var r = d - s; if (r < 0) r += 0x10000; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; flgSub(s, d, r, 0x8000, false); //SAEF_log(("I_SUBI_D.W %08x - %08x = %08x", d, s, d, r)); coreSyncPC(); return p.cyc; } function I_SUBI_D_8(p) { var s = coreNext16() & 0xff; var d = regs.d[p.Dn] & 0xff; var r = d - s; if (r < 0) r += 0x100; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffffff00) | r; flgSub(s, d, r, 0x80, false); //SAEF_log(("I_SUBI_D.B %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_SUBI_E_32(p) { var s = coreNext32(); var a = exEAtab[p.ea](4); var d = coreGet32(a); var r = d - s; if (r < 0) r += 0x100000000; corePut32(a, r); flgSub(s, d, r, 0x80000000, false); //SAEF_log(("I_SUBI_E.L %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_SUBI_E_16(p) { var s = coreNext16(); var a = exEAtab[p.ea](2); var d = coreGet16(a); var r = d - s; if (r < 0) r += 0x10000; corePut16(a, r); flgSub(s, d, r, 0x8000, false); //SAEF_log(("I_SUBI_E.W %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_SUBI_E_8(p) { var s = coreNext16() & 0xff; var a = exEAtab[p.ea](1); var d = coreGet8(a); var r = d - s; if (r < 0) r += 0x100; corePut8(a, r); flgSub(s, d, r, 0x80, false); //SAEF_log(("I_SUBI_E.B %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_CMPI_32(p) { var s = coreNext32(); var d = ldEA32tab[p.ea](); var r = d - s; if (r < 0) r += 0x100000000; flgCmp(s, d, r, 0x80000000); //SAEF_log(("I_CMPI.L %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_CMPI_16(p) { var s = coreNext16(); var d = ldEA16tab[p.ea](); var r = d - s; if (r < 0) r += 0x10000; flgCmp(s, d, r, 0x8000); //SAEF_log(("I_CMPI.W %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_CMPI_8(p) { var s = coreNext16() & 0xff; var d = ldEA8tab[p.ea](); var r = d - s; if (r < 0) r += 0x100; flgCmp(s, d, r, 0x80); //SAEF_log(("I_CMPI.B %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* Integer Arithmetic - Quick */ function I_ADDQ_D_32(p) { var s = p.data; var d = regs.d[p.Dn]; var r = s + d; if (r > 0xffffffff) r -= 0x100000000; regs.d[p.Dn] = r; flgAdd(s, d, r, 0x80000000, false); //SAEF_log(("I_ADDQ_D.L %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADDQ_A_32(p) { var s = p.data; var d = regs.a[p.An]; var r = s + d; if (r > 0xffffffff) r -= 0x100000000; regs.a[p.An] = r; //ccna //SAEF_log(("I_ADDQ_A.L %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADDQ_E_32(p) { var a = exEAtab[p.ea](4); var s = p.data; var d = coreGet32(a); var r = s + d; if (r > 0xffffffff) r -= 0x100000000; corePut32(a, r); flgAdd(s, d, r, 0x80000000, false); //SAEF_log(("I_ADDQ_E.L %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADDQ_D_16(p) { var s = p.data; var d = regs.d[p.Dn] & 0xffff; var r = s + d; if (r > 0xffff) r -= 0x10000; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; flgAdd(s, d, r, 0x8000, false); //SAEF_log(("I_ADDQ_D.W %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADDQ_E_16(p) { var a = exEAtab[p.ea](2); var s = p.data; var d = coreGet16(a); var r = s + d; if (r > 0xffff) r -= 0x10000; corePut16(a, r); flgAdd(s, d, r, 0x8000, false); //SAEF_log(("I_ADDQ_E.W %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADDQ_D_8(p) { var s = p.data; var d = regs.d[p.Dn] & 0xff; var r = s + d; if (r > 0xff) r -= 0x100; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffffff00) | r; flgAdd(s, d, r, 0x80, false); //SAEF_log(("I_ADDQ_D.B %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ADDQ_E_8(p) { var a = exEAtab[p.ea](1); var s = p.data; var d = coreGet8(a); var r = s + d; if (r > 0xff) r -= 0x100; corePut8(a, r); flgAdd(s, d, r, 0x80, false); //SAEF_log(("I_ADDQ_E.B %08x + %08x = %08x", s, d, r)); coreSyncPC(); return p.cyc; } function I_SUBQ_D_32(p) { var s = p.data; var d = regs.d[p.Dn]; var r = d - s; if (r < 0) r += 0x100000000; regs.d[p.Dn] = r; flgSub(s, d, r, 0x80000000, false); //SAEF_log(("I_SUBQ_D.L %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_SUBQ_A_32(p) { var s = p.data; var d = regs.a[p.An]; var r = d - s; if (r < 0) r += 0x100000000; regs.a[p.An] = r; //ccna //SAEF_log(("I_SUBQ_A.L %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_SUBQ_E_32(p) { var a = exEAtab[p.ea](4); var s = p.data; var d = coreGet32(a); var r = d - s; if (r < 0) r += 0x100000000; corePut32(a, r); flgSub(s, d, r, 0x80000000, false); //SAEF_log(("I_SUBQ_E.L %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_SUBQ_D_16(p) { var s = p.data; var d = regs.d[p.Dn] & 0xffff; var r = d - s; if (r < 0) r += 0x10000; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; flgSub(s, d, r, 0x8000, false); //SAEF_log(("I_SUBQ_D.W %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_SUBQ_E_16(p) { var a = exEAtab[p.ea](2); var s = p.data; var d = coreGet16(a); var r = d - s; if (r < 0) r += 0x10000; corePut16(a, r); flgSub(s, d, r, 0x8000, false); //SAEF_log(("I_SUBQ_E.W %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_SUBQ_D_8(p) { var s = p.data; var d = regs.d[p.Dn] & 0xff; var r = d - s; if (r < 0) r += 0x100; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffffff00) | r; flgSub(s, d, r, 0x80, false); //SAEF_log(("I_SUBQ_D.B %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_SUBQ_E_8(p) { var a = exEAtab[p.ea](1); var s = p.data; var d = coreGet8(a); var r = d - s; if (r < 0) r += 0x100; corePut8(a, r); flgSub(s, d, r, 0x80, false); //SAEF_log(("I_SUBQ_E.B %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* Integer Arithmetic - Misc */ function I_CMPM_32(p) { var s = coreGet32(regs.a[p.Ay]); regs.a[p.Ay] += 4; var d = coreGet32(regs.a[p.Ax]); regs.a[p.Ax] += 4; var r = d - s; if (r < 0) r += 0x100000000; flgCmp(s, d, r, 0x80000000); //SAEF_log(("I_CMPM.L %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_CMPM_16(p) { var s = coreGet16(regs.a[p.Ay]); regs.a[p.Ay] += 2; var d = coreGet16(regs.a[p.Ax]); regs.a[p.Ax] += 2; var r = d - s; if (r < 0) r += 0x10000; flgCmp(s, d, r, 0x8000); //SAEF_log(("I_CMPM.W %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_CMPM_8(p) { var s = coreGet8(regs.a[p.Ay]); regs.a[p.Ay] += aIncDec[1][p.Ay]; var d = coreGet8(regs.a[p.Ax]); regs.a[p.Ax] += aIncDec[1][p.Ax]; var r = d - s; if (r < 0) r += 0x100; flgCmp(s, d, r, 0x80); //SAEF_log(("I_CMPM.B %08x - %08x = %08x", d, s, r)); coreSyncPC(); return p.cyc; } function I_EXT_16(p) { var d = regs.d[p.Dn] & 0xff; var r = (d & 0x80) ? 0xff00 | d : d; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; flgLogical(r, 0x8000); //SAEF_log(("I_EXT.W %08x -> %08x", d, r)); coreSyncPC(); return p.cyc; } function I_EXT_32(p) { var d = regs.d[p.Dn] & 0xffff; var r = (d & 0x8000) ? ((0xffff0000 | d) >>> 0) : d; regs.d[p.Dn] = r; flgLogical(r, 0x80000000); //SAEF_log(("I_EXT.L %08x -> %08x", d, r)); coreSyncPC(); return p.cyc; } function I_EXTB(p) { /* >= 68020 */ var d = regs.d[p.Dn] & 0xff; var r = (d & 0x80) ? ((0xffffff00 | d) >>> 0) : d; regs.d[p.Dn] = r; flgLogical(r, 0x80000000); //SAEF_log(("I_EXTB.L %08x -> %08x", d, r)); coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* Logical */ function I_AND_D_32(p) { var r = (ldEA32tab[p.ea]() & regs.d[p.Dn]) >>> 0; regs.d[p.Dn] = r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_AND_D_16(p) { var r = ldEA16tab[p.ea]() & (regs.d[p.Dn] & 0xffff); regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_AND_D_8(p) { var r = ldEA8tab[p.ea]() & (regs.d[p.Dn] & 0xff); regs.d[p.Dn] = (regs.d[p.Dn] & 0xffffff00) | r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_AND_E_32(p) { var a = exEAtab[p.ea](4); var r = (regs.d[p.Dn] & coreGet32(a)) >>> 0; corePut32(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_AND_E_16(p) { var a = exEAtab[p.ea](2); var r = (regs.d[p.Dn] & 0xffff) & coreGet16(a); corePut16(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_AND_E_8(p) { var a = exEAtab[p.ea](1); var r = (regs.d[p.Dn] & 0xff) & coreGet8(a); corePut8(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_EOR_D_32(p) { var r = (regs.d[p.Dd] ^ regs.d[p.Dn]) >>> 0; regs.d[p.Dd] = r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_EOR_D_16(p) { var r = (regs.d[p.Dd] & 0xffff) ^ (regs.d[p.Dn] & 0xffff); regs.d[p.Dd] = (regs.d[p.Dd] & 0xffff0000) | r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_EOR_D_8(p) { var r = (regs.d[p.Dd] & 0xff) ^ (regs.d[p.Dn] & 0xff); regs.d[p.Dd] = (regs.d[p.Dd] & 0xffffff00) | r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_EOR_E_32(p) { var a = exEAtab[p.ea](4); var r = (coreGet32(a) ^ regs.d[p.Dn]) >>> 0; corePut32(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_EOR_E_16(p) { var a = exEAtab[p.ea](2); var r = coreGet16(a) ^ (regs.d[p.Dn] & 0xffff); corePut16(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_EOR_E_8(p) { var a = exEAtab[p.ea](1); var r = coreGet8(a) ^ (regs.d[p.Dn] & 0xff); corePut8(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_NOT_D_32(p) { var r = ~regs.d[p.Dn] >>> 0; regs.d[p.Dn] = r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_NOT_D_16(p) { var r = ~(regs.d[p.Dn] & 0xffff) & p.m; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_NOT_D_8(p) { var r = ~(regs.d[p.Dn] & 0xff) & p.m; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffffff00) | r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_NOT_E_32(p) { var a = exEAtab[p.ea](4); var r = ~coreGet32(a) >>> 0; corePut32(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_NOT_E_16(p) { var a = exEAtab[p.ea](2); var r = ~coreGet16(a) & p.m; corePut16(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_NOT_E_8(p) { var a = exEAtab[p.ea](1); var r = ~coreGet8(a) & p.m; corePut8(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_OR_D_32(p) { var r = (ldEA32tab[p.ea]() | regs.d[p.Dn]) >>> 0; regs.d[p.Dn] = r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_OR_D_16(p) { var r = ldEA16tab[p.ea]() | (regs.d[p.Dn] & 0xffff); regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_OR_D_8(p) { var r = ldEA8tab[p.ea]() | (regs.d[p.Dn] & 0xff); regs.d[p.Dn] = (regs.d[p.Dn] & 0xffffff00) | r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_OR_E_32(p) { var a = exEAtab[p.ea](4); var r = (regs.d[p.Dn] | coreGet32(a)) >>> 0; corePut32(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_OR_E_16(p) { var a = exEAtab[p.ea](2); var r = (regs.d[p.Dn] & 0xffff) | coreGet16(a); corePut16(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_OR_E_8(p) { var a = exEAtab[p.ea](1); var r = (regs.d[p.Dn] & 0xff) | coreGet8(a); corePut8(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* Logical - Immediate */ function I_ANDI_D_32(p) { var r = (coreNext32() & regs.d[p.Dn]) >>> 0; regs.d[p.Dn] = r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_ANDI_D_16(p) { var r = coreNext16() & (regs.d[p.Dn] & 0xffff); regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_ANDI_D_8(p) { var r = (coreNext16() & 0xff) & (regs.d[p.Dn] & 0xff); regs.d[p.Dn] = (regs.d[p.Dn] & 0xffffff00) | r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_ANDI_E_32(p) { var s = coreNext32(); var a = exEAtab[p.ea](4); var d = coreGet32(a); var r = (s & d) >>> 0; corePut32(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_ANDI_E_16(p) { var s = coreNext16(); var a = exEAtab[p.ea](2); var d = coreGet16(a); var r = s & d; corePut16(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_ANDI_E_8(p) { var s = coreNext16() & 0xff; var a = exEAtab[p.ea](1); var d = coreGet8(a); var r = s & d; corePut8(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_EORI_D_32(p) { var r = (coreNext32() ^ regs.d[p.Dn]) >>> 0; regs.d[p.Dn] = r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_EORI_D_16(p) { var r = coreNext16() ^ (regs.d[p.Dn] & 0xffff); regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_EORI_D_8(p) { var r = (coreNext16() & 0xff) ^ (regs.d[p.Dn] & 0xff); regs.d[p.Dn] = (regs.d[p.Dn] & 0xffffff00) | r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_EORI_E_32(p) { var s = coreNext32(); var a = exEAtab[p.ea](4); var d = coreGet32(a); var r = (s ^ d) >>> 0; corePut32(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_EORI_E_16(p) { var s = coreNext16(); var a = exEAtab[p.ea](2); var d = coreGet16(a); var r = s ^ d; corePut16(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_EORI_E_8(p) { var s = coreNext16() & 0xff; var a = exEAtab[p.ea](1); var d = coreGet8(a); var r = s ^ d; corePut8(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_ORI_D_32(p) { var r = (coreNext32() | regs.d[p.Dn]) >>> 0; regs.d[p.Dn] = r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_ORI_D_16(p) { var r = coreNext16() | (regs.d[p.Dn] & 0xffff); regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_ORI_D_8(p) { var r = (coreNext16() & 0xff) | (regs.d[p.Dn] & 0xff); regs.d[p.Dn] = (regs.d[p.Dn] & 0xffffff00) | r; flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_ORI_E_32(p) { var s = coreNext32(); var a = exEAtab[p.ea](4); var d = coreGet32(a); var r = (s | d) >>> 0; corePut32(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_ORI_E_16(p) { var s = coreNext16(); var a = exEAtab[p.ea](2); var d = coreGet16(a); var r = s | d; corePut16(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } function I_ORI_E_8(p) { var s = coreNext16() & 0xff; var a = exEAtab[p.ea](1); var d = coreGet8(a); var r = s | d; corePut8(a, r); flgLogical(r, p.zm); coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* Shift and Rotate */ function I_ASL_32(p) { var d = regs.d[p.Dy], _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { var sign = (d & 0x80000000) != 0; var mask = ~((1 << (32 - n)) - 1) >>> 0; //var mask = (0xffffffff << (31 - n)) >>> 0; regs.x = regs.c = (d & (1 << (32-n))) != 0; regs.v = sign ? (((d & mask) >>> 0) != mask) : (((d & mask) >>> 0) != 0); //regs.v = ((d & mask) >>> 0) != mask && ((d & mask) >>> 0) != 0; d = ((d << n) & 0xffffffff) >>> 0; regs.d[p.Dy] = d; } else regs.v = regs.c = false; regs.n = (d & 0x80000000) != 0; regs.z = d == 0; //if (sign) SAEF_log(("I_ASL.L %08x << %d = %08x, sign %d, mask %x, V %d -> %08x", _d, n, d, sign?1:0, mask, regs.v?1:0, (_d & mask)>>>0)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ASL_16(p) { var d = regs.d[p.Dy] & 0xffff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { var sign = (d & 0x8000) != 0; var mask = ~((1 << (16 - n)) - 1) & 0xffff; //var mask = (0xffff << (15 - n)) & 0xffff; regs.x = regs.c = (d & (1 << (16-n))) != 0; regs.v = sign ? (d & mask) != mask : (d & mask) != 0; //regs.v = (d & mask) != mask && (d & mask) != 0; d = ((d << n) & 0xffff) >>> 0; regs.d[p.Dy] = (regs.d[p.Dy] & 0xffff0000) | d; } else regs.v = regs.c = false; regs.n = (d & 0x8000) != 0; regs.z = d == 0; //if (sign) SAEF_log(("I_ASL.W %08x << %d = %08x, sign %d, mask %x, V %d", _d, n, d, sign?1:0, mask, regs.v?1:0)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ASL_8(p) { var d = regs.d[p.Dy] & 0xff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { var sign = (d & 0x80) != 0; var mask = ~((1 << (8 - n)) - 1) & 0xff; //var mask = (0xff << (7 - n)) & 0xff; regs.x = regs.c = (d & (1 << (8-n))) != 0; regs.v = sign ? (d & mask) != mask : (d & mask) != 0; //regs.v = (d & mask) != mask && (d & mask) != 0; d = ((d << n) & 0xff) >>> 0; regs.d[p.Dy] = (regs.d[p.Dy] & 0xffffff00) | d; } else regs.v = regs.c = false; regs.n = (d & 0x80) != 0; regs.z = d == 0; //if (sign) SAEF_log(("I_ASL.B %08x << %d = %08x, sign %d, mask %x, V %d", _d, n, d, sign?1:0, mask, regs.v?1:0)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ASR_32(p) { var d = regs.d[p.Dy], _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.x = regs.c = (d & (1 << (n-1))) != 0; d = (d >> n) >>> 0; //js 32 regs.d[p.Dy] = d; } else regs.c = false; regs.n = (d & 0x80000000) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ASR.L %08x >> %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ASR_16(p) { var d = regs.d[p.Dy] & 0xffff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.x = regs.c = (d & (1 << (n-1))) != 0; d = extWord(d); d = ((d >> n) & 0xffff) >>> 0; //js 32 //d >>= n; regs.d[p.Dy] = (regs.d[p.Dy] & 0xffff0000) | d; } else regs.c = false; regs.n = (d & 0x8000) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ASR.W %08x >> %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ASR_8(p) { var d = regs.d[p.Dy] & 0xff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.x = regs.c = (d & (1 << (n-1))) != 0; d = extByte(d); d = ((d >> n) & 0xff) >>> 0; //js 32 //d >>= n; regs.d[p.Dy] = (regs.d[p.Dy] & 0xffffff00) | d; } else regs.c = false; regs.n = (d & 0x80) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ASR.B %08x >> %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ASL_M(p) { var a = exEAtab[p.ea](2); var d = coreGet16(a), _d = d; regs.x = regs.c = (d & 0x8000) != 0; regs.v = regs.c != ((d & 0x4000) != 0); d = (d << 1) & 0xffff; regs.n = (d & 0x8000) != 0; regs.z = d == 0; corePut16(a, d); //SAEF_log(("I_ASL_M.W %08x << 1 = %08x", _d, d)); coreSyncPC(); return p.cyc; } function I_ASR_M(p) { var a = exEAtab[p.ea](2); var d = coreGet16(a), _d = d; var sign = d & 0x8000; regs.x = regs.c = (d & 1) != 0; regs.v = false; d = sign | (d >> 1); regs.n = (d & 0x8000) != 0; regs.z = d == 0; corePut16(a, d); //SAEF_log(("I_ASR_M.W %08x >> 1 = %08x", _d, d)); coreSyncPC(); return p.cyc; } function I_LSL_32(p) { var d = regs.d[p.Dy], _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.x = regs.c = (d & (1 << (32-n))) != 0; d = ((d << n) & 0xffffffff) >>> 0; regs.d[p.Dy] = d; } else regs.c = false; regs.n = (d & 0x80000000) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_LSL.L %08x << %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_LSL_16(p) { var d = regs.d[p.Dy] & 0xffff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.x = regs.c = (d & (1 << (16-n))) != 0; d = ((d << n) & 0xffff) >>> 0; regs.d[p.Dy] = (regs.d[p.Dy] & 0xffff0000) | d; } else regs.c = false; regs.n = (d & 0x8000) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_LSL.W %08x << %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_LSL_8(p) { var d = regs.d[p.Dy] & 0xff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.x = regs.c = (d & (1 << (8-n))) != 0; d = ((d << n) & 0xff) >>> 0; regs.d[p.Dy] = (regs.d[p.Dy] & 0xffffff00) | d; } else regs.c = false; regs.n = (d & 0x80) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_LSL.B %08x << %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_LSR_32(p) { var d = regs.d[p.Dy], _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.x = regs.c = (d & (1 << (n-1))) != 0; d = d >>> n; regs.d[p.Dy] = d; } else regs.c = false; regs.n = (d & 0x80000000) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_LSR.L %08x >> %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_LSR_16(p) { var d = regs.d[p.Dy] & 0xffff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.x = regs.c = (d & (1 << (n-1))) != 0; d >>= n; regs.d[p.Dy] = (regs.d[p.Dy] & 0xffff0000) | d; } else regs.c = false; regs.n = (d & 0x8000) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_LSR.W %08x >> %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_LSR_8(p) { var d = regs.d[p.Dy] & 0xff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.x = regs.c = (d & (1 << (n-1))) != 0; d >>= n; regs.d[p.Dy] = (regs.d[p.Dy] & 0xffffff00) | d; } else regs.c = false; regs.n = (d & 0x80) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_LSR.B %08x >> %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_LSL_M(p) { var a = exEAtab[p.ea](2); var d = coreGet16(a), _d = d; regs.x = regs.c = (d & 0x8000) != 0; d = (d << 1) & 0xffff; regs.n = (d & 0x8000) != 0; regs.z = d == 0; regs.v = false; corePut16(a, d); //SAEF_log(("I_LSL_M.W %08x << 1 = %08x", _d, d)); coreSyncPC(); return p.cyc; } function I_LSR_M(p) { var a = exEAtab[p.ea](2); var d = coreGet16(a), _d = d; regs.x = regs.c = (d & 1) != 0; d >>= 1; regs.n = (d & 0x8000) != 0; regs.z = d == 0; regs.v = false; corePut16(a, d); //SAEF_log(("I_LSR_M.W %08x >> 1 = %08x", _d, d)); coreSyncPC(); return p.cyc; } function I_ROL_32(p) { var d = regs.d[p.Dy], _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.c = (d & (1 << (32-n))) != 0; d = (((d << n) | (d >>> (32-n))) & 0xffffffff) >>> 0; regs.d[p.Dy] = d; } else regs.c = false; regs.n = (d & 0x80000000) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ROL.L %08x << %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ROL_16(p) { var d = regs.d[p.Dy] & 0xffff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.c = (d & (1 << (16-n))) != 0; d = (((d << n) | (d >> (16-n))) & 0xffff) >>> 0; regs.d[p.Dy] = (regs.d[p.Dy] & 0xffff0000) | d; } else regs.c = false; regs.n = (d & 0x8000) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ROL.W %08x << %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ROL_8(p) { var d = regs.d[p.Dy] & 0xff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.c = (d & (1 << (8-n))) != 0; d = (((d << n) | (d >> (8-n))) & 0xff) >>> 0; regs.d[p.Dy] = (regs.d[p.Dy] & 0xffffff00) | d; } else regs.c = false; regs.n = (d & 0x80) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ROL.B %08x << %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ROR_32(p) { var d = regs.d[p.Dy], _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.c = (d & (1 << (n-1))) != 0; d = (((d << (32-n)) | (d >>> n)) & 0xffffffff) >>> 0; regs.d[p.Dy] = d; } else regs.c = false; regs.n = (d & 0x80000000) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ROR.L %08x >> %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ROR_16(p) { var d = regs.d[p.Dy] & 0xffff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.c = (d & (1 << (n-1))) != 0; d = (((d << (16-n)) | (d >>> n)) & 0xffff) >>> 0; regs.d[p.Dy] = (regs.d[p.Dy] & 0xffff0000) | d; } else regs.c = false; regs.n = (d & 0x8000) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ROR.W %08x >> %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ROR_8(p) { var d = regs.d[p.Dy] & 0xff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.c = (d & (1 << (n-1))) != 0; d = (((d << (8-n)) | (d >>> n)) & 0xff) >>> 0; regs.d[p.Dy] = (regs.d[p.Dy] & 0xffffff00) | d; } else regs.c = false; regs.n = (d & 0x80) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ROR.B %08x >> %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ROL_M(p) { var a = exEAtab[p.ea](2); var d = coreGet16(a), _d = d; regs.c = (d & 0x8000) != 0; d = ((d << 1) & 0xffff) | (regs.c ? 1:0); regs.n = (d & 0x8000) != 0; regs.z = d == 0; regs.v = false; corePut16(a, d); //SAEF_log(("I_ROL_M.W %08x << 1 = %08x", _d, d)); coreSyncPC(); return p.cyc; } function I_ROR_M(p) { var a = exEAtab[p.ea](2); var d = coreGet16(a), _d = d; regs.c = (d & 1) != 0; d = (regs.c ? 0x8000 : 0) | (d >> 1); regs.n = (d & 0x8000) != 0; regs.z = d == 0; regs.v = false; corePut16(a, d); //SAEF_log(("I_ROR_M.W %08x >> 1 = %08x", _d, d)); coreSyncPC(); return p.cyc; } function I_ROXL_32(p) { var d = regs.d[p.Dy], _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.c = (d & (1 << (32-n))) != 0; d = (((d << n) | (d >>> (32-n))) & 0xffffffff) >>> 0; d = ((d & 0xfffffffe) | (regs.x ? 1 : 0)) >>> 0; regs.d[p.Dy] = d; regs.x = regs.c; } else regs.c = regs.x; regs.n = (d & 0x80000000) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ROXL.L %08x << %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ROXL_16(p) { var d = regs.d[p.Dy] & 0xffff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.c = (d & (1 << (16-n))) != 0; d = ((d << n) | (d >> (16-n))) & 0xffff; d = (d & 0xfffe) | (regs.x ? 1 : 0); regs.d[p.Dy] = (regs.d[p.Dy] & 0xffff0000) | d; regs.x = regs.c; } else regs.c = regs.x; regs.n = (d & 0x8000) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ROXL.W %08x << %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ROXL_8(p) { var d = regs.d[p.Dy] & 0xff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.c = (d & (1 << (8-n))) != 0; d = ((d << n) | (d >> (8-n))) & 0xff; d = (d & 0xfe) | (regs.x ? 1 : 0); regs.d[p.Dy] = (regs.d[p.Dy] & 0xffffff00) | d; regs.x = regs.c; } else regs.c = regs.x; regs.n = (d & 0x80) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ROXL.B %08x << %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ROXR_32(p) { var d = regs.d[p.Dy], _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.c = (d & (1 << (n-1))) != 0; d = (((d << (32-n)) | (d >>> n)) & 0xffffffff) >>> 0; d = ((regs.x ? 0x80000000 : 0) | (d & 0x7fffffff)) >>> 0; regs.d[p.Dy] = d; regs.x = regs.c; } else regs.c = regs.x; regs.n = (d & 0x80000000) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ROXR.L %08x >> %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ROXR_16(p) { var d = regs.d[p.Dy] & 0xffff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.c = (d & (1 << (n-1))) != 0; d = ((d << (16-n)) | (d >>> n)) & 0xffff; d = (regs.x ? 0x8000 : 0) | (d & 0x7fff); regs.d[p.Dy] = (regs.d[p.Dy] & 0xffff0000) | d; regs.x = regs.c; } else regs.c = regs.x; regs.n = (d & 0x8000) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ROXR.W %08x >> %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ROXR_8(p) { var d = regs.d[p.Dy] & 0xff, _d = d; var n = p.ir ? regs.d[p.cr] & 63 : p.cr; if (n) { regs.c = (d & (1 << (n-1))) != 0; d = ((d << (8-n)) | (d >>> n)) & 0xff; d = (regs.x ? 0x80 : 0) | (d & 0x7f); regs.d[p.Dy] = (regs.d[p.Dy] & 0xffffff00) | d; regs.x = regs.c; } else regs.c = regs.x; regs.n = (d & 0x80) != 0; regs.z = d == 0; regs.v = false; //SAEF_log(("I_ROXR.B %08x >> %d = %08x", _d, n, d)); coreSyncPC(); return [p.cyc[0]+2*n,p.cyc[1],p.cyc[2]]; } function I_ROXL_M(p) { var a = exEAtab[p.ea](2); var d = coreGet16(a), _d = d; regs.c = (d & 0x8000) != 0; d = ((d << 1) & 0xffff) | (regs.x ? 1:0); regs.x = regs.c; regs.n = (d & 0x8000) != 0; regs.z = d == 0; regs.v = false; corePut16(a, d); //SAEF_log(("I_ROXL_M.W %08x << 1 = %08x", _d, d)); coreSyncPC(); return p.cyc; } function I_ROXR_M(p) { var a = exEAtab[p.ea](2); var d = coreGet16(a), _d = d; regs.c = (d & 1) != 0; d = (regs.x ? 0x8000 : 0) | (d >> 1); regs.x = regs.c; regs.n = (d & 0x8000) != 0; regs.z = d == 0; regs.v = false; corePut16(a, d); //SAEF_log(("I_ROXR_M.W %08x >> 1 = %08x", _d, d)); coreSyncPC(); return p.cyc; } function I_SWAP(p) { var d = regs.d[p.Dn]; var r = (((d & 0xffff) << 16) | (d >>> 16)) >>> 0; regs.d[p.Dn] = r; regs.n = (r & 0x80000000) != 0; regs.z = r == 0; regs.v = regs.c = false; //SAEF_log(("I_SWAP.W %08x <> %08x", d, r)); coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* Bit Manipulation */ function I_BCHG_DD_32(p) { var s = regs.d[p.Dn] & 31; var d = regs.d[p.Dd]; var m = (1 << s) >>> 0; regs.z = (d & m) == 0; var r = (d ^ m) >>> 0; regs.d[p.Dd] = r; //SAEF_log(("I_BCHG1.L s %08x == m %08x, d %08x, r %08x", s, m, d, r)); coreSyncPC(); return p.cyc; } function I_BCHG_DE_8(p) { var a = exEAtab[p.ea](1); var s = regs.d[p.Dn] & 7; var d = coreGet8(a); var m = 1 << s; regs.z = (d & m) == 0; var r = d ^ m; corePut8(a, r); //SAEF_log(("I_BCHG1.B s %08x == m %08x, d %08x, r %08x", s, m, d, r)); coreSyncPC(); return p.cyc; } function I_BCHG_ID_32(p) { var s = coreNext16() & 31; var d = regs.d[p.Dd]; var m = (1 << s) >>> 0; regs.z = (d & m) == 0; var r = (d ^ m) >>> 0; regs.d[p.Dd] = r; //SAEF_log(("I_BCHG2.L s %08x == m %08x, d %08x, r %08x", s, m, d, r)); coreSyncPC(); return p.cyc; } function I_BCHG_IE_8(p) { var s = coreNext16() & 7; var a = exEAtab[p.ea](1); var d = coreGet8(a); var m = 1 << s; regs.z = (d & m) == 0; var r = d ^ m; corePut8(a, r); //SAEF_log(("I_BCHG2.B s %08x == m %08x, d %08x, r %08x", s, m, d, r)); coreSyncPC(); return p.cyc; } function I_BCLR_DD_32(p) { var s = regs.d[p.Dn] & 31; var d = regs.d[p.Dd]; var m = (1 << s) >>> 0; regs.z = (d & m) == 0; var r = (d & ~m) >>> 0; regs.d[p.Dd] = r; //SAEF_log(("I_BCLR1.L s %08x == m %08x, d %08x, r %08x", s, m, d, r)); coreSyncPC(); return p.cyc; } function I_BCLR_DE_8(p) { var a = exEAtab[p.ea](1); var s = regs.d[p.Dn] & 7; var d = coreGet8(a); var m = 1 << s; regs.z = (d & m) == 0; var r = d & ~m; corePut8(a, r); //SAEF_log(("I_BCLR1.B s %08x == m %08x, d %08x, r %08x", s, m, d, r)); coreSyncPC(); return p.cyc; } function I_BCLR_ID_32(p) { var s = coreNext16() & 31; var d = regs.d[p.Dd]; var m = (1 << s) >>> 0; regs.z = (d & m) == 0; var r = (d & ~m) >>> 0; regs.d[p.Dd] = r; //SAEF_log(("I_BCLR2.L s %08x == m %08x, d %08x, r %08x", s, m, d, r)); coreSyncPC(); return p.cyc; } function I_BCLR_IE_8(p) { var s = coreNext16() & 7; var a = exEAtab[p.ea](1); var d = coreGet8(a); var m = 1 << s; regs.z = (d & m) == 0; var r = d & ~m; corePut8(a, r); //SAEF_log(("I_BCLR2.B s %08x == m %08x, d %08x, r %08x", s, m, d, r)); coreSyncPC(); return p.cyc; } function I_BSET_DD_32(p) { var s = regs.d[p.Dn] & 31; var d = regs.d[p.Dd]; var m = (1 << s) >>> 0; regs.z = (d & m) == 0; var r = (d | m) >>> 0; regs.d[p.Dd] = r; //SAEF_log(("I_BSET1.L s %08x == m %08x, d %08x, r %08x", s, m, d, r)); coreSyncPC(); return p.cyc; } function I_BSET_DE_8(p) { var a = exEAtab[p.ea](1); var s = regs.d[p.Dn] & 7; var d = coreGet8(a); var m = 1 << s; regs.z = (d & m) == 0; var r = d | m; corePut8(a, r); //SAEF_log(("I_BSET1.B s %08x == m %08x, d %08x, r %08x", s, m, d, r)); coreSyncPC(); return p.cyc; } function I_BSET_ID_32(p) { var s = coreNext16() & 31; var d = regs.d[p.Dd]; var m = (1 << s) >>> 0; regs.z = (d & m) == 0; var r = (d | m) >>> 0; regs.d[p.Dd] = r; //SAEF_log(("I_BSET2.L s %08x == m %08x, d %08x, r %08x", s, m, d, r)); coreSyncPC(); return p.cyc; } function I_BSET_IE_8(p) { var s = coreNext16() & 7; var a = exEAtab[p.ea](1); var d = coreGet8(a); var m = 1 << s; regs.z = (d & m) == 0; var r = d | m; corePut8(a, r); //SAEF_log(("I_BSET2.B s %08x == m %08x, d %08x, r %08x", s, m, d, r)); coreSyncPC(); return p.cyc; } function I_BTST_DD_32(p) { var s = regs.d[p.Dn] & 31; var d = regs.d[p.Dd]; var m = (1 << s) >>> 0; regs.z = (d & m) == 0; //SAEF_log(("I_BTST1.L s %08x == m %08x, d %08x, zero %d", s, m, d, regs.z?1:0)); coreSyncPC(); return p.cyc; } function I_BTST_DE_8(p) { var s = regs.d[p.Dn] & 7; var d = ldEA8tab[p.ea](); var m = 1 << s; regs.z = (d & m) == 0; //SAEF_log(("I_BTST1.B s %08x == m %08x, d %08x, zero %d", s, m, d, regs.z?1:0)); coreSyncPC(); return p.cyc; } function I_BTST_ID_32(p) { var s = coreNext16() & 31; var d = regs.d[p.Dd]; var m = (1 << s) >>> 0; regs.z = (d & m) == 0; //SAEF_log(("I_BTST2.L s %08x == m %08x, d %08x, zero %d", s, m, d, regs.z?1:0)); coreSyncPC(); return p.cyc; } function I_BTST_IE_8(p) { var s = coreNext16() & 7; var d = ldEA8tab[p.ea](); var m = 1 << s; regs.z = (d & m) == 0; //SAEF_log(("I_BTST2.B s %08x == m %08x, d %08x, zero %d", s, m, d, regs.z?1:0)); coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* Bitfield >= 68020 (ported from WinUAE) */ function I_BFXXX(p) { var ext = coreNext16(); var offset = (ext & 0x800) ? regs.d[(ext >> 6) & 7] : (ext >> 6) & 0x1f; var width = (ext & 0x20) ? regs.d[ext & 7] & 0x1f : ext & 0x1f; if (width == 0) width = 32; var tmp, bdata = [0,0]; if (p.ea >> 3 == 0) { tmp = regs.d[p.ea & 7]; offset &= 0x1f; tmp = ((tmp << offset) | (tmp >>> (32 - offset))) >>> 0; bdata[0] = (tmp & ((1 << (32 - width)) - 1)) >>> 0; } else { if (offset & 0x80000000) offset -= 0x100000000; addr = exEAtab[p.ea](1); if (offset) addr += Math.truncate(offset / 8); var bf = getBitfield(addr, Math.abs(offset), width); tmp = bf[0]; bdata = bf[1]; } regs.n = (tmp & 0x80000000) != 0; if (p.id == ID_BFEXTS) tmp >>= (32 - width); /* having fun with javascript signed-shift feature */ else tmp >>>= (32 - width); regs.z = tmp == 0; regs.v = false; regs.c = false; switch (p.id) { case ID_BFTST: break; case ID_BFEXTU: case ID_BFEXTS: regs.d[(ext >> 12) & 7] = tmp; break; case ID_BFCHG: tmp = (tmp ^ (0xffffffff >>> (32 - width))) >>> 0; break; case ID_BFCLR: tmp = 0; break; case ID_BFFFO: { var mask = (1 << (width - 1)) >>> 0; while (mask) { if (tmp & mask) break; mask >>>= 1; offset++; }} if (offset < 0) offset += 0x100000000; regs.d[(ext >> 12) & 7] = offset; break; case ID_BFSET: tmp = 0xffffffff >>> (32 - width); break; case ID_BFINS: tmp = regs.d[(ext >> 12) & 7] & (0xffffffff >>> (32 - width)); regs.n = (tmp & (1 << (width - 1))) != 0; regs.z = tmp == 0; break; } if (p.id == ID_BFCHG || p.id == ID_BFCLR || p.id == ID_BFSET || p.id == ID_BFINS) { if (p.ea >> 3 == 0) { tmp = bdata[0] | (tmp << (32 - width)); regs.d[p.ea & 7] = (tmp >>> offset) | (tmp << (32 - offset)); } else { putBitfield(addr, Math.abs(offset), width, bdata, tmp); } } /*if (p.ea >> 3 == 0) SAEF_log(("I_%s at D%d Do %d Dw %d {%d:%d} | s %08x data %08x:%08x | N=%d Z=%d", bfName(p.id), p.ea&7, (ext & 0x800)?1:0,(ext & 0x20)?1:0, offset,width, tmp,bdata[0],bdata[1], regs.n?1:0, regs.z?1:0)); else SAEF_log(("I_%s at %08x Do %d Dw %d {%d:%d} | s %08x data %08x:%08x | N=%d Z=%d", bfName(p.id), addr, (ext & 0x800)?1:0,(ext & 0x20)?1:0, offset,width, tmp,bdata[0],bdata[1], regs.n?1:0, regs.z?1:0)); */ coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* Binary-Coded Decimal */ function I_ABCD_D(p) { var s = regs.d[p.Ry] & 0xff; var d = regs.d[p.Rx] & 0xff; var lo = (s & 0x0f) + (d & 0x0f) + (regs.x?1:0); var hi = (s & 0xf0) + (d & 0xf0); var r = hi + lo; if (lo > 9) r += 6; if ((r & 0x3f0) > 0x90) { r = (r + 0x60) & 0xff; regs.x = regs.c = true; } else regs.x = regs.c = false; if (r) regs.z = false; //n,v undef regs.d[p.Rx] = (regs.d[p.Rx] & 0xffffff00) | r; //SAEF_log(("I_ABCD_D.B %02x + %02x = %02x carry %d", s,d,r,regs.c?1:0)); coreSyncPC(); return p.cyc; } function I_ABCD_A(p) { regs.a[p.Ry] -= aIncDec[1][p.Ry]; var s = coreGet8(regs.a[p.Ry]); regs.a[p.Rx] -= aIncDec[1][p.Rx]; var d = coreGet8(regs.a[p.Rx]); var lo = (s & 0x0f) + (d & 0x0f) + (regs.x?1:0); var hi = (s & 0xf0) + (d & 0xf0); var r = hi + lo; if (lo > 9) r += 6; if ((r & 0x3f0) > 0x90) { r = (r + 0x60) & 0xff; regs.x = regs.c = true; } else regs.x = regs.c = false; if (r) regs.z = false; //n,v undef corePut8(regs.a[p.Rx], r); //SAEF_log(("I_ABCD_A.B %02x + %02x = %02x carry %d", s,d,r,regs.c?1:0)); coreSyncPC(); return p.cyc; } function I_SBCD_D(p) { var s = regs.d[p.Rx] & 0xff; var d = regs.d[p.Ry] & 0xff; var lo = (d & 0x0f) - (s & 0x0f) - (regs.x?1:0); var hi = (d & 0xf0) - (s & 0xf0); var r = hi + lo, bcd = 0; if (lo & 0xf0) { r -= 6; bcd = 6; }; if ((((d & 0xff) - (s & 0xff) - (regs.x?1:0)) & 0x100) > 0xff) r = (r - 0x60) & 0xff; regs.x = regs.c = (((d & 0xff) - (s & 0xff) - bcd - (regs.x?1:0)) & 0x300) > 0xff; if (r) regs.z = false; //n,v undef regs.d[p.Ry] = (regs.d[p.Ry] & 0xffffff00) | r; //SAEF_log(("I_SBCD_D.B %02x - %02x = %02x carry %d", d,s,r,regs.c?1:0)); coreSyncPC(); return p.cyc; } function I_SBCD_A(p) { regs.a[p.Rx] -= aIncDec[1][p.Rx]; var s = coreGet8(regs.a[p.Rx]); regs.a[p.Ry] -= aIncDec[1][p.Ry]; var d = coreGet8(regs.a[p.Ry]); var lo = (d & 0x0f) - (s & 0x0f) - (regs.x?1:0); var hi = (d & 0xf0) - (s & 0xf0); var r = hi + lo, bcd = 0; if (lo & 0xf0) { r -= 6; bcd = 6; }; if ((((d & 0xff) - (s & 0xff) - (regs.x?1:0)) & 0x100) > 0xff) r = (r - 0x60) & 0xff; regs.x = regs.c = (((d & 0xff) - (s & 0xff) - bcd - (regs.x?1:0)) & 0x300) > 0xff; if (r) regs.z = false; //n,v undef corePut8(regs.a[p.Ry], r); //SAEF_log(("I_SBCD_A.B %02x - %02x = %02x carry %d", d,s,r,regs.c?1:0)); coreSyncPC(); return p.cyc; } function I_NBCD_D(p) { var d = regs.d[p.Dd] & 0xff; var lo = -(d & 0x0f) - (regs.x?1:0); var hi = -(d & 0xf0); if (lo > 9) { lo -= 6; } var r = hi + lo; if ((r & 0x1f0) > 0x90) { r = (r - 0x60) & 0xff; regs.x = regs.c = true; } else regs.x = regs.c = false; if (r) regs.z = false; //n,v undef regs.d[p.Dd] = (regs.d[p.Dd] & 0xffffff00) | r; //SAEF_log(("I_NBCD_D.B 0 - %02x = %02x carry %d", d,r,regs.c?1:0)); coreSyncPC(); return p.cyc; } function I_NBCD_E(p) { var a = exEAtab[p.ea](1); var d = coreGet8(a); var lo = -(d & 0x0f) - (regs.x?1:0); var hi = -(d & 0xf0); if (lo > 9) { lo -= 6; } var r = hi + lo; if ((r & 0x1f0) > 0x90) { r = (r - 0x60) & 0xff; regs.x = regs.c = true; } else regs.x = regs.c = false; if (r) regs.z = false; //n,v undef corePut8(a, r); //SAEF_log(("I_NBCD_E.B 0 - %02x = %02x carry %d", d,r,regs.c?1:0)); coreSyncPC(); return p.cyc; } function I_PACK_D(p) { /* >= 68020 */ var adj = coreNext16(); var s = (regs.d[p.Rx] & 0xffff) + adj; if (s > 0xffff) s -= 0x10000; var d = ((s >> 4) & 0xf0) | (s & 0xf); regs.d[p.Ry] = (regs.d[p.Ry] & 0xffffff00) | d; //SAEF_log(("I_PACK D%d,D%d,#%04x | %04x -> %02x", p.Rx,p.Ry,adj, s,d)); //ccna coreSyncPC(); return p.cyc; } function I_PACK_A(p) { /* >= 68020 */ var adj = coreNext16(); regs.a[p.Rx] -= aIncDec[1][p.Rx]; var s_hi = coreGet8(regs.a[p.Rx]); regs.a[p.Rx] -= aIncDec[1][p.Rx]; var s_lo = coreGet8(regs.a[p.Rx]); var s = (((s_hi & 0xf) << 8) | (s_lo & 0xf)) + adj; if (s > 0xffff) s -= 0x10000; var d = (((s >> 4) & 0xf0) | (s & 0xf)); regs.a[p.Ry] -= aIncDec[1][p.Ry]; corePut8(regs.a[p.Ry], d); //SAEF_log(("I_PACK -(A%d),-(A%d),#%04x | %04x -> %02x", p.Rx,p.Ry,adj, s,d)); //ccna coreSyncPC(); return p.cyc; } function I_UNPK_D(p) { /* >= 68020 */ var adj = coreNext16(); var s = regs.d[p.Rx] & 0xffff; var d = (((s << 4) & 0xf00) | (s & 0xf)) + adj; if (d > 0xffff) d -= 0x10000; regs.d[p.Ry] = (regs.d[p.Ry] & 0xffff0000) | d; //SAEF_log(("I_UNPK D%d,D%d,#%04x | %02x -> %04x", p.Rx,p.Ry,adj, s&0xff,d)); //ccna coreSyncPC(); return p.cyc; } function I_UNPK_A(p) { /* >= 68020 */ var adj = coreNext16(); regs.a[p.Rx] -= aIncDec[1][p.Rx]; var s = coreGet8(regs.a[p.Rx]); var d = (((s << 4) & 0xf00) | (s & 0xf)) + adj; if (d > 0xffff) d -= 0x10000; regs.a[p.Ry] -= aIncDec[1][p.Ry]; corePut8(regs.a[p.Ry], d >> 8); regs.a[p.Ry] -= aIncDec[1][p.Ry]; corePut8(regs.a[p.Ry], d & 0xff); //SAEF_log(("I_UNPK -(A%d),-(A%d),#%04x | %02x -> %04x", p.Rx,p.Ry,adj, s,d)); //ccna coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* Program Control */ function I_Bcc(p) { var pc = coreGetPC(); var dp; if (p.dp == 0) dp = coreNext16(); else if (p.dp == 255) dp = coreNext32(); /* 68020 only*/ if (ccTab[p.cc]()) { if (p.dp == 0) pc = add32(pc, extWord(dp)); else if (p.dp == 255) pc = add32(pc, dp); else pc = add32(pc, extByte(p.dp)); //SAEF_log(("I_Bcc pc $%08x", pc)); if (pc & 1) return coreException3i(p.op, pc); coreSetPC(pc); return p.cycTaken; } //ccna coreSyncPC(); return p.cyc; } function I_DBcc(p) { var pc = coreGetPC(); var dp = coreNext16(); var cyc; if (!ccTab[p.cc]()) { var dr = (regs.d[p.Dn] & 0xffff) - 1; if (dr < 0) dr += 0x10000; regs.d[p.Dn] = (regs.d[p.Dn] & 0xffff0000) | dr; if (dr != 0xffff) { pc = add32(pc, extWord(dp)); if (pc & 1) return coreException3i(p.op, pc); coreSetPC(pc); return p.cyc; } cyc = p.cycNotTakenFalse; } else cyc = p.cycNotTakenTrue; //ccna coreSyncPC(); return cyc; } function I_Scc(p) { var rdd = (p.ea >> 3) == 0; var isTrue = ccTab[p.cc](); if (rdd) { var Dn = p.ea & 7; regs.d[Dn] = (regs.d[Dn] & 0xffffff00) | (isTrue ? 0xff : 0x00); } else { var a = exEAtab[p.ea](1); /* page 4-173: In the MC68000 and MC68008 a memory location is read before it is cleared. */ if (model < 68020) { var foo = coreGet8(a); } corePut8(a, isTrue ? 0xff : 0x00); } //ccna //SAEF_log(("I_S%s, cc %d, ccTrue %d", ccNames[p.cc], p.cc, isTrue?1:0)); coreSyncPC(); return isTrue ? (rdd ? p.cycTrue : p.cyc) : (rdd ? p.cycFalse : p.cyc); } function I_BRA(p) { var dp, pc = coreGetPC(); if (p.dp == 0) dp = extWord(coreNext16()); else if (p.dp == 255) dp = coreNext32(); /* 68020 only */ else dp = extByte(p.dp); pc = add32(pc, dp); if (pc & 1) return coreException3i(p.op, pc); coreSetPC(pc); //ccna return p.cyc; } function I_BSR(p) { var dp, pc = coreGetPC(); if (p.dp == 0) dp = extWord(coreNext16()); else if (p.dp == 255) dp = coreNext32(); /* 68020 only */ else dp = extByte(p.dp); pc = add32(pc, dp); if (pc & 1) return coreException3i(p.op, pc); //SAEF_log(("I_BSR $%08x -> $%08x", coreGetPC(), pc)); stackPut32(coreGetPC()); coreSetPC(pc); //ccna return p.cyc; } function I_JMP(p) { var pc = exEAtab[p.ea](4); if (pc & 1) return coreException3i(p.op, pc); coreSetPC(pc); //ccna //SAEF_log(("I_JMP $%08x", pc)); return p.cyc; } function I_JSR(p) { var pc = exEAtab[p.ea](4); if (pc & 1) return coreException3i(p.op, pc); stackPut32(coreGetPC()); coreSetPC(pc); //ccna //SAEF_log(("I_JSR $%08x", pc)); return p.cyc; } function I_NOP(p) { //SAEF_log("I_NOP"); coreSyncPC(); return p.cyc; } function I_RTD(p) { /* >= 68010 */ var pc = stackGet32(); var dp = coreNext16(); pc = add32(pc, extWord(dp)); //SAEF_log(("I_RTD oldpc $%08x newpc $%08x dp %d", regs.pc, pc, castWord(dp))); if (pc & 1) return coreException3i(p.op, pc); coreSetPC(pc); //ccna return p.cyc; } function I_RTR(p) { var ccr = stackGet16() & 0xff; var pc = stackGet32(); coreSetCCR(ccr); //SAEF_log(("I_RTR crr $%04x pc $%08x", crr, pc)); if (pc & 1) return coreException3i(p.op, pc); coreSetPC(pc); return p.cyc; } function I_RTS(p) { var pc = stackGet32(); //SAEF_log("I_RTS regs.pc $%08x newpc $%08x", regs.pc, pc); if (pc & 1) return coreException3i(p.op, pc); coreSetPC(pc); //ccna return p.cyc; } function I_TST_8(p) { var r = ldEA8tab[p.ea](); flgLogical(r, p.zm); //SAEF_log(("I_TST.B r $%08x", r)); coreSyncPC(); return p.cyc; } function I_TST_16(p) { var r = ldEA16tab[p.ea](); flgLogical(r, p.zm); //SAEF_log(("I_TST.W r $%08x", r)); coreSyncPC(); return p.cyc; } function I_TST_32(p) { var r = ldEA32tab[p.ea](); flgLogical(r, p.zm); //SAEF_log(("I_TST.L r $%08x", r)); coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* System Control - CCR */ function I_ANDI_CCR(p) { var s = coreNext16() & 0xff; var d = coreGetCCR(); var r = s & d; coreSetCCR(r); //SAEF_log(("I_ANDI_CCR.B val $%02x, old $%02x new $%02x", s, d, r)); coreSyncPC(); return p.cyc; } function I_EORI_CCR(p) { var s = coreNext16() & 0xff; var d = coreGetCCR(); var r = s ^ d; coreSetCCR(r); //SAEF_log(("I_EORI_CCR.B val $%02x, old $%02x new $%02x", s, d, r)); coreSyncPC(); return p.cyc; } function I_ORI_CCR(p) { var s = coreNext16() & 0xff; var d = coreGetCCR(); var r = s | d; coreSetCCR(r); //SAEF_log(("I_ORI_CCR.B val $%02x, old $%02x new $%02x", s, d, r)); coreSyncPC(); return p.cyc; } function I_MOVE_2CCR(p) { var ccr = ldEA16tab[p.ea]() & 0xff; //SAEF_log(("I_MOVE_2CCR.W old $%02x new $%02x", coreGetCCR(), ccr)); coreSyncPC(); coreSetCCR(ccr); return p.cyc; } function I_MOVE_CCR2(p) { /* >= 68010 */ var ccr = coreGetCCR(); stEA16tab[p.ea](ccr); //SAEF_log(("I_MOVE_CCR2.W $%02x", ccr)); coreSyncPC(); //ccna return p.cyc; } /*-----------------------------------------------------------------------*/ /* System Control - SR */ function I_ANDI_SR(p) { if (regs.s) { var s = coreNext16(); var d = coreGetSR(); var r = s & d; //SAEF_log(("I_ANDI_SR.W val $%04x, old $%04x new $%04x", s, d, r)); coreSetSR(r); coreSyncPC(); //ccna return p.cyc; } else { //SAEF_log("I_ANDI_SR PRIVILIG VIOLATION"); //coreClrPC(); return coreException(8); } } function I_EORI_SR(p) { if (regs.s) { var s = coreNext16(); var d = coreGetSR(); var r = s ^ d; //SAEF_log(("I_EORI_SR.W val $%04x, old $%04x new $%04x", s, d, r)); coreSetSR(r); coreSyncPC(); //ccna return p.cyc; } else { //SAEF_log("I_EORI_SR PRIVILIG VIOLATION"); //coreClrPC(); return coreException(8); } } function I_ORI_SR(p) { if (regs.s) { var s = coreNext16(); var d = coreGetSR(); var r = s | d; //SAEF_log(("I_ORI_SR.W val $%04x, old $%04x new $%04x", s, d, r)); coreSetSR(r); coreSyncPC(); //ccna return p.cyc; } else { //SAEF_log("I_ORI_SR PRIVILIG VIOLATION"); //coreClrPC(); return coreException(8); } } function I_MOVE_2SR(p) { if (regs.s) { var sr = ldEA16tab[p.ea](); //SAEF_log(("I_MOVE_2SR.W sr $%04x", sr)); coreSetSR(sr); coreSyncPC(); //ccna return p.cyc; } else { //SAEF_log("I_MOVE_2SR PRIVILIG VIOLATION"); //coreClrPC(); return coreException(8); } } function I_MOVE_SR2(p) { if (regs.s || model == 68000) { /* This instruction is not privileged for the MC68000 and MC68008 */ var sr = coreGetSR(); //SAEF_log(("I_MOVE_SR2.W sr $%04x", sr)); stEA16tab[p.ea](sr); coreSyncPC(); //ccna return p.cyc; } else { //SAEF_log("I_MOVE_2SR PRIVILIG VIOLATION"); //coreClrPC(); return coreException(8); } } /*-----------------------------------------------------------------------*/ /* System Control - USP */ function I_MOVE_USP2A(p) { if (regs.s) { //SAEF_log(("I_MOVE_USP2A.L usp $%08x", regs.usp)); regs.a[p.An] = regs.usp; coreSyncPC(); return p.cyc; } else { //SAEF_log("I_MOVE_USP PRIVILIG VIOLATION"); //coreClrPC(); return coreException(8); } } function I_MOVE_A2USP(p) { if (regs.s) { regs.usp = regs.a[p.An]; //SAEF_log(("I_MOVE_A2USP.L usp $%08x", regs.usp)); coreSyncPC(); return p.cyc; } else { //SAEF_log("I_MOVE_USP PRIVILIG VIOLATION"); //coreClrPC(); return coreException(8); } } /*-----------------------------------------------------------------------*/ /* System Control - MOVEC */ function I_MOVE_2C(p) { /* >= 68010 */ var ext = coreNext16(); if (regs.s) { var cr = ext & 0xfff; if (movecValid(cr)) { if (ext & 0x8000) var data = regs.a[(ext >> 12) & 7]; else var data = regs.d[(ext >> 12) & 7]; movec2C(cr, data); //SAEF_log("I_MOVE_2C.L %s%d,%s [%08x]", (ext&0x8000)?"A":"D",(ext>>12)&7, movecRegName(cr), data); coreSyncPC(); //ccna return p.cyc; } else { //coreSyncPC(); return coreIllegal(p.op); } } else { //SAEF_log("I_MOVE_2C PRIVILIG VIOLATION"); //coreClrPC(); return coreException(8); } } function I_MOVE_C2(p) { /* >= 68010 */ var ext = coreNext16(); if (regs.s) { var cr = ext & 0xfff; if (movecValid(cr)) { var data = movecC2(cr); //SAEF_log("I_MOVE_C2.L %s,%s%d [%08x]", movecRegName(cr), (ext&0x8000)?"A":"D", (ext>>12)&7, data); if (ext & 0x8000) regs.a[(ext >> 12) & 7] = data; else regs.d[(ext >> 12) & 7] = data; coreSyncPC(); //ccna return p.cyc; } else { //coreSyncPC(); return coreIllegal(p.op); } } else { //SAEF_log("I_MOVE_C2 PRIVILIG VIOLATION"); //coreClrPC(); return coreException(8); } } /*-----------------------------------------------------------------------*/ /* System Control - MOVES, ignore the registers SFC/DFC for now */ function I_MOVES_32(p) { /* >= 68010 */ if (regs.s) { var args = coreNext16(); //SAEF_log(("I_MOVES.L %04x", args)); if (args & 0x800) { var s = (args & 0x8000) ? regs.a[(args >> 12) & 7] : regs.d[(args >> 12) & 7]; stEA32tab[p.ea](s); } else { if (args & 0x8000) regs.a[(args >> 12) & 7] = ldEA32tab[p.ea](); else regs.d[(args >> 12) & 7] = ldEA32tab[p.ea](); } //ccna coreSyncPC(); return p.cyc; } else { //SAEF_log("I_MOVES PRIVILIG VIOLATION"); //coreClrPC(); return coreException(8); } } function I_MOVES_16(p) { /* >= 68010 */ if (regs.s) { var args = coreNext16(); //SAEF_log(("I_MOVES.W %04x", args)); if (args & 0x800) { var s = (args & 0x8000) ? regs.a[(args >> 12) & 7] : regs.d[(args >> 12) & 7]; stEA16tab[p.ea](s & 0xffff); } else { var s = ldEA16tab[p.ea](); if (args & 0x8000) regs.a[(args >> 12) & 7] = extWord(s); else regs.d[(args >> 12) & 7] = (regs.d[(args >> 12) & 7] & 0xffff0000) | s; } //ccna coreSyncPC(); return p.cyc; } else { //SAEF_log("I_MOVES PRIVILIG VIOLATION"); //coreClrPC(); return coreException(8); } } function I_MOVES_8(p) { /* >= 68010 */ if (regs.s) { var args = coreNext16(); //SAEF_log(("I_MOVES.B %04x", args)); if (args & 0x800) { var s = (args & 0x8000) ? regs.a[(args >> 12) & 7] : regs.d[(args >> 12) & 7]; stEA8tab[p.ea](s & 0xff); } else { var s = ldEA8tab[p.ea](); if (args & 0x8000) regs.a[(args >> 12) & 7] = extByte(s); else regs.d[(args >> 12) & 7] = (regs.d[(args >> 12) & 7] & 0xffffff00) | s; } //ccna coreSyncPC(); return p.cyc; } else { //SAEF_log("I_MOVES PRIVILIG VIOLATION"); //coreClrPC(); return coreException(8); } } /*-----------------------------------------------------------------------*/ /* System Control */ function I_BKPT(p) { /* >= 68010, FIX not implemented */ //SAEF_log(("I_BKPT vec %d", p.v)); //ccna coreSyncPC(); return p.cyc; } function I_CHK_16(p) { var s = castWord(ldEA16tab[p.ea]()); var d = castWord(regs.d[p.Dn] & 0xffff); if (d < 0) { //SAEF_log(("I_CHK.W YES (%d < 0)", d)); regs.n = true; //coreSyncPC(); return coreException(6); } else if (d > s) { //SAEF_log(("I_CHK.W YES (%d > %d)", d, s)); regs.n = false; //coreSyncPC(); return coreException(6); } //else n undef //z v c undef //SAEF_log(("I_CHK.W no (%d >= 0 && %d < %d)", d, d, s)); coreSyncPC(); return p.cyc; } function I_CHK_32(p) { var s = castLong(ldEA32tab[p.ea]()); var d = castLong(regs.d[p.Dn]); if (d < 0) { //SAEF_log(("I_CHK.L YES (%d < 0)", d)); regs.n = true; //coreSyncPC(); return coreException(6); } else if (d > s) { //SAEF_log(("I_CHK.L YES (%d > %d)", d, s)); regs.n = false; //coreSyncPC(); return coreException(6); } //else n undef //z v c undef //SAEF_log(("I_CHK.L no (%d >= 0 && %d < %d)", d, d, s)); coreSyncPC(); return p.cyc; } function I_CHK2_32(p) { /* >= 68020 */ var ext = coreNext16(); var a = exEAtab[p.ea](4); var lb = coreGet32(a); var ub = coreGet32(a + 4); var Rn; if (ext & 0x8000) Rn = regs.a[(ext >> 12) & 7]; else { Rn = castLong(regs.d[(ext >> 12) & 7]); lb = castLong(lb); ub = castLong(ub); } regs.z = ub == Rn || lb == Rn; regs.c = lb <= ub ? Rn < lb || Rn > ub : Rn < ub || Rn > lb; // Rn > ub || Rn < lb; //n v undef //SAEF_log("I_%s2.L (%d < %d || %d > %d) -> %s", (ext&0x800)?"CHK":"CMP", Rn, lb<=ub?lb:ub, Rn, lb<=ub?ub:lb, regs.c?"true":"false"); if ((ext & 0x800) && regs.c) { //coreSyncPC(); return coreException(6); } coreSyncPC(); return p.cyc; } function I_CHK2_16(p) { /* >= 68020 */ var ext = coreNext16(); var a = exEAtab[p.ea](2); var lb = coreGet16(a); var ub = coreGet16(a + 2); var Rn; if (ext & 0x8000) { Rn = extWord(regs.a[(ext >> 12) & 7] & 0xffff); lb = extWord(lb); ub = extWord(ub); } else { Rn = castWord(regs.d[(ext >> 12) & 7] & 0xffff); lb = castWord(lb); ub = castWord(ub); } regs.z = ub == Rn || lb == Rn; regs.c = lb <= ub ? Rn < lb || Rn > ub : Rn < ub || Rn > lb; // Rn > ub || Rn < lb; //n v undef //SAEF_log("I_%s2.W (%d < %d || %d > %d) -> %s", (ext&0x800)?"CHK":"CMP", Rn, lb<=ub?lb:ub, Rn, lb<=ub?ub:lb, regs.c?"true":"false"); if ((ext & 0x800) && regs.c) { //coreSyncPC(); return coreException(6); } coreSyncPC(); return p.cyc; } function I_CHK2_8(p) { /* >= 68020 */ var ext = coreNext16(); var a = exEAtab[p.ea](1); var lb = coreGet8(a); var ub = coreGet8(a + 1); var Rn; if (ext & 0x8000) { Rn = extByte(regs.a[(ext >> 12) & 7] & 0xff); lb = extByte(lb); ub = extByte(ub); } else { Rn = castByte(regs.d[(ext >> 12) & 7] & 0xff); lb = castByte(lb); ub = castByte(ub); } regs.z = ub == Rn || lb == Rn; regs.c = lb <= ub ? Rn < lb || Rn > ub : Rn < ub || Rn > lb; // Rn > ub || Rn < lb; //n v undef //SAEF_log("I_%s2.B (%d < %d || %d > %d) -> %s", (ext&0x800)?"CHK":"CMP", Rn, lb<=ub?lb:ub, Rn, lb<=ub?ub:lb, regs.c?"true":"false"); if ((ext & 0x800) && regs.c) { //coreSyncPC(); return coreException(6); } coreSyncPC(); return p.cyc; } function I_ILLEGAL(p) { //SAEF_log("I_ILLEGAL op $%04x, pc $%08x", p.op, regs.instruction_pc); //coreSyncPC(); return coreIllegal(p.op); } function I_RESET(p) { if (regs.s) { SAEF_log("I_RESET pc $%08x", regs.instruction_pc); coreReset(); coreSyncPC(); return p.cyc; } else { //SAEF_log("I_RESET PRIVILIG VIOLATION"); //coreClrPC(); return coreException(8); } } function I_RTE(p) { if (regs.s) { var sr = stackGet16(); var pc = stackGet32(); if (model == 68000) { //SAEF_log("I_RTE000 sr $%04x newpc $%08x oldpc $%08x", sr, pc, regs.pc); } else { var fmt = stackGet16(); var frame = fmt >> 12; var offset = 0; //8 //if (frame > 1) SAEF_log("I_RTE010 fmt %04x frame %x sr $%04x newpc $%08x oldpc $%08x", fmt, frame, sr, pc, regs.pc); if (frame == 0x0) {}//regs.a[7] += offset; else if (frame == 0x1) {}//regs.a[7] += offset; else if (frame == 0x2) regs.a[7] += offset + 4; else if (frame == 0x4) regs.a[7] += offset + 8; else if (frame == 0x8) regs.a[7] += offset + 50; else if (frame == 0x9) regs.a[7] += offset + 12; else if (frame == 0xa) regs.a[7] += offset + 24; else if (frame == 0xb) regs.a[7] += offset + 84; else { regs.a[7] += offset; //coreSyncPC(); return coreException(14); } } coreSetSR(sr); if (pc & 1) return coreException3i(p.op, pc); coreSetPC(pc); return p.cyc; } else { //SAEF_log("I_RTE PRIVILEG VIOLATION"); //coreClrPC(); return coreException(8); } } function I_STOP(p) { if (regs.s) { var sr = coreNext16(); coreSetSR(sr); coreStop(); //SAEF_log("I_STOP new sr $%04x", sr); coreSyncPC(); return p.cyc; } else { //coreClrPC(); return coreException(8); } } function I_TRAP(p) { //SAEF_log(("I_TRAP coreException 32 + %d", p.v)); //ccna //coreSyncPC(); return coreException(32 + p.v); } function I_TRAPCC(p) { /* 68020 */ if (ccTab[p.cc]()) { //SAEF_log(("I_TRAP%s coreException 7 -> take", ccNames(p.cc))); stackPut32(coreGetPC()); //coreSyncPC(); return coreException(7); } //else SAEF_log(("I_TRAP%s coreException 7 -> abort", ccNames(p.cc))); //ccna coreSyncPC(); return p.cyc; } function I_TRAPCC_16(p) { /* 68020 */ var entry = coreNext16(); if (ccTab[p.cc]()) { //SAEF_log(("I_TRAP%s.W coreException 7 -> take", ccNames(p.cc))); stackPut32(coreGetPC()); //coreSyncPC(); return coreException(7); } //else SAEF_log(("I_TRAP%s.W coreException 7 -> abort", ccNames(p.cc))); //ccna coreSyncPC(); return p.cyc; } function I_TRAPCC_32(p) { /* 68020 */ var entry = coreNext32(); if (ccTab[p.cc]()) { //SAEF_log(("I_TRAP%s.L coreException 7 -> take", ccNames(p.cc))); stackPut32(coreGetPC()); //coreSyncPC(); return coreException(7); } //else SAEF_log(("I_TRAP%s.L coreException 7 -> abort", ccNames(p.cc))); //ccna coreSyncPC(); return p.cyc; } function I_TRAPV(p) { if (regs.v) { //SAEF_log("I_TRAPV coreException 7"); //coreSyncPC(); return coreException(7); } //ccna coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* Multiprocessor */ function I_CAS_32(p) { /* >= 68020 */ var ext = coreNext16(); var a = exEAtab[p.ea](4); var c = regs.d[ext & 7]; var d = coreGet32(a); var r = d - c; if (r < 0) r += 0x100000000; flgCmp(c, d, r, 0x80000000); if (regs.z) corePut32(a, regs.d[(ext >> 6) & 7]); else regs.d[ext & 7] = d; //SAEF_log(("I_CAS.L %04x", ext)); coreSyncPC(); return p.cyc; } function I_CAS_16(p) { /* >= 68020 */ var ext = coreNext16(); var a = exEAtab[p.ea](2); var c = regs.d[ext & 7] & 0xffff; var d = coreGet16(a); var r = d - c; if (r < 0) r += 0x10000; flgCmp(c, d, r, 0x8000); if (regs.z) corePut16(a, regs.d[(ext >> 6) & 7] & 0xffff); else regs.d[ext & 7] = (regs.d[ext & 7] & 0xffff0000) | d; //SAEF_log(("I_CAS.W %04x", ext)); coreSyncPC(); return p.cyc; } function I_CAS_8(p) { /* >= 68020 */ var ext = coreNext16(); var a = exEAtab[p.ea](1); var c = regs.d[ext & 7] & 0xff; var d = coreGet8(a); var r = d - c; if (r < 0) r += 0x100; flgCmp(c, d, r, 0x80); if (regs.z) corePut8(a, regs.d[(ext >> 6) & 7] & 0xff); else regs.d[ext & 7] = (regs.d[ext & 7] & 0xffffff00) | d; //SAEF_log(("I_CAS.B %04x", ext)); coreSyncPC(); return p.cyc; } function I_CAS2_32(p) { /* >= 68020 */ var ext1 = coreNext16(); var ext2 = coreNext16(); var Rn1 = (ext1 >> 12) & 7; var Rn2 = (ext2 >> 12) & 7; var Du1 = (ext1 >> 6) & 7; var Du2 = (ext2 >> 6) & 7; var Dc1 = ext1 & 7; var Dc2 = ext2 & 7; var c1 = regs.d[Dc1]; var c2 = regs.d[Dc2]; var d1 = (ext1 & 0x8000) ? coreGet32(regs.a[Rn1]) : regs.d[Rn1]; var d2 = (ext2 & 0x8000) ? coreGet32(regs.a[Rn2]) : regs.d[Rn2]; var upd = false; var r = d1 - c1; if (r < 0) r += 0x100000000; flgCmp(c1, d1, r, 0x80000000); if (regs.z) { r = d2 - c2; if (r < 0) r += 0x100000000; flgCmp(c2, d2, r, 0x80000000); upd = regs.z; } if (upd) { if (ext1 & 0x8000) corePut32(regs.a[Rn1], regs.d[Du1]); else regs.d[Rn1] = regs.d[Du1]; if (ext2 & 0x8000) corePut32(regs.a[Rn2], regs.d[Du2]); else regs.d[Rn2] = regs.d[Du2]; } else { regs.d[Dc1] = d1; regs.d[Dc2] = d2; } //SAEF_log(("I_CAS2.L %04x %04x", ext1, ext2)); coreSyncPC(); return p.cyc; } function I_CAS2_16(p) { /* >= 68020 */ var ext1 = coreNext16(); var ext2 = coreNext16(); var Rn1 = (ext1 >> 12) & 7; var Rn2 = (ext2 >> 12) & 7; var Du1 = (ext1 >> 6) & 7; var Du2 = (ext2 >> 6) & 7; var Dc1 = ext1 & 7; var Dc2 = ext2 & 7; var c1 = regs.d[Dc1] & 0xffff; var c2 = regs.d[Dc2] & 0xffff; var d1 = (ext1 & 0x8000) ? coreGet16(regs.a[Rn1]) : regs.d[Rn1] & 0xffff; var d2 = (ext2 & 0x8000) ? coreGet16(regs.a[Rn2]) : regs.d[Rn2] & 0xffff; var upd = false; var r = d1 - c1; if (r < 0) r += 0x10000; flgCmp(c1, d1, r, 0x8000); if (regs.z) { r = d2 - c2; if (r < 0) r += 0x10000; flgCmp(c2, d2, r, 0x8000); upd = regs.z; } if (upd) { if (ext1 & 0x8000) corePut16(regs.a[Rn1], regs.d[Du1] & 0xffff); else regs.d[Rn1] = (regs.d[Rn1] & 0xffff0000) | (regs.d[Du1] & 0xffff); if (ext2 & 0x8000) corePut16(regs.a[Rn2], regs.d[Du2] & 0xffff); else regs.d[Rn2] = (regs.d[Rn2] & 0xffff0000) | (regs.d[Du2] & 0xffff); } else { regs.d[Dc1] = (regs.d[Dc1] & 0xffff0000) | d1; regs.d[Dc2] = (regs.d[Dc2] & 0xffff0000) | d2; } //SAEF_log(("I_CAS2.W %04x %04x", ext1, ext2)); coreSyncPC(); return p.cyc; } function I_TAS(p) { var d = ldEA8tab[p.ea](); stEA8tab[p.ea](0x80 | d); regs.n = (d & 0x80) != 0; regs.z = d == 0; regs.v = false; regs.c = false; //SAEF_log(("I_TAS.B $%02x", d)); coreSyncPC(); return p.cyc; } /*-----------------------------------------------------------------------*/ /* 68020 only */ function I_CALLM(p) { /* FIX not implemented */ var ext = coreNext16() & 0xff; SAEF_warn("I_CALLM not implemented (ext %d)", ext); //coreSyncPC(); return coreIllegal(p.op); } function I_RTM(p) { /* FIX not implemented */ SAEF_warn("I_RTM not implemented"); //coreSyncPC(); return coreIllegal(p.op); } /*-----------------------------------------------------------------------*/ /* 68030 fake MMU */ function I_MMU(p) { if (regs.s) { var pc = coreGetPC(); var ext = coreNext16(); var a = exEAtab[p.ea](4); if (mmu_op30(pc, p.op, ext, a)) { //coreSyncPC(); return coreIllegal(p.op); } coreSyncPC(); //ccna return p.cyc; } else { //coreClrPC(); return coreException(8); } } /*-----------------------------------------------------------------------*/ /* Coprocessor 68020/68030 */ function I_cpBcc(p) { //SAEF_warn("I_cpBcc.%s not implemented, cid %d, ccc %d, pc %08x", szChr(p.z), p.cid, p.ccc, regs.instruction_pc); return coreIllegal(p.op); //ccna //return p.cyc; } function I_cpDBcc(p) { //SAEF_warn("I_cpDBcc.w not implemented, cid %d, dn %d, pc %08x", p.cid, p.dn, regs.instruction_pc); return coreIllegal(p.op); //ccna //return p.cyc; } function I_cpGEN(p) { //SAEF_warn("I_cpGEN not implemented, cid %d, ea %d(%d:%d), pc %08x", p.cid, p.ea,p.ea>>3,p.ea&7, regs.instruction_pc); return coreIllegal(p.op); //var cmd = coreNext16(); //ccna //return p.cyc; } function I_cpRESTORE(p) { //SAEF_warn("I_cpRESTORE not implemented, cid %d, pc %08x", p.cid, regs.instruction_pc); return coreIllegal(p.op); if (regs.s) { //var data = ldEA32tab[p.ea](); //ccna //return p.cyc; } else { //coreClrPC(); return coreException(8); } } function I_cpSAVE(p) { //SAEF_warn("I_cpSAVE not implemented, cid %d, pc %08x", p.cid, regs.instruction_pc); return coreIllegal(p.op); if (regs.s) { //var data = 12345; //stEA32tab[p.ea](data); //ccna //return p.cyc; } else { //coreClrPC(); return coreException(8); } } function I_cpScc(p) { //SAEF_warn("I_cpScc not implemented, cid %d, pc %08x", p.cid, regs.instruction_pc); return coreIllegal(p.op); //var data = ldEA32tab[p.ea](); //ccna //return p.cyc; } function I_cpTRAPcc(p) { //SAEF_warn("I_cpTRAPcc not implemented, cid %d, opm %d, pc %08x", p.cid, p.opm, regs.instruction_pc); return coreIllegal(p.op); //var ext coreNext16(); //var ext2 = p.opm == 2 ? coreNext16() : (p.opm == 3 ? coreNext32() : 0); //ccna //return p.cyc; } /*function I_cpXXX(p) { //var cmd = coreNext16(); SAEF_warn("I_cpXXX not implemented, cid %d, xxx %x, pc %08x", p.cid, p.xxx, regs.instruction_pc); //ccna //return p.cyc; return coreIllegal(p.op); }*/ /*-----------------------------------------------------------------------*/ /* real illegal/undefined instruction */ function ILLEGAL(op) { /*if (typeof SAER != "undefined") { SAEF_warn("ILLEGAL op $%04x", op); SAER.cpu.diss(regs.instruction_pc,0); }*/ //coreSyncPC(); return coreIllegal(op); } /*-----------------------------------------------------------------------*/ /* SECT core tables */ /*-----------------------------------------------------------------------*/ /* Condition-code table */ function mkCCTab() { var i = 0; ccTab = new Array(16); ccTab[i++] = function() { return true; }; //T ccTab[i++] = function() { return false; }; //F ccTab[i++] = function() { return !regs.c && !regs.z; }; //HI ccTab[i++] = function() { return regs.c || regs.z; }; //LS ccTab[i++] = function() { return !regs.c; }; //CC ccTab[i++] = function() { return regs.c; }; //CS ccTab[i++] = function() { return !regs.z; }; //NE ccTab[i++] = function() { return regs.z; }; //EQ ccTab[i++] = function() { return !regs.v; }; //VC ccTab[i++] = function() { return regs.v; }; //VV ccTab[i++] = function() { return !regs.n; }; //PL ccTab[i++] = function() { return regs.n; }; //MI ccTab[i++] = function() { return regs.n == regs.v; }; //GE ccTab[i++] = function() { return regs.n != regs.v; }; //LT ccTab[i++] = function() { return !regs.z && (regs.n == regs.v); }; //GT ccTab[i ] = function() { return regs.z || (regs.n != regs.v); }; //LE } /*-----------------------------------------------------------------------*/ /* Effective-Address tables */ function exII(base, dp) { var reg = (dp >> 12) & 7; //var cycles = 0; var v; var regd = (dp & 0x8000) ? regs.a[reg] : regs.d[reg]; var scale = (dp >> 9) & 3; if ((dp & 0x800) == 0) //regd = (uae_s32)(uae_s16)regd; regd = extWord(regd & 0xffff); //regd <<= (dp >> 9) & 3; if (scale) regd = ((regd << scale) & 0xffffffff) >>> 0; if (dp & 0x100) { var outer = 0; if (dp & 0x80) base = 0; if (dp & 0x40) regd = 0; if ((dp & 0x30) == 0x20) { //base += (uae_s32)(uae_s16)coreNext16(); base = add32(base, extWord(coreNext16())); //cycles++; } if ((dp & 0x30) == 0x30) { //base += coreNext32(); base = add32(base, coreNext32()); //cycles++; } if ((dp & 0x3) == 0x2) { //outer = (uae_s32)(uae_s16)coreNext16(); outer = extWord(coreNext16()); //cycles++; } if ((dp & 0x3) == 0x3) { //outer = coreNext32(); outer = coreNext32(); //cycles++; } if ((dp & 0x4) == 0) { //base += regd; base = add32(base, regd); //cycles++; } if (dp & 0x3) { base = coreGet32(base); //cycles++; } if (dp & 0x4) { //base += regd; base = add32(base, regd); //cycles++; } //v = base + outer; v = add32(base, outer); } else { //v = base + (uae_s32)((uae_s8)dp) + regd; v = add32(add32(base, extByte(dp & 0xff)), regd); } return v; } function mkEATabs() { exEAtab = new Array(64); exEAtab[(2<<3)|0] = function() { return regs.a[0]; } //ria exEAtab[(2<<3)|1] = function() { return regs.a[1]; } exEAtab[(2<<3)|2] = function() { return regs.a[2]; } exEAtab[(2<<3)|3] = function() { return regs.a[3]; } exEAtab[(2<<3)|4] = function() { return regs.a[4]; } exEAtab[(2<<3)|5] = function() { return regs.a[5]; } exEAtab[(2<<3)|6] = function() { return regs.a[6]; } exEAtab[(2<<3)|7] = function() { return regs.a[7]; } exEAtab[(3<<3)|0] = function(z) { var a = regs.a[0]; regs.a[0] += aIncDec[z][0]; return a; }; //ripo exEAtab[(3<<3)|1] = function(z) { var a = regs.a[1]; regs.a[1] += aIncDec[z][1]; return a; }; exEAtab[(3<<3)|2] = function(z) { var a = regs.a[2]; regs.a[2] += aIncDec[z][2]; return a; }; exEAtab[(3<<3)|3] = function(z) { var a = regs.a[3]; regs.a[3] += aIncDec[z][3]; return a; }; exEAtab[(3<<3)|4] = function(z) { var a = regs.a[4]; regs.a[4] += aIncDec[z][4]; return a; }; exEAtab[(3<<3)|5] = function(z) { var a = regs.a[5]; regs.a[5] += aIncDec[z][5]; return a; }; exEAtab[(3<<3)|6] = function(z) { var a = regs.a[6]; regs.a[6] += aIncDec[z][6]; return a; }; exEAtab[(3<<3)|7] = function(z) { var a = regs.a[7]; regs.a[7] += aIncDec[z][7]; return a; }; exEAtab[(4<<3)|0] = function(z) { regs.a[0] -= aIncDec[z][0]; return regs.a[0]; } //ripr exEAtab[(4<<3)|1] = function(z) { regs.a[1] -= aIncDec[z][1]; return regs.a[1]; } exEAtab[(4<<3)|2] = function(z) { regs.a[2] -= aIncDec[z][2]; return regs.a[2]; } exEAtab[(4<<3)|3] = function(z) { regs.a[3] -= aIncDec[z][3]; return regs.a[3]; } exEAtab[(4<<3)|4] = function(z) { regs.a[4] -= aIncDec[z][4]; return regs.a[4]; } exEAtab[(4<<3)|5] = function(z) { regs.a[5] -= aIncDec[z][5]; return regs.a[5]; } exEAtab[(4<<3)|6] = function(z) { regs.a[6] -= aIncDec[z][6]; return regs.a[6]; } exEAtab[(4<<3)|7] = function(z) { regs.a[7] -= aIncDec[z][7]; return regs.a[7]; } exEAtab[(5<<3)|0] = function() { return add32(regs.a[0], extWord(coreNext16())); } //rid exEAtab[(5<<3)|1] = function() { return add32(regs.a[1], extWord(coreNext16())); } exEAtab[(5<<3)|2] = function() { return add32(regs.a[2], extWord(coreNext16())); } exEAtab[(5<<3)|3] = function() { return add32(regs.a[3], extWord(coreNext16())); } exEAtab[(5<<3)|4] = function() { return add32(regs.a[4], extWord(coreNext16())); } exEAtab[(5<<3)|5] = function() { return add32(regs.a[5], extWord(coreNext16())); } exEAtab[(5<<3)|6] = function() { return add32(regs.a[6], extWord(coreNext16())); } exEAtab[(5<<3)|7] = function() { return add32(regs.a[7], extWord(coreNext16())); } exEAtab[(6<<3)|0] = function() { return exII(regs.a[0], coreNext16()); } //rii exEAtab[(6<<3)|1] = function() { return exII(regs.a[1], coreNext16()); } exEAtab[(6<<3)|2] = function() { return exII(regs.a[2], coreNext16()); } exEAtab[(6<<3)|3] = function() { return exII(regs.a[3], coreNext16()); } exEAtab[(6<<3)|4] = function() { return exII(regs.a[4], coreNext16()); } exEAtab[(6<<3)|5] = function() { return exII(regs.a[5], coreNext16()); } exEAtab[(6<<3)|6] = function() { return exII(regs.a[6], coreNext16()); } exEAtab[(6<<3)|7] = function() { return exII(regs.a[7], coreNext16()); } exEAtab[(7<<3)|0] = function() { return extWord(coreNext16()); } //absw exEAtab[(7<<3)|1] = function() { return coreNext32(); } //absl exEAtab[(7<<3)|2] = function() { return add32(coreGetPC(), extWord(coreNext16())); } //pcid exEAtab[(7<<3)|3] = function() { return exII(coreGetPC(), coreNext16()); } //pcii exEAtab[(7<<3)|4] = function() { SAEF_error("cpu.exEAtab() invalid EA 60 (7|4) (imm)"); } //imm /*-----------------------------------------------------------------------*/ ldEA8tab = new Array(64); ldEA8tab[ 0] = function() { return regs.d[0] & 0xff; } //rdd ldEA8tab[ 1] = function() { return regs.d[1] & 0xff; } ldEA8tab[ 2] = function() { return regs.d[2] & 0xff; } ldEA8tab[ 3] = function() { return regs.d[3] & 0xff; } ldEA8tab[ 4] = function() { return regs.d[4] & 0xff; } ldEA8tab[ 5] = function() { return regs.d[5] & 0xff; } ldEA8tab[ 6] = function() { return regs.d[6] & 0xff; } ldEA8tab[ 7] = function() { return regs.d[7] & 0xff; } ldEA8tab[(1<<3)|0] = function() { SAEF_error("cpu.ldEA8tab() invalid EA 8 (1|0)"); } //rda ldEA8tab[(1<<3)|1] = function() { SAEF_error("cpu.ldEA8tab() invalid EA 9 (1|1)"); } ldEA8tab[(1<<3)|2] = function() { SAEF_error("cpu.ldEA8tab() invalid EA 10 (1|2)"); } ldEA8tab[(1<<3)|3] = function() { SAEF_error("cpu.ldEA8tab() invalid EA 11 (1|3)"); } ldEA8tab[(1<<3)|4] = function() { SAEF_error("cpu.ldEA8tab() invalid EA 12 (1|4)"); } ldEA8tab[(1<<3)|5] = function() { SAEF_error("cpu.ldEA8tab() invalid EA 13 (1|5)"); } ldEA8tab[(1<<3)|6] = function() { SAEF_error("cpu.ldEA8tab() invalid EA 14 (1|6)"); } ldEA8tab[(1<<3)|7] = function() { SAEF_error("cpu.ldEA8tab() invalid EA 15 (1|7)"); } ldEA8tab[(2<<3)|0] = function() { return coreGet8(regs.a[0]); } //ria ldEA8tab[(2<<3)|1] = function() { return coreGet8(regs.a[1]); } ldEA8tab[(2<<3)|2] = function() { return coreGet8(regs.a[2]); } ldEA8tab[(2<<3)|3] = function() { return coreGet8(regs.a[3]); } ldEA8tab[(2<<3)|4] = function() { return coreGet8(regs.a[4]); } ldEA8tab[(2<<3)|5] = function() { return coreGet8(regs.a[5]); } ldEA8tab[(2<<3)|6] = function() { return coreGet8(regs.a[6]); } ldEA8tab[(2<<3)|7] = function() { return coreGet8(regs.a[7]); } ldEA8tab[(3<<3)|0] = function() { var a = regs.a[0]; regs.a[0] += 1; return coreGet8(a); } //ripo ldEA8tab[(3<<3)|1] = function() { var a = regs.a[1]; regs.a[1] += 1; return coreGet8(a); } ldEA8tab[(3<<3)|2] = function() { var a = regs.a[2]; regs.a[2] += 1; return coreGet8(a); } ldEA8tab[(3<<3)|3] = function() { var a = regs.a[3]; regs.a[3] += 1; return coreGet8(a); } ldEA8tab[(3<<3)|4] = function() { var a = regs.a[4]; regs.a[4] += 1; return coreGet8(a); } ldEA8tab[(3<<3)|5] = function() { var a = regs.a[5]; regs.a[5] += 1; return coreGet8(a); } ldEA8tab[(3<<3)|6] = function() { var a = regs.a[6]; regs.a[6] += 1; return coreGet8(a); } ldEA8tab[(3<<3)|7] = function() { var a = regs.a[7]; regs.a[7] += 2; return coreGet8(a); } ldEA8tab[(4<<3)|0] = function() { regs.a[0] -= 1; return coreGet8(regs.a[0]); } //ripr ldEA8tab[(4<<3)|1] = function() { regs.a[1] -= 1; return coreGet8(regs.a[1]); } ldEA8tab[(4<<3)|2] = function() { regs.a[2] -= 1; return coreGet8(regs.a[2]); } ldEA8tab[(4<<3)|3] = function() { regs.a[3] -= 1; return coreGet8(regs.a[3]); } ldEA8tab[(4<<3)|4] = function() { regs.a[4] -= 1; return coreGet8(regs.a[4]); } ldEA8tab[(4<<3)|5] = function() { regs.a[5] -= 1; return coreGet8(regs.a[5]); } ldEA8tab[(4<<3)|6] = function() { regs.a[6] -= 1; return coreGet8(regs.a[6]); } ldEA8tab[(4<<3)|7] = function() { regs.a[7] -= 2; return coreGet8(regs.a[7]); } ldEA8tab[(5<<3)|0] = function() { return coreGet8(add32(regs.a[0], extWord(coreNext16()))); } //rid ldEA8tab[(5<<3)|1] = function() { return coreGet8(add32(regs.a[1], extWord(coreNext16()))); } ldEA8tab[(5<<3)|2] = function() { return coreGet8(add32(regs.a[2], extWord(coreNext16()))); } ldEA8tab[(5<<3)|3] = function() { return coreGet8(add32(regs.a[3], extWord(coreNext16()))); } ldEA8tab[(5<<3)|4] = function() { return coreGet8(add32(regs.a[4], extWord(coreNext16()))); } ldEA8tab[(5<<3)|5] = function() { return coreGet8(add32(regs.a[5], extWord(coreNext16()))); } ldEA8tab[(5<<3)|6] = function() { return coreGet8(add32(regs.a[6], extWord(coreNext16()))); } ldEA8tab[(5<<3)|7] = function() { return coreGet8(add32(regs.a[7], extWord(coreNext16()))); } ldEA8tab[(6<<3)|0] = function() { return coreGet8(exII(regs.a[0], coreNext16())); } //rii ldEA8tab[(6<<3)|1] = function() { return coreGet8(exII(regs.a[1], coreNext16())); } ldEA8tab[(6<<3)|2] = function() { return coreGet8(exII(regs.a[2], coreNext16())); } ldEA8tab[(6<<3)|3] = function() { return coreGet8(exII(regs.a[3], coreNext16())); } ldEA8tab[(6<<3)|4] = function() { return coreGet8(exII(regs.a[4], coreNext16())); } ldEA8tab[(6<<3)|5] = function() { return coreGet8(exII(regs.a[5], coreNext16())); } ldEA8tab[(6<<3)|6] = function() { return coreGet8(exII(regs.a[6], coreNext16())); } ldEA8tab[(6<<3)|7] = function() { return coreGet8(exII(regs.a[7], coreNext16())); } ldEA8tab[(7<<3)|0] = function() { return coreGet8(extWord(coreNext16())); } //absw ldEA8tab[(7<<3)|1] = function() { return coreGet8(coreNext32()); } //absl ldEA8tab[(7<<3)|2] = function() { return coreGet8(add32(coreGetPC(), extWord(coreNext16()))); } //pcid ldEA8tab[(7<<3)|3] = function() { return coreGet8(exII(coreGetPC(), coreNext16())); } //pcii ldEA8tab[(7<<3)|4] = function() { return coreNext16() & 0xff; } //imm ldEA16tab = new Array(64); ldEA16tab[ 0] = function() { return regs.d[0] & 0xffff; } //rdd ldEA16tab[ 1] = function() { return regs.d[1] & 0xffff; } ldEA16tab[ 2] = function() { return regs.d[2] & 0xffff; } ldEA16tab[ 3] = function() { return regs.d[3] & 0xffff; } ldEA16tab[ 4] = function() { return regs.d[4] & 0xffff; } ldEA16tab[ 5] = function() { return regs.d[5] & 0xffff; } ldEA16tab[ 6] = function() { return regs.d[6] & 0xffff; } ldEA16tab[ 7] = function() { return regs.d[7] & 0xffff; } ldEA16tab[(1<<3)|0] = function() { return regs.a[0] & 0xffff; } //rda ldEA16tab[(1<<3)|1] = function() { return regs.a[1] & 0xffff; } ldEA16tab[(1<<3)|2] = function() { return regs.a[2] & 0xffff; } ldEA16tab[(1<<3)|3] = function() { return regs.a[3] & 0xffff; } ldEA16tab[(1<<3)|4] = function() { return regs.a[4] & 0xffff; } ldEA16tab[(1<<3)|5] = function() { return regs.a[5] & 0xffff; } ldEA16tab[(1<<3)|6] = function() { return regs.a[6] & 0xffff; } ldEA16tab[(1<<3)|7] = function() { return regs.a[7] & 0xffff; } ldEA16tab[(2<<3)|0] = function() { return coreGet16(regs.a[0]); } //ria ldEA16tab[(2<<3)|1] = function() { return coreGet16(regs.a[1]); } ldEA16tab[(2<<3)|2] = function() { return coreGet16(regs.a[2]); } ldEA16tab[(2<<3)|3] = function() { return coreGet16(regs.a[3]); } ldEA16tab[(2<<3)|4] = function() { return coreGet16(regs.a[4]); } ldEA16tab[(2<<3)|5] = function() { return coreGet16(regs.a[5]); } ldEA16tab[(2<<3)|6] = function() { return coreGet16(regs.a[6]); } ldEA16tab[(2<<3)|7] = function() { return coreGet16(regs.a[7]); } ldEA16tab[(3<<3)|0] = function() { var a = regs.a[0]; regs.a[0] += 2; return coreGet16(a); } //ripo ldEA16tab[(3<<3)|1] = function() { var a = regs.a[1]; regs.a[1] += 2; return coreGet16(a); } ldEA16tab[(3<<3)|2] = function() { var a = regs.a[2]; regs.a[2] += 2; return coreGet16(a); } ldEA16tab[(3<<3)|3] = function() { var a = regs.a[3]; regs.a[3] += 2; return coreGet16(a); } ldEA16tab[(3<<3)|4] = function() { var a = regs.a[4]; regs.a[4] += 2; return coreGet16(a); } ldEA16tab[(3<<3)|5] = function() { var a = regs.a[5]; regs.a[5] += 2; return coreGet16(a); } ldEA16tab[(3<<3)|6] = function() { var a = regs.a[6]; regs.a[6] += 2; return coreGet16(a); } ldEA16tab[(3<<3)|7] = function() { var a = regs.a[7]; regs.a[7] += 2; return coreGet16(a); } ldEA16tab[(4<<3)|0] = function() { regs.a[0] -= 2; return coreGet16(regs.a[0]); } //ripr ldEA16tab[(4<<3)|1] = function() { regs.a[1] -= 2; return coreGet16(regs.a[1]); } ldEA16tab[(4<<3)|2] = function() { regs.a[2] -= 2; return coreGet16(regs.a[2]); } ldEA16tab[(4<<3)|3] = function() { regs.a[3] -= 2; return coreGet16(regs.a[3]); } ldEA16tab[(4<<3)|4] = function() { regs.a[4] -= 2; return coreGet16(regs.a[4]); } ldEA16tab[(4<<3)|5] = function() { regs.a[5] -= 2; return coreGet16(regs.a[5]); } ldEA16tab[(4<<3)|6] = function() { regs.a[6] -= 2; return coreGet16(regs.a[6]); } ldEA16tab[(4<<3)|7] = function() { regs.a[7] -= 2; return coreGet16(regs.a[7]); } ldEA16tab[(5<<3)|0] = function() { return coreGet16(add32(regs.a[0], extWord(coreNext16()))); } //rid ldEA16tab[(5<<3)|1] = function() { return coreGet16(add32(regs.a[1], extWord(coreNext16()))); } ldEA16tab[(5<<3)|2] = function() { return coreGet16(add32(regs.a[2], extWord(coreNext16()))); } ldEA16tab[(5<<3)|3] = function() { return coreGet16(add32(regs.a[3], extWord(coreNext16()))); } ldEA16tab[(5<<3)|4] = function() { return coreGet16(add32(regs.a[4], extWord(coreNext16()))); } ldEA16tab[(5<<3)|5] = function() { return coreGet16(add32(regs.a[5], extWord(coreNext16()))); } ldEA16tab[(5<<3)|6] = function() { return coreGet16(add32(regs.a[6], extWord(coreNext16()))); } ldEA16tab[(5<<3)|7] = function() { return coreGet16(add32(regs.a[7], extWord(coreNext16()))); } ldEA16tab[(6<<3)|0] = function() { return coreGet16(exII(regs.a[0], coreNext16())); } //rii ldEA16tab[(6<<3)|1] = function() { return coreGet16(exII(regs.a[1], coreNext16())); } ldEA16tab[(6<<3)|2] = function() { return coreGet16(exII(regs.a[2], coreNext16())); } ldEA16tab[(6<<3)|3] = function() { return coreGet16(exII(regs.a[3], coreNext16())); } ldEA16tab[(6<<3)|4] = function() { return coreGet16(exII(regs.a[4], coreNext16())); } ldEA16tab[(6<<3)|5] = function() { return coreGet16(exII(regs.a[5], coreNext16())); } ldEA16tab[(6<<3)|6] = function() { return coreGet16(exII(regs.a[6], coreNext16())); } ldEA16tab[(6<<3)|7] = function() { return coreGet16(exII(regs.a[7], coreNext16())); } ldEA16tab[(7<<3)|0] = function() { return coreGet16(extWord(coreNext16())); } //absw ldEA16tab[(7<<3)|1] = function() { return coreGet16(coreNext32()); } //absl ldEA16tab[(7<<3)|2] = function() { return coreGet16(add32(coreGetPC(), extWord(coreNext16()))); } //pcid ldEA16tab[(7<<3)|3] = function() { return coreGet16(exII(coreGetPC(), coreNext16())); } //pcii ldEA16tab[(7<<3)|4] = function() { return coreNext16(); } //imm ldEA32tab = new Array(64); ldEA32tab[ 0] = function() { return regs.d[0]; } //rdd ldEA32tab[ 1] = function() { return regs.d[1]; } ldEA32tab[ 2] = function() { return regs.d[2]; } ldEA32tab[ 3] = function() { return regs.d[3]; } ldEA32tab[ 4] = function() { return regs.d[4]; } ldEA32tab[ 5] = function() { return regs.d[5]; } ldEA32tab[ 6] = function() { return regs.d[6]; } ldEA32tab[ 7] = function() { return regs.d[7]; } ldEA32tab[(1<<3)|0] = function() { return regs.a[0]; } //rda ldEA32tab[(1<<3)|1] = function() { return regs.a[1]; } ldEA32tab[(1<<3)|2] = function() { return regs.a[2]; } ldEA32tab[(1<<3)|3] = function() { return regs.a[3]; } ldEA32tab[(1<<3)|4] = function() { return regs.a[4]; } ldEA32tab[(1<<3)|5] = function() { return regs.a[5]; } ldEA32tab[(1<<3)|6] = function() { return regs.a[6]; } ldEA32tab[(1<<3)|7] = function() { return regs.a[7]; } ldEA32tab[(2<<3)|0] = function() { return coreGet32(regs.a[0]); } //ria ldEA32tab[(2<<3)|1] = function() { return coreGet32(regs.a[1]); } ldEA32tab[(2<<3)|2] = function() { return coreGet32(regs.a[2]); } ldEA32tab[(2<<3)|3] = function() { return coreGet32(regs.a[3]); } ldEA32tab[(2<<3)|4] = function() { return coreGet32(regs.a[4]); } ldEA32tab[(2<<3)|5] = function() { return coreGet32(regs.a[5]); } ldEA32tab[(2<<3)|6] = function() { return coreGet32(regs.a[6]); } ldEA32tab[(2<<3)|7] = function() { return coreGet32(regs.a[7]); } ldEA32tab[(3<<3)|0] = function() { var a = regs.a[0]; regs.a[0] += 4; return coreGet32(a); } //ripo ldEA32tab[(3<<3)|1] = function() { var a = regs.a[1]; regs.a[1] += 4; return coreGet32(a); } ldEA32tab[(3<<3)|2] = function() { var a = regs.a[2]; regs.a[2] += 4; return coreGet32(a); } ldEA32tab[(3<<3)|3] = function() { var a = regs.a[3]; regs.a[3] += 4; return coreGet32(a); } ldEA32tab[(3<<3)|4] = function() { var a = regs.a[4]; regs.a[4] += 4; return coreGet32(a); } ldEA32tab[(3<<3)|5] = function() { var a = regs.a[5]; regs.a[5] += 4; return coreGet32(a); } ldEA32tab[(3<<3)|6] = function() { var a = regs.a[6]; regs.a[6] += 4; return coreGet32(a); } ldEA32tab[(3<<3)|7] = function() { var a = regs.a[7]; regs.a[7] += 4; return coreGet32(a); } ldEA32tab[(4<<3)|0] = function() { regs.a[0] -= 4; return coreGet32(regs.a[0]); } //ripr ldEA32tab[(4<<3)|1] = function() { regs.a[1] -= 4; return coreGet32(regs.a[1]); } ldEA32tab[(4<<3)|2] = function() { regs.a[2] -= 4; return coreGet32(regs.a[2]); } ldEA32tab[(4<<3)|3] = function() { regs.a[3] -= 4; return coreGet32(regs.a[3]); } ldEA32tab[(4<<3)|4] = function() { regs.a[4] -= 4; return coreGet32(regs.a[4]); } ldEA32tab[(4<<3)|5] = function() { regs.a[5] -= 4; return coreGet32(regs.a[5]); } ldEA32tab[(4<<3)|6] = function() { regs.a[6] -= 4; return coreGet32(regs.a[6]); } ldEA32tab[(4<<3)|7] = function() { regs.a[7] -= 4; return coreGet32(regs.a[7]); } ldEA32tab[(5<<3)|0] = function() { return coreGet32(add32(regs.a[0], extWord(coreNext16()))); } //rid ldEA32tab[(5<<3)|1] = function() { return coreGet32(add32(regs.a[1], extWord(coreNext16()))); } ldEA32tab[(5<<3)|2] = function() { return coreGet32(add32(regs.a[2], extWord(coreNext16()))); } ldEA32tab[(5<<3)|3] = function() { return coreGet32(add32(regs.a[3], extWord(coreNext16()))); } ldEA32tab[(5<<3)|4] = function() { return coreGet32(add32(regs.a[4], extWord(coreNext16()))); } ldEA32tab[(5<<3)|5] = function() { return coreGet32(add32(regs.a[5], extWord(coreNext16()))); } ldEA32tab[(5<<3)|6] = function() { return coreGet32(add32(regs.a[6], extWord(coreNext16()))); } ldEA32tab[(5<<3)|7] = function() { return coreGet32(add32(regs.a[7], extWord(coreNext16()))); } ldEA32tab[(6<<3)|0] = function() { return coreGet32(exII(regs.a[0], coreNext16())); } //rii0 ldEA32tab[(6<<3)|1] = function() { return coreGet32(exII(regs.a[1], coreNext16())); } ldEA32tab[(6<<3)|2] = function() { return coreGet32(exII(regs.a[2], coreNext16())); } ldEA32tab[(6<<3)|3] = function() { return coreGet32(exII(regs.a[3], coreNext16())); } ldEA32tab[(6<<3)|4] = function() { return coreGet32(exII(regs.a[4], coreNext16())); } ldEA32tab[(6<<3)|5] = function() { return coreGet32(exII(regs.a[5], coreNext16())); } ldEA32tab[(6<<3)|6] = function() { return coreGet32(exII(regs.a[6], coreNext16())); } ldEA32tab[(6<<3)|7] = function() { return coreGet32(exII(regs.a[7], coreNext16())); } ldEA32tab[(7<<3)|0] = function() { return coreGet32(extWord(coreNext16())); } //absw ldEA32tab[(7<<3)|1] = function() { return coreGet32(coreNext32()); } //absl ldEA32tab[(7<<3)|2] = function() { return coreGet32(add32(coreGetPC(), extWord(coreNext16()))); } //pcid ldEA32tab[(7<<3)|3] = function() { return coreGet32(exII(coreGetPC(), coreNext16())); } //pcii ldEA32tab[(7<<3)|4] = function() { return coreNext32(); } //imm stEA8tab = new Array(64); stEA8tab[ 0] = function(v) { regs.d[0] = (regs.d[0] & 0xffffff00) | v; } //rdd stEA8tab[ 1] = function(v) { regs.d[1] = (regs.d[1] & 0xffffff00) | v; } stEA8tab[ 2] = function(v) { regs.d[2] = (regs.d[2] & 0xffffff00) | v; } stEA8tab[ 3] = function(v) { regs.d[3] = (regs.d[3] & 0xffffff00) | v; } stEA8tab[ 4] = function(v) { regs.d[4] = (regs.d[4] & 0xffffff00) | v; } stEA8tab[ 5] = function(v) { regs.d[5] = (regs.d[5] & 0xffffff00) | v; } stEA8tab[ 6] = function(v) { regs.d[6] = (regs.d[6] & 0xffffff00) | v; } stEA8tab[ 7] = function(v) { regs.d[7] = (regs.d[7] & 0xffffff00) | v; } stEA8tab[(1<<3)|0] = function(v) { SAEF_error("cpu.stEA8tab() invalid EA 8 (1|0)"); } //rda stEA8tab[(1<<3)|1] = function(v) { SAEF_error("cpu.stEA8tab() invalid EA 9 (1|1)"); } stEA8tab[(1<<3)|2] = function(v) { SAEF_error("cpu.stEA8tab() invalid EA 10 (1|2)"); } stEA8tab[(1<<3)|3] = function(v) { SAEF_error("cpu.stEA8tab() invalid EA 11 (1|3)"); } stEA8tab[(1<<3)|4] = function(v) { SAEF_error("cpu.stEA8tab() invalid EA 12 (1|4)"); } stEA8tab[(1<<3)|5] = function(v) { SAEF_error("cpu.stEA8tab() invalid EA 13 (1|5)"); } stEA8tab[(1<<3)|6] = function(v) { SAEF_error("cpu.stEA8tab() invalid EA 14 (1|6)"); } stEA8tab[(1<<3)|7] = function(v) { SAEF_error("cpu.stEA8tab() invalid EA 15 (1|7)"); } stEA8tab[(2<<3)|0] = function(v) { corePut8(regs.a[0], v); } //ria stEA8tab[(2<<3)|1] = function(v) { corePut8(regs.a[1], v); } stEA8tab[(2<<3)|2] = function(v) { corePut8(regs.a[2], v); } stEA8tab[(2<<3)|3] = function(v) { corePut8(regs.a[3], v); } stEA8tab[(2<<3)|4] = function(v) { corePut8(regs.a[4], v); } stEA8tab[(2<<3)|5] = function(v) { corePut8(regs.a[5], v); } stEA8tab[(2<<3)|6] = function(v) { corePut8(regs.a[6], v); } stEA8tab[(2<<3)|7] = function(v) { corePut8(regs.a[7], v); } stEA8tab[(3<<3)|0] = function(v) { corePut8(regs.a[0], v); regs.a[0] += 1; } //ripo stEA8tab[(3<<3)|1] = function(v) { corePut8(regs.a[1], v); regs.a[1] += 1; } stEA8tab[(3<<3)|2] = function(v) { corePut8(regs.a[2], v); regs.a[2] += 1; } stEA8tab[(3<<3)|3] = function(v) { corePut8(regs.a[3], v); regs.a[3] += 1; } stEA8tab[(3<<3)|4] = function(v) { corePut8(regs.a[4], v); regs.a[4] += 1; } stEA8tab[(3<<3)|5] = function(v) { corePut8(regs.a[5], v); regs.a[5] += 1; } stEA8tab[(3<<3)|6] = function(v) { corePut8(regs.a[6], v); regs.a[6] += 1; } stEA8tab[(3<<3)|7] = function(v) { corePut8(regs.a[7], v); regs.a[7] += 2; } stEA8tab[(4<<3)|0] = function(v) { regs.a[0] -= 1; corePut8(regs.a[0], v); } //ripr stEA8tab[(4<<3)|1] = function(v) { regs.a[1] -= 1; corePut8(regs.a[1], v); } stEA8tab[(4<<3)|2] = function(v) { regs.a[2] -= 1; corePut8(regs.a[2], v); } stEA8tab[(4<<3)|3] = function(v) { regs.a[3] -= 1; corePut8(regs.a[3], v); } stEA8tab[(4<<3)|4] = function(v) { regs.a[4] -= 1; corePut8(regs.a[4], v); } stEA8tab[(4<<3)|5] = function(v) { regs.a[5] -= 1; corePut8(regs.a[5], v); } stEA8tab[(4<<3)|6] = function(v) { regs.a[6] -= 1; corePut8(regs.a[6], v); } stEA8tab[(4<<3)|7] = function(v) { regs.a[7] -= 2; corePut8(regs.a[7], v); } stEA8tab[(5<<3)|0] = function(v) { corePut8(add32(regs.a[0], extWord(coreNext16())), v); } //rid stEA8tab[(5<<3)|1] = function(v) { corePut8(add32(regs.a[1], extWord(coreNext16())), v); } stEA8tab[(5<<3)|2] = function(v) { corePut8(add32(regs.a[2], extWord(coreNext16())), v); } stEA8tab[(5<<3)|3] = function(v) { corePut8(add32(regs.a[3], extWord(coreNext16())), v); } stEA8tab[(5<<3)|4] = function(v) { corePut8(add32(regs.a[4], extWord(coreNext16())), v); } stEA8tab[(5<<3)|5] = function(v) { corePut8(add32(regs.a[5], extWord(coreNext16())), v); } stEA8tab[(5<<3)|6] = function(v) { corePut8(add32(regs.a[6], extWord(coreNext16())), v); } stEA8tab[(5<<3)|7] = function(v) { corePut8(add32(regs.a[7], extWord(coreNext16())), v); } stEA8tab[(6<<3)|0] = function(v) { corePut8(exII(regs.a[0], coreNext16()), v); } //rii stEA8tab[(6<<3)|1] = function(v) { corePut8(exII(regs.a[1], coreNext16()), v); } stEA8tab[(6<<3)|2] = function(v) { corePut8(exII(regs.a[2], coreNext16()), v); } stEA8tab[(6<<3)|3] = function(v) { corePut8(exII(regs.a[3], coreNext16()), v); } stEA8tab[(6<<3)|4] = function(v) { corePut8(exII(regs.a[4], coreNext16()), v); } stEA8tab[(6<<3)|5] = function(v) { corePut8(exII(regs.a[5], coreNext16()), v); } stEA8tab[(6<<3)|6] = function(v) { corePut8(exII(regs.a[6], coreNext16()), v); } stEA8tab[(6<<3)|7] = function(v) { corePut8(exII(regs.a[7], coreNext16()), v); } stEA8tab[(7<<3)|0] = function(v) { corePut8(extWord(coreNext16()), v); } //absw stEA8tab[(7<<3)|1] = function(v) { corePut8(coreNext32(), v); } //absl stEA8tab[(7<<3)|2] = function(v) { corePut8(add32(coreGetPC(), extWord(coreNext16())), v); } //pcid stEA8tab[(7<<3)|3] = function(v) { corePut8(exII(coreGetPC(), coreNext16()), v); } //pcii stEA8tab[(7<<3)|4] = function(v) { SAEF_error("cpu.stEA8tab() invalid EA 60 (7|4)"); } //imm stEA16tab = new Array(64); stEA16tab[ 0] = function(v) { regs.d[0] = (regs.d[0] & 0xffff0000) | v; } //rdd stEA16tab[ 1] = function(v) { regs.d[1] = (regs.d[1] & 0xffff0000) | v; } stEA16tab[ 2] = function(v) { regs.d[2] = (regs.d[2] & 0xffff0000) | v; } stEA16tab[ 3] = function(v) { regs.d[3] = (regs.d[3] & 0xffff0000) | v; } stEA16tab[ 4] = function(v) { regs.d[4] = (regs.d[4] & 0xffff0000) | v; } stEA16tab[ 5] = function(v) { regs.d[5] = (regs.d[5] & 0xffff0000) | v; } stEA16tab[ 6] = function(v) { regs.d[6] = (regs.d[6] & 0xffff0000) | v; } stEA16tab[ 7] = function(v) { regs.d[7] = (regs.d[7] & 0xffff0000) | v; } stEA16tab[(1<<3)|0] = function(v) { regs.a[0] = v; } //rda stEA16tab[(1<<3)|1] = function(v) { regs.a[1] = v; } stEA16tab[(1<<3)|2] = function(v) { regs.a[2] = v; } stEA16tab[(1<<3)|3] = function(v) { regs.a[3] = v; } stEA16tab[(1<<3)|4] = function(v) { regs.a[4] = v; } stEA16tab[(1<<3)|5] = function(v) { regs.a[5] = v; } stEA16tab[(1<<3)|6] = function(v) { regs.a[6] = v; } stEA16tab[(1<<3)|7] = function(v) { regs.a[7] = v; } stEA16tab[(2<<3)|0] = function(v) { corePut16(regs.a[0], v); } //ria stEA16tab[(2<<3)|1] = function(v) { corePut16(regs.a[1], v); } stEA16tab[(2<<3)|2] = function(v) { corePut16(regs.a[2], v); } stEA16tab[(2<<3)|3] = function(v) { corePut16(regs.a[3], v); } stEA16tab[(2<<3)|4] = function(v) { corePut16(regs.a[4], v); } stEA16tab[(2<<3)|5] = function(v) { corePut16(regs.a[5], v); } stEA16tab[(2<<3)|6] = function(v) { corePut16(regs.a[6], v); } stEA16tab[(2<<3)|7] = function(v) { corePut16(regs.a[7], v); } stEA16tab[(3<<3)|0] = function(v) { corePut16(regs.a[0], v); regs.a[0] += 2; } //ripo stEA16tab[(3<<3)|1] = function(v) { corePut16(regs.a[1], v); regs.a[1] += 2; } stEA16tab[(3<<3)|2] = function(v) { corePut16(regs.a[2], v); regs.a[2] += 2; } stEA16tab[(3<<3)|3] = function(v) { corePut16(regs.a[3], v); regs.a[3] += 2; } stEA16tab[(3<<3)|4] = function(v) { corePut16(regs.a[4], v); regs.a[4] += 2; } stEA16tab[(3<<3)|5] = function(v) { corePut16(regs.a[5], v); regs.a[5] += 2; } stEA16tab[(3<<3)|6] = function(v) { corePut16(regs.a[6], v); regs.a[6] += 2; } stEA16tab[(3<<3)|7] = function(v) { corePut16(regs.a[7], v); regs.a[7] += 2; } stEA16tab[(4<<3)|0] = function(v) { regs.a[0] -= 2; corePut16(regs.a[0], v); } //ripr stEA16tab[(4<<3)|1] = function(v) { regs.a[1] -= 2; corePut16(regs.a[1], v); } stEA16tab[(4<<3)|2] = function(v) { regs.a[2] -= 2; corePut16(regs.a[2], v); } stEA16tab[(4<<3)|3] = function(v) { regs.a[3] -= 2; corePut16(regs.a[3], v); } stEA16tab[(4<<3)|4] = function(v) { regs.a[4] -= 2; corePut16(regs.a[4], v); } stEA16tab[(4<<3)|5] = function(v) { regs.a[5] -= 2; corePut16(regs.a[5], v); } stEA16tab[(4<<3)|6] = function(v) { regs.a[6] -= 2; corePut16(regs.a[6], v); } stEA16tab[(4<<3)|7] = function(v) { regs.a[7] -= 2; corePut16(regs.a[7], v); } stEA16tab[(5<<3)|0] = function(v) { corePut16(add32(regs.a[0], extWord(coreNext16())), v); } //rid stEA16tab[(5<<3)|1] = function(v) { corePut16(add32(regs.a[1], extWord(coreNext16())), v); } stEA16tab[(5<<3)|2] = function(v) { corePut16(add32(regs.a[2], extWord(coreNext16())), v); } stEA16tab[(5<<3)|3] = function(v) { corePut16(add32(regs.a[3], extWord(coreNext16())), v); } stEA16tab[(5<<3)|4] = function(v) { corePut16(add32(regs.a[4], extWord(coreNext16())), v); } stEA16tab[(5<<3)|5] = function(v) { corePut16(add32(regs.a[5], extWord(coreNext16())), v); } stEA16tab[(5<<3)|6] = function(v) { corePut16(add32(regs.a[6], extWord(coreNext16())), v); } stEA16tab[(5<<3)|7] = function(v) { corePut16(add32(regs.a[7], extWord(coreNext16())), v); } stEA16tab[(6<<3)|0] = function(v) { corePut16(exII(regs.a[0], coreNext16()), v); } //rii stEA16tab[(6<<3)|1] = function(v) { corePut16(exII(regs.a[1], coreNext16()), v); } stEA16tab[(6<<3)|2] = function(v) { corePut16(exII(regs.a[2], coreNext16()), v); } stEA16tab[(6<<3)|3] = function(v) { corePut16(exII(regs.a[3], coreNext16()), v); } stEA16tab[(6<<3)|4] = function(v) { corePut16(exII(regs.a[4], coreNext16()), v); } stEA16tab[(6<<3)|5] = function(v) { corePut16(exII(regs.a[5], coreNext16()), v); } stEA16tab[(6<<3)|6] = function(v) { corePut16(exII(regs.a[6], coreNext16()), v); } stEA16tab[(6<<3)|7] = function(v) { corePut16(exII(regs.a[7], coreNext16()), v); } stEA16tab[(7<<3)|0] = function(v) { corePut16(extWord(coreNext16()), v); } //absw stEA16tab[(7<<3)|1] = function(v) { corePut16(coreNext32(), v); } //absl stEA16tab[(7<<3)|2] = function(v) { corePut16(add32(coreGetPC(), extWord(coreNext16())), v); } //pcid stEA16tab[(7<<3)|3] = function(v) { corePut16(exII(coreGetPC(), coreNext16()), v); } //pcii stEA16tab[(7<<3)|4] = function(v) { SAEF_error("cpu.stEA16tab() invalid EA 60 (7|4)"); } //imm stEA32tab = new Array(64); stEA32tab[ 0] = function(v) { regs.d[0] = v; } //rdd stEA32tab[ 1] = function(v) { regs.d[1] = v; } stEA32tab[ 2] = function(v) { regs.d[2] = v; } stEA32tab[ 3] = function(v) { regs.d[3] = v; } stEA32tab[ 4] = function(v) { regs.d[4] = v; } stEA32tab[ 5] = function(v) { regs.d[5] = v; } stEA32tab[ 6] = function(v) { regs.d[6] = v; } stEA32tab[ 7] = function(v) { regs.d[7] = v; } stEA32tab[(1<<3)|0] = function(v) { regs.a[0] = v; } //rda stEA32tab[(1<<3)|1] = function(v) { regs.a[1] = v; } stEA32tab[(1<<3)|2] = function(v) { regs.a[2] = v; } stEA32tab[(1<<3)|3] = function(v) { regs.a[3] = v; } stEA32tab[(1<<3)|4] = function(v) { regs.a[4] = v; } stEA32tab[(1<<3)|5] = function(v) { regs.a[5] = v; } stEA32tab[(1<<3)|6] = function(v) { regs.a[6] = v; } stEA32tab[(1<<3)|7] = function(v) { regs.a[7] = v; } stEA32tab[(2<<3)|0] = function(v) { corePut32(regs.a[0], v); } //ria stEA32tab[(2<<3)|1] = function(v) { corePut32(regs.a[1], v); } stEA32tab[(2<<3)|2] = function(v) { corePut32(regs.a[2], v); } stEA32tab[(2<<3)|3] = function(v) { corePut32(regs.a[3], v); } stEA32tab[(2<<3)|4] = function(v) { corePut32(regs.a[4], v); } stEA32tab[(2<<3)|5] = function(v) { corePut32(regs.a[5], v); } stEA32tab[(2<<3)|6] = function(v) { corePut32(regs.a[6], v); } stEA32tab[(2<<3)|7] = function(v) { corePut32(regs.a[7], v); } stEA32tab[(3<<3)|0] = function(v) { corePut32(regs.a[0], v); regs.a[0] += 4; } //ripo stEA32tab[(3<<3)|1] = function(v) { corePut32(regs.a[1], v); regs.a[1] += 4; } stEA32tab[(3<<3)|2] = function(v) { corePut32(regs.a[2], v); regs.a[2] += 4; } stEA32tab[(3<<3)|3] = function(v) { corePut32(regs.a[3], v); regs.a[3] += 4; } stEA32tab[(3<<3)|4] = function(v) { corePut32(regs.a[4], v); regs.a[4] += 4; } stEA32tab[(3<<3)|5] = function(v) { corePut32(regs.a[5], v); regs.a[5] += 4; } stEA32tab[(3<<3)|6] = function(v) { corePut32(regs.a[6], v); regs.a[6] += 4; } stEA32tab[(3<<3)|7] = function(v) { corePut32(regs.a[7], v); regs.a[7] += 4; } stEA32tab[(4<<3)|0] = function(v) { regs.a[0] -= 4; corePut32(regs.a[0], v); } //ripr stEA32tab[(4<<3)|1] = function(v) { regs.a[1] -= 4; corePut32(regs.a[1], v); } stEA32tab[(4<<3)|2] = function(v) { regs.a[2] -= 4; corePut32(regs.a[2], v); } stEA32tab[(4<<3)|3] = function(v) { regs.a[3] -= 4; corePut32(regs.a[3], v); } stEA32tab[(4<<3)|4] = function(v) { regs.a[4] -= 4; corePut32(regs.a[4], v); } stEA32tab[(4<<3)|5] = function(v) { regs.a[5] -= 4; corePut32(regs.a[5], v); } stEA32tab[(4<<3)|6] = function(v) { regs.a[6] -= 4; corePut32(regs.a[6], v); } stEA32tab[(4<<3)|7] = function(v) { regs.a[7] -= 4; corePut32(regs.a[7], v); } stEA32tab[(5<<3)|0] = function(v) { corePut32(add32(regs.a[0], extWord(coreNext16())), v); } //rid stEA32tab[(5<<3)|1] = function(v) { corePut32(add32(regs.a[1], extWord(coreNext16())), v); } stEA32tab[(5<<3)|2] = function(v) { corePut32(add32(regs.a[2], extWord(coreNext16())), v); } stEA32tab[(5<<3)|3] = function(v) { corePut32(add32(regs.a[3], extWord(coreNext16())), v); } stEA32tab[(5<<3)|4] = function(v) { corePut32(add32(regs.a[4], extWord(coreNext16())), v); } stEA32tab[(5<<3)|5] = function(v) { corePut32(add32(regs.a[5], extWord(coreNext16())), v); } stEA32tab[(5<<3)|6] = function(v) { corePut32(add32(regs.a[6], extWord(coreNext16())), v); } stEA32tab[(5<<3)|7] = function(v) { corePut32(add32(regs.a[7], extWord(coreNext16())), v); } stEA32tab[(6<<3)|0] = function(v) { corePut32(exII(regs.a[0], coreNext16()), v); } //rii stEA32tab[(6<<3)|1] = function(v) { corePut32(exII(regs.a[1], coreNext16()), v); } stEA32tab[(6<<3)|2] = function(v) { corePut32(exII(regs.a[2], coreNext16()), v); } stEA32tab[(6<<3)|3] = function(v) { corePut32(exII(regs.a[3], coreNext16()), v); } stEA32tab[(6<<3)|4] = function(v) { corePut32(exII(regs.a[4], coreNext16()), v); } stEA32tab[(6<<3)|5] = function(v) { corePut32(exII(regs.a[5], coreNext16()), v); } stEA32tab[(6<<3)|6] = function(v) { corePut32(exII(regs.a[6], coreNext16()), v); } stEA32tab[(6<<3)|7] = function(v) { corePut32(exII(regs.a[7], coreNext16()), v); } stEA32tab[(7<<3)|0] = function(v) { corePut32(extWord(coreNext16()), v); } //absw stEA32tab[(7<<3)|1] = function(v) { corePut32(coreNext32(), v); } //absl stEA32tab[(7<<3)|2] = function(v) { corePut32(add32(coreGetPC(), extWord(coreNext16())), v); } //pcid stEA32tab[(7<<3)|3] = function(v) { corePut32(exII(coreGetPC(), coreNext16()), v); } //pcii stEA32tab[(7<<3)|4] = function(v) { SAEF_error("cpu.stEA32tab() invalid EA 60 (7|4)"); } //imm } /*-----------------------------------------------------------------------*/ /* Instruction table */ /*function mkEA(m,r) { switch (m) { case M_rdd: return (0 << 3) | r; case M_rda: return (1 << 3) | r; case M_ria: return (2 << 3) | r; case M_ripo: return (3 << 3) | r; case M_ripr: return (4 << 3) | r; case M_rid: return (5 << 3) | r; case M_rii: return (6 << 3) | r; case M_absw: return (7 << 3) | 0; case M_absl: return (7 << 3) | 1; case M_pcid: return (7 << 3) | 2; case M_pcii: return (7 << 3) | 3; case M_imm: return (7 << 3) | 4; } SAEF_error("cpu.mkEA() ERROR m "+m+", r "+r); return -1; }*/ function getEAMode(ea) { var m = ea >> 3; if (m == 7) { switch (ea & 7) { case 0: return M_absw; case 1: return M_absl; case 2: return M_pcid; case 3: return M_pcii; case 4: return M_imm; } } else { switch (m) { case 0: return M_rdd; case 1: return M_rda; case 2: return M_ria; case 3: return M_ripo; case 4: return M_ripr; case 5: return M_rid; case 6: return M_rii; } } SAEF_error("cpu.getEAMode() ERROR ea "+ea); return -1; } function isEA(ea, en) { var m = ea >> 3; if (m == 7) { var r = ea & 7; if (r == 0 && en.indexOf(M_absw) != -1) return true; if (r == 1 && en.indexOf(M_absl) != -1) return true; if (r == 2 && en.indexOf(M_pcid) != -1) return true; if (r == 3 && en.indexOf(M_pcii) != -1) return true; if (r == 4 && en.indexOf(M_imm) != -1) return true; } else { if (m == 0 && en.indexOf(M_rdd) != -1) return true; if (m == 1 && en.indexOf(M_rda) != -1) return true; if (m == 2 && en.indexOf(M_ria) != -1) return true; if (m == 3 && en.indexOf(M_ripo) != -1) return true; if (m == 4 && en.indexOf(M_ripr) != -1) return true; if (m == 5 && en.indexOf(M_rid) != -1) return true; if (m == 6 && en.indexOf(M_rii) != -1) return true; } return false; } function getEACycs(ea, z) { var m = ea >> 3; if (m == 7) { switch (ea & 7) { case 0: return z == 4 ? [12,3,0] : [ 8,2,0]; //absw case 1: return z == 4 ? [16,4,0] : [12,3,0]; //absl case 2: return z == 4 ? [12,3,0] : [ 8,2,0]; //pcid case 3: return z == 4 ? [14,3,0] : [10,2,0]; //pcii case 4: return z == 4 ? [ 8,2,0] : [ 4,1,0]; //imm } } else { switch (m) { case 0: return [0,0,0]; //rdd case 1: return [0,0,0]; //rda case 2: return z == 4 ? [ 8,2,0] : [ 4,1,0]; //ria case 3: return z == 4 ? [ 8,2,0] : [ 4,1,0]; //ripo case 4: return z == 4 ? [10,2,0] : [ 6,1,0]; //ripr case 5: return z == 4 ? [12,3,0] : [ 8,2,0]; //rid case 6: return z == 4 ? [14,3,0] : [10,2,0]; //rii } } } function addCycs(c1, c2) { c1[0] += c2[0]; c1[1] += c2[1]; c1[2] += c2[2]; return c1; } function mkI(op, mn, cyc) { return { op: op, mn: mn, p: { op:op, cyc:cyc } }; } function mkDiss(ext, sm, s, dm, d, z, z2) { if (sm && dm) return { ext:ext, sm:sm, s:s, dm:dm, d:d, z:z, z2:z2 }; else if (dm) return { ext:ext, dm:dm, d:d, z:z, z2:z2 }; else return { ext:ext, z:z, z2:z2 }; } function mkITab() { var op, cnt = 0; //45827 var old = 0; iTab = new Array(0x10000); for (op = 0; op < 0x10000; op++) { iTab[op] = { op: -1, mn: "ILLEGAL", p: op, /* opcode as param for ILLEGAL or real param if function */ f: ILLEGAL }; } /*-----------------------------------------------------------------------*/ /* Data Movement */ //EXG { for (var m = 0; m < 3; m++) { var opm = m == 0 ? 8 : (m == 1 ? 9 : 17); for (var Rx = 0; Rx < 8; Rx++) { for (var Ry = 0; Ry < 8; Ry++) { op = (12 << 12) | (Rx << 9) | (1 << 8) | (opm << 3) | Ry; if (iTab[op].op === -1) { iTab[op] = mkI(op, "EXG", [6,1,0]); iTab[op].p.Rx = Rx; iTab[op].p.Ry = Ry; if (m == 0) { iTab[op].f = I_EXG_DD; iTab[op].d = mkDiss(0, D_RDD,Rx, D_RDD,Ry, 4,0); } else if (m == 1) { iTab[op].f = I_EXG_AA; iTab[op].d = mkDiss(0, D_RDA,Rx, D_RDA,Ry, 4,0); } else { iTab[op].f = I_EXG_DA; iTab[op].d = mkDiss(0, D_RDD,Rx, D_RDA,Ry, 4,0); } cnt++; } else { SAEF_error("cpu.mkITab() op exists EXG "+op); return false; } } } } } //LEA { var en = [M_ria, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl]; for (var An = 0; An < 8; An++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (4 << 12) | (An << 9) | (7 << 6) | ea; if (iTab[op].op === -1) { var cyc; switch (getEAMode(ea)) { case M_ria: cyc = [ 4,1,0]; break; case M_rid: cyc = [ 8,2,0]; break; case M_rii: cyc = [12,2,0]; break; case M_pcid: cyc = [ 8,2,0]; break; case M_pcii: cyc = [12,2,0]; break; case M_absw: cyc = [ 8,2,0]; break; case M_absl: cyc = [12,3,0]; break; } iTab[op] = mkI(op, "LEA", cyc); iTab[op].p.An = An; iTab[op].p.ea = ea; iTab[op].f = I_LEA; iTab[op].d = mkDiss(0, D_EA,ea, D_RDA,An, 4,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists LEA "+op); return false; } } } } } //PEA { var en = [M_ria, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (289 << 6) | ea; if (iTab[op].op === -1) { var cyc; switch (getEAMode(ea)) { case M_ria: cyc = [12,1,2]; break; case M_rid: cyc = [16,2,2]; break; case M_rii: cyc = [20,2,2]; break; case M_pcid: cyc = [16,2,2]; break; case M_pcii: cyc = [20,2,2]; break; case M_absw: cyc = [16,2,2]; break; case M_absl: cyc = [20,3,2]; break; } iTab[op] = mkI(op, "PEA", cyc); iTab[op].p.ea = ea; iTab[op].f = I_PEA; iTab[op].d = mkDiss(0, false,false, D_EA,ea, 4,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists PEA " + op); return false; } } } } //LINK { for (var An = 0; An < 8; An++) { op = (2506 << 3) | An; if (iTab[op].op === -1) { iTab[op] = mkI(op, "LINK", [16,2,2]); iTab[op].p.An = An; iTab[op].f = I_LINK; iTab[op].d = mkDiss(0, D_RDA,An, D_IME,1, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists LINK "+op); return false; } } if (model >= 68020) { for (var An = 0; An < 8; An++) { op = (2305 << 3) | An; if (iTab[op].op === -1) { iTab[op] = mkI(op, "LINK", [16,2,2]); //FIXME cycles iTab[op].p.An = An; iTab[op].f = I_LINK_32; iTab[op].d = mkDiss(0, D_RDA,An, D_IME,2, 4,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists LINK "+op); return false; } } } } //UNLK { for (var An = 0; An < 8; An++) { op = (2507 << 3) | An; if (iTab[op].op === -1) { iTab[op] = mkI(op, "UNLK", [12,3,0]); iTab[op].p.An = An; iTab[op].f = I_UNLK; iTab[op].d = mkDiss(0, false,false, D_RDA,An, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists UNLK "+op); return false; } } } //MOVE { var tab2 = [ [[ 4,1,0],null,[ 8,1,1],[ 8,1,1],[ 8,1,1],[12,2,1],[14,2,1],null,null,[12,2,1],[16,3,1],null], [[ 4,1,0],null,[ 8,1,1],[ 8,1,1],[ 8,1,1],[12,2,1],[14,2,1],null,null,[12,2,1],[16,3,1],null], [[ 8,2,0],null,[12,2,1],[12,2,1],[12,2,1],[16,3,1],[18,3,1],null,null,[16,3,1],[20,4,1],null], [[ 8,2,0],null,[12,2,1],[12,2,1],[12,2,1],[16,3,1],[18,3,1],null,null,[16,3,1],[20,4,1],null], [[10,2,0],null,[14,2,1],[14,2,1],[14,2,1],[18,3,1],[20,4,1],null,null,[18,3,1],[22,4,1],null], [[12,3,0],null,[16,3,1],[16,3,1],[16,3,1],[20,4,1],[22,4,1],null,null,[20,4,1],[24,5,1],null], [[14,3,0],null,[18,3,1],[18,3,1],[18,3,1],[22,4,1],[24,4,1],null,null,[22,4,1],[26,5,1],null], [[12,3,0],null,[16,3,1],[16,3,1],[16,3,1],[20,4,1],[22,4,1],null,null,[20,4,1],[24,5,1],null], [[14,3,0],null,[18,3,1],[18,3,1],[18,3,1],[22,4,1],[24,4,1],null,null,[22,4,1],[26,5,1],null], [[12,3,0],null,[16,3,1],[16,3,1],[16,3,1],[20,4,1],[22,4,1],null,null,[20,4,1],[24,5,1],null], [[16,4,0],null,[20,4,1],[20,4,1],[20,4,1],[24,5,1],[26,5,1],null,null,[24,5,1],[28,6,1],null], [[ 8,2,0],null,[12,2,1],[12,2,1],[12,2,1],[16,3,1],[18,3,1],null,null,[16,3,1],[20,4,1],null] ]; var tab4 = [ [[ 4,1,0],null,[12,1,2],[12,1,2],[12,1,2],[16,2,2],[18,2,2],null,null,[16,2,2],[20,3,2],null], [[ 4,1,0],null,[12,1,2],[12,1,2],[12,1,2],[16,2,2],[18,2,2],null,null,[16,2,2],[20,3,2],null], [[12,3,0],null,[20,3,2],[20,3,2],[20,3,2],[24,4,2],[26,4,2],null,null,[24,4,2],[28,5,2],null], [[12,3,0],null,[20,3,2],[20,3,2],[20,3,2],[24,4,2],[26,4,2],null,null,[24,4,2],[28,5,2],null], [[14,3,0],null,[22,3,2],[22,3,2],[22,3,2],[26,4,2],[28,4,2],null,null,[26,4,2],[30,5,2],null], [[16,4,0],null,[24,4,2],[24,4,2],[24,4,2],[28,5,2],[30,5,2],null,null,[28,5,2],[32,6,2],null], [[18,4,0],null,[26,4,2],[26,4,2],[26,4,2],[30,5,2],[32,5,2],null,null,[30,5,2],[34,6,2],null], [[16,4,0],null,[24,4,2],[24,4,2],[24,4,2],[28,5,2],[30,5,2],null,null,[28,5,2],[32,5,2],null], [[18,4,0],null,[26,4,2],[26,4,2],[26,4,2],[30,5,2],[32,5,2],null,null,[30,5,2],[34,6,2],null], [[16,4,0],null,[24,4,2],[24,4,2],[24,4,2],[28,5,2],[30,5,2],null,null,[28,5,2],[32,6,2],null], [[20,5,0],null,[28,5,2],[28,5,2],[28,5,2],[32,6,2],[34,6,2],null,null,[32,6,2],[36,7,2],null], [[12,3,0],null,[20,3,2],[20,3,2],[20,3,2],[24,4,2],[26,4,2],null,null,[24,4,2],[28,5,2],null] ]; var den = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); var z3 = z == 0 ? 1 : (z == 1 ? 3 : 2); for (var dea = 0; dea < 61; dea++) { if (isEA(dea, den)) { for (var sea = 0; sea < 61; sea++) { if (z2 == 1 && sea >> 3 == 1) continue; //For byte size operation, address register direct is not allowed. var deainv = ((dea & 7) << 3) | (dea >> 3); op = (z3 << 12) | (deainv << 6) | sea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "MOVE", z2 == 4 ? tab4[getEAMode(sea)-1][getEAMode(dea)-1] : tab2[getEAMode(sea)-1][getEAMode(dea)-1]); iTab[op].p.sea = sea; iTab[op].p.dea = dea; iTab[op].p.zm = z2 == 1 ? 0x80 : (z2 == 2 ? 0x8000 : 0x80000000); iTab[op].f = z2 == 4 ? I_MOVE_32 : (z2 == 2 ? I_MOVE_16 : I_MOVE_8); iTab[op].d = mkDiss(0, D_EA,sea, D_EA,dea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists MOVE "+op); return false; } } } } } } //MOVEA { var tab2 = [[4,1,0],[4,1,0],[ 8,2,0],[ 8,2,0],[10,2,0],[12,3,0],[14,3,0],[12,3,0],[14,3,0],[12,3,0],[16,4,0],[ 8,2,0]]; var tab4 = [[4,1,0],[4,1,0],[12,3,0],[12,3,0],[14,3,0],[16,4,0],[18,4,0],[16,4,0],[18,4,0],[16,4,0],[20,5,0],[12,3,0]]; for (var z = 1; z < 3; z++) { var z2 = z == 1 ? 2 : 4; var z3 = z == 1 ? 3 : 2; for (var An = 0; An < 8; An++) { for (var ea = 0; ea < 61; ea++) { op = (z3 << 12) | (An << 9) | (1 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "MOVEA", z2 == 4 ? tab4[getEAMode(ea)-1] : tab2[getEAMode(ea)-1]); iTab[op].p.An = An; iTab[op].p.ea = ea; iTab[op].f = z2 == 4 ? I_MOVEA_32 : I_MOVEA_16; iTab[op].d = mkDiss(0, D_EA,ea, D_RDA,An, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists MOVEA "+op); return false; } } } } } //MOVEQ { for (var Dn = 0; Dn < 8; Dn++) { for (var d = 0; d < 256; d++) { op = (7 << 12) | (Dn << 9) | d; if (iTab[op].op === -1) { iTab[op] = mkI(op, "MOVEQ", [4,1,0]); iTab[op].p.Dn = Dn; iTab[op].p.data = d; iTab[op].p.zm = 0x80000000; iTab[op].f = I_MOVEQ; iTab[op].d = mkDiss(0, D_IMD,d, D_RDD,Dn, 4,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists MOVEQ " + op); return false; } } } } //MOVEM /* size (An) (An)+ -(An) d(An) d(An,ix)+ xxx.W xxx.L d(PC) d(PC,ix)* --------------------------------------------------------------------------------------------------------------- R->M word 8+4n - 8+4n 12+4n 14+4n 12+4n 16+4n - - (2/n) - (2/n) (3/n) (3/n) (3/n) (4/n) - - long 8+8n - 8+8n 12+8n 14+8n 12+8n 16+8n - - (2/2n) - (2/2n) (3/2n) (3/2n) (3/2n) (4/2n) - - M->R word 12+4n 12+4n - 16+4n 18+4n 16+4n 20+4n 16+4n 18+4n (3+n/0) (3+n/0) - (4+n/0) (4+n/0) (4+n/0) (5+n/0) (4+n/0) (4+n/0) long 12+8n 12+8n - 16+8n 18+8n 16+8n 20+8n 16+8n 18+8n (3+2n/0) (3+2n/0) - (4+2n/0) (4+2n/0) (4+2n/0) (5+2n/0) (4+2n/0) (4+2n/0) */ { for (var z = 0; z < 2; z++) { var z2 = z == 0 ? 2 : 4; for (var dr = 0; dr < 2; dr++) { if (dr == 0) en = [M_ria, M_ripr, M_rid, M_rii, M_absw, M_absl]; else en = [M_ria, M_ripo, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (9 << 11) | (dr << 10) | (1 << 7) | (z << 6) | ea; if (iTab[op].op === -1) { var cyc, m = getEAMode(ea); if (dr == 0) { switch (m) { case M_ria: cyc = [8,2,0]; break; case M_ripr: cyc = [8,2,0]; break; case M_rid: cyc = [12,3,0]; break; case M_rii: cyc = [14,3,0]; break; case M_absw: cyc = [12,3,0]; break; case M_absl: cyc = [16,4,0]; break; } iTab[op] = mkI(op, "MOVEM", cyc); iTab[op].f = z2 == 2 ? I_MOVEM_R2M_16 : I_MOVEM_R2M_32; iTab[op].d = mkDiss(1, D_EXT_MOVEM,m == M_ripr, D_EA,ea, z2,0); } else { switch (m) { case M_ria: cyc = [12,3,0]; break; case M_ripo: cyc = [12,3,0]; break; case M_rid: cyc = [16,4,0]; break; case M_rii: cyc = [18,4,0]; break; case M_pcid: cyc = [16,4,0]; break; case M_pcii: cyc = [20,5,0]; break; case M_absw: cyc = [16,4,0]; break; case M_absl: cyc = [18,4,0]; break; } iTab[op] = mkI(op, "MOVEM", cyc); iTab[op].f = z2 == 2 ? I_MOVEM_M2R_16 : I_MOVEM_M2R_32; iTab[op].d = mkDiss(1, D_EA,ea, D_EXT_MOVEM,m == M_ripr, z2,0); } iTab[op].p.ea = ea; cnt++; } else { SAEF_error("cpu.mkITab() op exists MOVEM " + op); return false; } } } } } } //MOVEP { for (var m = 4; m < 8; m++) { for (var Dn = 0; Dn < 8; Dn++) { for (var An = 0; An < 8; An++) { op = (Dn << 9) | (m << 6) | (1 << 3) | An; if (iTab[op].op === -1) { if (m == 4) { iTab[op] = mkI(op, "MOVEP", [16,4,0]); iTab[op].f = I_MOVEP_M2R_16; iTab[op].d = mkDiss(0, D_RID,An, D_RDD,Dn, 2,0); } else if (m == 5) { iTab[op] = mkI(op, "MOVEP", [24,6,0]); iTab[op].f = I_MOVEP_M2R_32; iTab[op].d = mkDiss(0, D_RID,An, D_RDD,Dn, 4,0); } else if (m == 6) { iTab[op] = mkI(op, "MOVEP", [16,2,2]); iTab[op].f = I_MOVEP_R2M_16; iTab[op].d = mkDiss(0, D_RDD,Dn, D_RID,An, 2,0); } else { iTab[op] = mkI(op, "MOVEP", [24,2,4]); iTab[op].f = I_MOVEP_R2M_32; iTab[op].d = mkDiss(0, D_RDD,Dn, D_RID,An, 4,0); } iTab[op].p.Dn = Dn; iTab[op].p.An = An; cnt++; } else { SAEF_error("cpu.mkITab() op exists MOVEP " + op); return false; } } } } } /*-----------------------------------------------------------------------*/ /* Integer - Basic */ //ADD { var en = [M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var dir = 0; dir < 2; dir++) { for (var Dn = 0; Dn < 8; Dn++) { for (var ea = 0; ea < 61; ea++) { if (dir == 0 || (dir == 1 && isEA(ea, en))) { var m = getEAMode(ea); if (dir == 0 && m == M_rda && z == 0) continue; //An word and long only op = (13 << 12) | (Dn << 9) | (dir << 8) | (z << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "ADD", []); iTab[op].p.Dn = Dn; iTab[op].p.ea = ea; iTab[op].p.zm = z2 == 4 ? 0x80000000 : (z2 == 2 ? 0x8000 : 0x80); if (dir == 0) { iTab[op].p.cyc = addCycs(z2 == 4 ? (m == M_rdd || m == M_imm ? [8,1,0]:[6,1,0]) : [4,1,0], getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_ADD_ED_32 : (z2 == 2 ? I_ADD_ED_16 : I_ADD_ED_8); iTab[op].d = mkDiss(0, D_EA,ea, D_RDD,Dn, z2,0); } else { iTab[op].p.cyc = addCycs(z2 == 4 ? [12,1,2] : [8,1,1], getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_ADD_DE_32 : (z2 == 2 ? I_ADD_DE_16 : I_ADD_DE_8); iTab[op].d = mkDiss(0, D_RDD,Dn, D_EA,ea, z2,0); } cnt++; } else { SAEF_error("cpu.mkITab() op exists ADD " + op); return false; } } } } } } } //SUB { var en = [M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var dir = 0; dir < 2; dir++) { for (var Dn = 0; Dn < 8; Dn++) { for (var ea = 0; ea < 61; ea++) { if (dir == 0 || (dir == 1 && isEA(ea, en))) { var m = getEAMode(ea); if (dir == 0 && m == M_rda && z == 0) continue; //An word and long only op = (9 << 12) | (Dn << 9) | (dir << 8) | (z << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "SUB", []); iTab[op].p.Dn = Dn; iTab[op].p.ea = ea; iTab[op].p.zm = z2 == 4 ? 0x80000000 : (z2 == 2 ? 0x8000 : 0x80); if (dir == 0) { iTab[op].p.cyc = addCycs(z2 == 4 ? (m == M_rdd || m == M_imm ? [8,1,0]:[6,1,0]) : [4,1,0], getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_SUB_ED_32 : (z2 == 2 ? I_SUB_ED_16 : I_SUB_ED_8); iTab[op].d = mkDiss(0, D_EA,ea, D_RDD,Dn, z2,0); } else { iTab[op].p.cyc = addCycs(z2 == 4 ? [12,1,2] : [8,1,1], getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_SUB_DE_32 : (z2 == 2 ? I_SUB_DE_16 : I_SUB_DE_8); iTab[op].d = mkDiss(0, D_RDD,Dn, D_EA,ea, z2,0); } cnt++; } else { SAEF_error("cpu.mkITab() op exists SUB "+op); return false; } } } } } } } //CMP { for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var Dn = 0; Dn < 8; Dn++) { for (var ea = 0; ea < 61; ea++) { var m = getEAMode(ea); if (m == M_rda && z == 0) continue; //An word and long only op = (11 << 12) | (Dn << 9) | (z << 6) | ea; if (iTab[op].op === -1) { var cyc = z2 == 4 ? [6,1,0] : [4,1,0]; if (!(m == M_rdd || m == M_rda)) cyc = addCycs(cyc, getEACycs(ea, z2)); iTab[op] = mkI(op, "CMP", cyc); iTab[op].p.Dn = Dn; iTab[op].p.ea = ea; iTab[op].f = z2 == 4 ? I_CMP_32 : (z2 == 2 ? I_CMP_16 : I_CMP_8); iTab[op].d = mkDiss(0, D_EA,ea, D_RDD,Dn, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists CMP "+op); return false; } } } } } //CLR { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (66 << 8) | (z << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); var cyc = m == M_rdd ? (z2 == 4 ? [6,1,0]:[4,1,0]) : (z2 == 4 ? [12,1,2]:[8,1,1]); if (m == M_rdd) cyc = addCycs(cyc, getEACycs(ea, z2)); iTab[op] = mkI(op, "CLR", cyc); iTab[op].p.ea = ea; iTab[op].f = z2 == 4 ? I_CLR_32 : (z2 == 2 ? I_CLR_16 : I_CLR_8); iTab[op].d = mkDiss(0, false,false, D_EA,ea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists CLR "+op); return false; } } } } } //NEG { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (68 << 8) | (z << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); var cyc = m == M_rdd ? (z2 == 4 ? [6,1,0]:[4,1,0]) : (z2 == 4 ? [12,1,2]:[8,1,1]); iTab[op] = mkI(op, "NEG", cyc); if (m == M_rdd) { iTab[op].p.Dn = ea & 7; iTab[op].f = z2 == 4 ? I_NEG_D_32 : (z2 == 2 ? I_NEG_D_16 : I_NEG_D_8); } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_NEG_E_32 : (z2 == 2 ? I_NEG_E_16 : I_NEG_E_8); } iTab[op].d = mkDiss(0, false,false, D_EA,ea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists NEG "+op); return false; } } } } } //MULS { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm]; for (var Dn = 0; Dn < 8; Dn++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (12 << 12) | (Dn << 9) | (7 << 6) | ea; if (iTab[op].op === -1) { var avg = ((70 - 38) / 2 + 38) >>> 0; /* average */ var cyc = getEAMode(ea) == M_rdd ? [70,1,0] : addCycs([70,1,0], getEACycs(ea, z2)); iTab[op] = mkI(op, "MULS", cyc); iTab[op].p.Dn = Dn; iTab[op].p.ea = ea; iTab[op].f = I_MULS; iTab[op].d = mkDiss(0, D_EA,ea, D_RDD,Dn, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists MULS "+op); return false; } } } } } //MULU { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm]; for (var Dn = 0; Dn < 8; Dn++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (12 << 12) | (Dn << 9) | (3 << 6) | ea; if (iTab[op].op === -1) { var avg = ((70 - 38) / 2 + 38) >>> 0; /* average */ var cyc = getEAMode(ea) == M_rdd ? [avg,1,0] : addCycs([avg,1,0], getEACycs(ea, z2)); iTab[op] = mkI(op, "MULU", cyc); iTab[op].p.Dn = Dn; iTab[op].p.ea = ea; iTab[op].f = I_MULU; iTab[op].d = mkDiss(0, D_EA,ea, D_RDD,Dn, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists MULU "+op); return false; } } } } } //MULx if (model >= 68020) { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (304 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "MULx", [40,0,0]); //FIXME cycles iTab[op].p.ea = ea; iTab[op].f = I_MULx; iTab[op].d = mkDiss(1, D_EA,ea, D_EXT_MUL64,0, 4,0); //FIXME cnt++; } else { SAEF_error("cpu.mkITab() op exists MULx "+op); return false; } } } } //DIVS { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm]; for (var Dn = 0; Dn < 8; Dn++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (8 << 12) | (Dn << 9) | (7 << 6) | ea; if (iTab[op].op === -1) { var avg = (156 - (156 - 120) / 2) >>> 0; /* average */ var cyc = getEAMode(ea) == M_rdd ? [avg,1,0] : addCycs([avg,1,0], getEACycs(ea, z2)); iTab[op] = mkI(op, "DIVS", cyc); iTab[op].p.Dn = Dn; iTab[op].p.ea = ea; iTab[op].f = I_DIVS; iTab[op].d = mkDiss(0, D_EA,ea, D_RDD,Dn, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists DIVS "+op); return false; } } } } } //DIVU { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm]; for (var Dn = 0; Dn < 8; Dn++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (8 << 12) | (Dn << 9) | (3 << 6) | ea; if (iTab[op].op === -1) { var avg = (136 - (136 - 76) / 2) >>> 0; /* average */ var cyc = getEAMode(ea) == M_rdd ? [avg,1,0] : addCycs([avg,1,0], getEACycs(ea, z2)); iTab[op] = mkI(op, "DIVU", cyc); iTab[op].p.Dn = Dn; iTab[op].p.ea = ea; iTab[op].f = I_DIVU; iTab[op].d = mkDiss(0, D_EA,ea, D_RDD,Dn, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists DIVU "+op); return false; } } } } } //DIVx if (model >= 68020) { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (305 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "DIVx", [70,0,0]); //FIXME cycles iTab[op].p.ea = ea; iTab[op].f = I_DIVx; iTab[op].d = mkDiss(1, D_EA,ea, D_EXT_DIV64,0, 4,0); //FIXME cnt++; } else { SAEF_error("cpu.mkITab() op exists DIVx "+op); return false; } } } } /*-----------------------------------------------------------------------*/ /* Integer - Extended */ //ADDX { for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var rm = 0; rm < 2; rm++) { for (var Rx = 0; Rx < 8; Rx++) { for (var Ry = 0; Ry < 8; Ry++) { op = (13 << 12) | (Rx << 9) | (1 << 8) | (z << 6) | (rm << 3) | Ry; if (iTab[op].op === -1) { var cyc = rm == 0 ? (z2 == 4 ? [8,1,0] : [4,1,0]) : (z2 == 4 ? [30,5,2] : [18,3,1]); iTab[op] = mkI(op, "ADDX", cyc); iTab[op].p.Rx = Rx; iTab[op].p.Ry = Ry; if (rm == 0) { iTab[op].f = z2 == 4 ? I_ADDX_D_32 : (z2 == 2 ? I_ADDX_D_16 : I_ADDX_D_8); iTab[op].d = mkDiss(0, D_RDD,Ry, D_RDD,Rx, z2,0); } else { iTab[op].f = z2 == 4 ? I_ADDX_M_32 : (z2 == 2 ? I_ADDX_M_16 : I_ADDX_M_8); iTab[op].d = mkDiss(0, D_RIPR,Ry, D_RIPR,Rx, z2,0); } cnt++; } else { SAEF_error("cpu.mkITab() op exists ADDX "+op); return false; } } } } } } //SUBX { for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var rm = 0; rm < 2; rm++) { for (var Rx = 0; Rx < 8; Rx++) { for (var Ry = 0; Ry < 8; Ry++) { op = (9 << 12) | (Ry << 9) | (1 << 8) | (z << 6) | (rm << 3) | Rx; if (iTab[op].op === -1) { var cyc = rm == 0 ? (z2 == 4 ? [8,1,0] : [4,1,0]) : (z2 == 4 ? [30,5,2] : [18,3,1]); iTab[op] = mkI(op, "SUBX", cyc); iTab[op].p.Rx = Rx; iTab[op].p.Ry = Ry; if (rm == 0) { iTab[op].f = z2 == 4 ? I_SUBX_D_32 : (z2 == 2 ? I_SUBX_D_16 : I_SUBX_D_8); iTab[op].d = mkDiss(0, D_RDD,Rx, D_RDD,Ry, z2,0); } else { iTab[op].f = z2 == 4 ? I_SUBX_M_32 : (z2 == 2 ? I_SUBX_M_16 : I_SUBX_M_8); iTab[op].d = mkDiss(0, D_RIPR,Rx, D_RIPR,Ry, z2,0); } cnt++; } else { SAEF_error("cpu.mkITab() op exists SUBX "+op); return false; } } } } } } //NEGX { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (64 << 8) | (z << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); var cyc = m == M_rdd ? (z2 == 4 ? [6,1,0]:[4,1,0]) : (z2 == 4 ? [12,1,2]:[8,1,1]); iTab[op] = mkI(op, "NEGX", cyc); if (m == M_rdd) { iTab[op].p.Dn = ea & 7; iTab[op].f = z2 == 4 ? I_NEGX_D_32 : (z2 == 2 ? I_NEGX_D_16 : I_NEGX_D_8); } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_NEGX_E_32 : (z2 == 2 ? I_NEGX_E_16 : I_NEGX_E_8); } iTab[op].d = mkDiss(0, false,false, D_EA,ea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists NEGX "+op); return false; } } } } } /*-----------------------------------------------------------------------*/ /* Integer - Address */ //ADDA { for (var z = 1; z < 3; z++) { var z2 = z == 1 ? 2 : 4; var z3 = z == 1 ? 3 : 7; for (var An = 0; An < 8; An++) { for (var ea = 0; ea < 61; ea++) { op = (13 << 12) | (An << 9) | (z3 << 6) | ea; if (iTab[op].op === -1) { var cyc = z2 == 4 ? (m == M_rdd || m == M_rda || m == M_imm ? [8,1,0] : [6,1,0]) : [8,1,0]; if (!(m == M_rdd || m == M_rda)) cyc = addCycs(cyc, getEACycs(ea, z2)); iTab[op] = mkI(op, "ADDA", cyc); iTab[op].p.An = An; iTab[op].p.ea = ea; iTab[op].f = z2 == 4 ? I_ADDA_32 : I_ADDA_16; iTab[op].d = mkDiss(0, D_EA,ea, D_RDA,An, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ADDA "+op); return false; } } } } } //SUBA { for (var z = 1; z < 3; z++) { var z2 = z == 1 ? 2 : 4; var z3 = z == 1 ? 3 : 7; for (var An = 0; An < 8; An++) { for (var ea = 0; ea < 61; ea++) { op = (9 << 12) | (An << 9) | (z3 << 6) | ea; if (iTab[op].op === -1) { var cyc = z2 == 4 ? (m == M_rdd || m == M_rda || m == M_imm ? [8,1,0] : [6,1,0]) : [8,1,0]; if (!(m == M_rdd || m == M_rda)) cyc = addCycs(cyc, getEACycs(ea, z2)); iTab[op] = mkI(op, "SUBA", cyc); iTab[op].p.An = An; iTab[op].p.ea = ea; iTab[op].f = z2 == 4 ? I_SUBA_32 : I_SUBA_16; iTab[op].d = mkDiss(0, D_EA,ea, D_RDA,An, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists SUBA "+op); return false; } } } } } //CMPA { for (var z = 1; z < 3; z++) { var z2 = z == 1 ? 2 : 4; var z3 = z == 1 ? 3 : 7; for (var An = 0; An < 8; An++) { for (var ea = 0; ea < 61; ea++) { op = (11 << 12) | (An << 9) | (z3 << 6) | ea; if (iTab[op].op === -1) { var cyc = [6,1,0]; if (!(m == M_rdd || m == M_rda)) cyc = addCycs(cyc, getEACycs(ea, z2)); iTab[op] = mkI(op, "CMPA", cyc); iTab[op].p.An = An; iTab[op].p.ea = ea; iTab[op].f = z2 == 4 ? I_CMPA_32 : I_CMPA_16; iTab[op].d = mkDiss(0, D_EA,ea, D_RDA,An, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists CMPA "+op); return false; } } } } } /*-----------------------------------------------------------------------*/ /* Integer - Immediate */ //ADDI { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (6 << 8) | (z << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); var cyc = m == M_rdd ? (z2 == 4 ? [16,3,0]:[8,2,0]) : (z2 == 4 ? [20,3,2]:[12,2,1]); iTab[op] = mkI(op, "ADDI", cyc); if (m == M_rdd) { iTab[op].p.Dn = ea & 7; iTab[op].f = z2 == 4 ? I_ADDI_D_32 : (z2 == 2 ? I_ADDI_D_16 : I_ADDI_D_8); } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_ADDI_E_32 : (z2 == 2 ? I_ADDI_E_16 : I_ADDI_E_8); } iTab[op].d = mkDiss(0, D_IME,z2 == 4 ? 2 : 1, D_EA,ea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ADDI "+op); return false; } } } } } //SUBI { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (4 << 8) | (z << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); var cyc = m == M_rdd ? (z2 == 4 ? [16,3,0]:[8,2,0]) : (z2 == 4 ? [20,3,2]:[12,2,1]); iTab[op] = mkI(op, "SUBI", cyc); if (m == M_rdd) { iTab[op].p.Dn = ea & 7; iTab[op].f = z2 == 4 ? I_SUBI_D_32 : (z2 == 2 ? I_SUBI_D_16 : I_SUBI_D_8); } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_SUBI_E_32 : (z2 == 2 ? I_SUBI_E_16 : I_SUBI_E_8); } iTab[op].d = mkDiss(0, D_IME,z2 == 4 ? 2 : 1, D_EA,ea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists SUBI "+op); return false; } } } } } //CMPI { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; if (model >= 68020) en.push(M_pcid, M_pcii); for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (12 << 8) | (z << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); var cyc = m == M_rdd ? (z2 == 4 ? [14,3,0]:[8,2,0]) : (z2 == 4 ? [12,3,0]:[8,2,0]); if (m != M_rdd) cyc = addCycs(cyc, getEACycs(ea, z2)); iTab[op] = mkI(op, "CMPI", cyc); iTab[op].p.ea = ea; iTab[op].f = z2 == 4 ? I_CMPI_32 : (z2 == 2 ? I_CMPI_16 : I_CMPI_8); iTab[op].d = mkDiss(0, D_IME,z2 == 4 ? 2 : 1, D_EA,ea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists CMPI "+op); return false; } } } } } /*-----------------------------------------------------------------------*/ /* Integer - Quick */ //ADDQ { var en = [M_rdd, M_rda, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var id = 0; id < 8; id++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { var m = getEAMode(ea); if (m == M_rda && z == 0) continue; //An word and long only op = (5 << 12) | (id << 9) | (z << 6) | ea; if (iTab[op].op === -1) { var cyc = m == M_rda ? [8,1,0] : (m == M_rdd ? (z2 == 4 ? [8,1,0]:[4,1,0]) : (z2 == 4 ? [12,1,2]:[8,1,1])); iTab[op] = mkI(op, "ADDQ", cyc); iTab[op].p.data = id == 0 ? 8 : id; if (m == M_rdd) { iTab[op].p.Dn = ea & 7; iTab[op].f = z2 == 4 ? I_ADDQ_D_32 : (z2 == 2 ? I_ADDQ_D_16 : I_ADDQ_D_8); } else if (m == M_rda) { iTab[op].p.An = ea & 7; iTab[op].f = I_ADDQ_A_32; } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_ADDQ_E_32 : (z2 == 2 ? I_ADDQ_E_16 : I_ADDQ_E_8); } iTab[op].d = mkDiss(0, D_IMD,id == 0 ? 8 : id, D_EA,ea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ADDQ " + op); return false; } } } } } } //SUBQ { var en = [M_rdd, M_rda, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var id = 0; id < 8; id++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { var m = getEAMode(ea); if (m == M_rda && z == 0) continue; //An word and long only op = (5 << 12) | (id << 9) | (1 << 8) | (z << 6) | ea; if (iTab[op].op === -1) { var cyc = m == M_rda ? [8,1,0] : (m == M_rdd ? (z2 == 4 ? [8,1,0]:[4,1,0]) : (z2 == 4 ? [12,1,2]:[8,1,1])); iTab[op] = mkI(op, "SUBQ", cyc); iTab[op].p.data = id == 0 ? 8 : id; if (m == M_rdd) { iTab[op].p.Dn = ea & 7; iTab[op].f = z2 == 4 ? I_SUBQ_D_32 : (z2 == 2 ? I_SUBQ_D_16 : I_SUBQ_D_8); } else if (m == M_rda) { iTab[op].p.An = ea & 7; iTab[op].f = I_SUBQ_A_32; } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_SUBQ_E_32 : (z2 == 2 ? I_SUBQ_E_16 : I_SUBQ_E_8); } iTab[op].d = mkDiss(0, D_IMD,id == 0 ? 8 : id, D_EA,ea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists SUBQ " + op); return false; } } } } } } /*-----------------------------------------------------------------------*/ /* Integer - Misc */ //CMPM { for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var Ax = 0; Ax < 8; Ax++) { for (var Ay = 0; Ay < 8; Ay++) { op = (11 << 12) | (Ax << 9) | (1 << 8) | (z << 6) | (1 << 3) | Ay; if (iTab[op].op === -1) { iTab[op] = mkI(op, "CMPM", z2 == 4 ? [20,5,0] : [12,3,0]); iTab[op].p.Ax = Ax; iTab[op].p.Ay = Ay; iTab[op].f = z2 == 4 ? I_CMPM_32 : (z2 == 2 ? I_CMPM_16 : I_CMPM_8); iTab[op].d = mkDiss(0, D_RIPO,Ay, D_RIPO,Ax, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists CMPM "+op); return false; } } } } } //EXT { for (var z = 1; z < 3; z++) { var z2 = z == 1 ? 2 : 4; var opm = z == 1 ? 2 : 3; for (var Dn = 0; Dn < 8; Dn++) { op = (36 << 9) | (opm << 6) | Dn; if (iTab[op].op === -1) { iTab[op] = mkI(op, "EXT", [4,1,0]); iTab[op].p.Dn = Dn; iTab[op].f = z2 == 4 ? I_EXT_32 : I_EXT_16; iTab[op].d = mkDiss(0, false,false, D_RDD,Dn, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists EXT "+op); return false; } } } } //EXTB if (model >= 68020) { for (var Dn = 0; Dn < 8; Dn++) { op = (36 << 9) | (7 << 6) | Dn; if (iTab[op].op === -1) { iTab[op] = mkI(op, "EXTB", [4,1,0]); iTab[op].p.Dn = Dn; iTab[op].f = I_EXTB; iTab[op].d = mkDiss(0, false,false, D_RDD,Dn, 4,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists EXTB "+op); return false; } } } /*-----------------------------------------------------------------------*/ /* Logical */ //AND { var en0 = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm]; var en1 = [M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var dir = 0; dir < 2; dir++) { for (var Dn = 0; Dn < 8; Dn++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, dir == 0 ? en0 : en1)) { op = (12 << 12) | (Dn << 9) | (dir << 8) | (z << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "AND", []); iTab[op].p.Dn = Dn; iTab[op].p.ea = ea; iTab[op].p.zm = z2 == 4 ? 0x80000000 : (z2 == 2 ? 0x8000 : 0x80); if (dir == 0) { var m = getEAMode(ea); iTab[op].p.cyc = addCycs(z2 == 4 ? (m == M_rdd || m == M_imm ? [8,1,0]:[6,1,0]) : [4,1,0], getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_AND_D_32 : (z2 == 2 ? I_AND_D_16 : I_AND_D_8); iTab[op].d = mkDiss(0, D_EA,ea, D_RDD,Dn, z2,0); } else { iTab[op].p.cyc = addCycs(z2 == 4 ? [12,1,2] : [8,1,1], getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_AND_E_32 : (z2 == 2 ? I_AND_E_16 : I_AND_E_8); iTab[op].d = mkDiss(0, D_RDD,Dn, D_EA,ea, z2,0); } cnt++; } else { SAEF_error("cpu.mkITab() op exists AND "+op); return false; } } } } } } } //EOR { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); var z3 = z == 0 ? 4 : (z == 1 ? 5 : 6); for (var Dn = 0; Dn < 8; Dn++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (11 << 12) | (Dn << 9) | (z3 << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); iTab[op] = mkI(op, "EOR", z2 == 4 ? [8,1,0] : [4,1,0]); iTab[op].p.Dn = Dn; iTab[op].p.zm = z2 == 4 ? 0x80000000 : (z2 == 2 ? 0x8000 : 0x80); if (m == M_rdd) { iTab[op].p.Dd = ea & 7; iTab[op].f = z2 == 4 ? I_EOR_D_32 : (z2 == 2 ? I_EOR_D_16 : I_EOR_D_8); } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_EOR_E_32 : (z2 == 2 ? I_EOR_E_16 : I_EOR_E_8); } iTab[op].d = mkDiss(0, D_RDD,Dn, D_EA,ea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists EOR "+op); return false; } } } } } } //OR { var en0 = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm]; var en1 = [M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var dir = 0; dir < 2; dir++) { for (var Dn = 0; Dn < 8; Dn++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, dir == 0 ? en0 : en1)) { op = (8 << 12) | (Dn << 9) | (dir << 8) | (z << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "OR", []); iTab[op].p.Dn = Dn; iTab[op].p.ea = ea; iTab[op].p.zm = z2 == 4 ? 0x80000000 : (z2 == 2 ? 0x8000 : 0x80); if (dir == 0) { var m = getEAMode(ea); iTab[op].p.cyc = addCycs(z2 == 4 ? (m == M_rdd || m == M_imm ? [8,1,0]:[6,1,0]) : [4,1,0], getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_OR_D_32 : (z2 == 2 ? I_OR_D_16 : I_OR_D_8); iTab[op].d = mkDiss(0, D_EA,ea, D_RDD,Dn, z2,0); } else { iTab[op].p.cyc = addCycs(z2 == 4 ? [12,1,2] : [8,1,1], getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_OR_E_32 : (z2 == 2 ? I_OR_E_16 : I_OR_E_8); iTab[op].d = mkDiss(0, D_RDD,Dn, D_EA,ea, z2,0); } cnt++; } else { SAEF_error("cpu.mkITab() op exists OR " + op); return false; } } } } } } } //NOT { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (70 << 8) | (z << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); var cyc = m == M_rdd ? (z2 == 4 ? [6,1,0]:[4,1,0]) : (z2 == 4 ? [12,1,2]:[8,1,1]); iTab[op] = mkI(op, "NOT", cyc); if (m == M_rdd) { iTab[op].p.Dn = ea & 7; iTab[op].f = z2 == 4 ? I_NOT_D_32 : (z2 == 2 ? I_NOT_D_16 : I_NOT_D_8); } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_NOT_E_32 : (z2 == 2 ? I_NOT_E_16 : I_NOT_E_8); } iTab[op].p.m = z2 == 4 ? 0xffffffff : (z2 == 2 ? 0xffff : 0xff); iTab[op].p.zm = z2 == 4 ? 0x80000000 : (z2 == 2 ? 0x8000 : 0x80); iTab[op].d = mkDiss(0, false,false, D_EA,ea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists NOT "+op); return false; } } } } } //ANDI { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (2 << 8) | (z << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); var cyc = m == M_rdd ? (z2 == 4 ? [16,3,0]:[8,2,0]) : (z2 == 4 ? [20,3,1]:[12,2,1]) iTab[op] = mkI(op, "ANDI", cyc); if (m == M_rdd) { iTab[op].p.Dn = ea & 7; iTab[op].f = z2 == 4 ? I_ANDI_D_32 : (z2 == 2 ? I_ANDI_D_16 : I_ANDI_D_8); } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_ANDI_E_32 : (z2 == 2 ? I_ANDI_E_16 : I_ANDI_E_8); } iTab[op].p.zm = z2 == 4 ? 0x80000000 : (z2 == 2 ? 0x8000 : 0x80); iTab[op].d = mkDiss(0, D_IME,z2 == 4 ? 2 : 1, D_EA,ea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ANDI "+op); return false; } } } } } //EORI { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (10 << 8) | (z << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); var cyc = m == M_rdd ? (z2 == 4 ? [16,3,0]:[8,2,0]) : (z2 == 4 ? [20,3,1]:[12,2,1]) iTab[op] = mkI(op, "EORI", cyc); if (m == M_rdd) { iTab[op].p.Dn = ea & 7; iTab[op].f = z2 == 4 ? I_EORI_D_32 : (z2 == 2 ? I_EORI_D_16 : I_EORI_D_8); } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_EORI_E_32 : (z2 == 2 ? I_EORI_E_16 : I_EORI_E_8); } iTab[op].p.zm = z2 == 4 ? 0x80000000 : (z2 == 2 ? 0x8000 : 0x80); iTab[op].d = mkDiss(0, D_IME,z2 == 4 ? 2 : 1, D_EA,ea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists EORI "+op); return false; } } } } } //ORI { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (z << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); var cyc = m == M_rdd ? (z2 == 4 ? [16,3,0]:[8,2,0]) : (z2 == 4 ? [20,3,1]:[12,2,1]) iTab[op] = mkI(op, "ORI", cyc); if (m == M_rdd) { iTab[op].p.Dn = ea & 7; iTab[op].f = z2 == 4 ? I_ORI_D_32 : (z2 == 2 ? I_ORI_D_16 : I_ORI_D_8); } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, z2)); iTab[op].f = z2 == 4 ? I_ORI_E_32 : (z2 == 2 ? I_ORI_E_16 : I_ORI_E_8); } iTab[op].p.zm = z2 == 4 ? 0x80000000 : (z2 == 2 ? 0x8000 : 0x80); iTab[op].d = mkDiss(0, D_IME,z2 == 4 ? 2 : 1, D_EA,ea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ORI "+op); return false; } } } } } /*-----------------------------------------------------------------------*/ /* Shift and Rotate */ //ASL,ASR { for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var dr = 0; dr < 2; dr++) { for (var ir = 0; ir < 2; ir++) { for (var cr = 0; cr < 8; cr++) { for (var Dy = 0; Dy < 8; Dy++) { op = (14 << 12) | (cr << 9) | (dr << 8) | (z << 6) | (ir << 5) | Dy; if (iTab[op].op === -1) { iTab[op] = mkI(op, dr == 0 ? "ASR" : "ASL", z2 == 4 ? [8,1,0] : [6,1,0]); iTab[op].p.ir = ir; iTab[op].p.cr = ir == 0 ? (cr == 0 ? 8 : cr) : cr; iTab[op].p.Dy = Dy; if (dr == 0) iTab[op].f = z2 == 4 ? I_ASR_32 : (z2 == 2 ? I_ASR_16 : I_ASR_8); else iTab[op].f = z2 == 4 ? I_ASL_32 : (z2 == 2 ? I_ASL_16 : I_ASL_8); iTab[op].d = mkDiss(0, ir == 0 ? D_IMD : D_RDD,ir == 0 ? (cr == 0 ? 8 : cr) : cr, D_RDD,Dy, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ASx "+op); return false; } } } } } } var en = [M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var dr = 0; dr < 2; dr++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (112 << 9) | (dr << 8) | (3 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, dr == 0 ? "ASR" : "ASL", addCycs([8,1,1], getEACycs(ea, 2))); iTab[op].p.ea = ea; iTab[op].f = dr == 0 ? I_ASR_M : I_ASL_M; iTab[op].d = mkDiss(0, false,false, D_EA,ea, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ASx "+op); return false; } } } } } //LSL,LSR { for (var z = 0; z < 3; z++) { z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var dr = 0; dr < 2; dr++) { for (var ir = 0; ir < 2; ir++) { for (var cr = 0; cr < 8; cr++) { for (var Dy = 0; Dy < 8; Dy++) { op = (14 << 12) | (cr << 9) | (dr << 8) | (z << 6) | (ir << 5) | (1 << 3) | Dy; if (iTab[op].op === -1) { iTab[op] = mkI(op, dr == 0 ? "LSR" : "LSL", z2 == 4 ? [8,1,0] : [6,1,0]); iTab[op].p.ir = ir; iTab[op].p.cr = ir == 0 ? (cr == 0 ? 8 : cr) : cr; iTab[op].p.Dy = Dy; if (dr == 0) iTab[op].f = z2 == 4 ? I_LSR_32 : (z2 == 2 ? I_LSR_16 : I_LSR_8); else iTab[op].f = z2 == 4 ? I_LSL_32 : (z2 == 2 ? I_LSL_16 : I_LSL_8); iTab[op].d = mkDiss(0, ir == 0 ? D_IMD : D_RDD,ir == 0 ? (cr == 0 ? 8 : cr) : cr, D_RDD,Dy, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists LSx "+op); return false; } } } } } } var en = [M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var dr = 0; dr < 2; dr++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (113 << 9) | (dr << 8) | (3 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, dr == 0 ? "LSR" : "LSL", addCycs([8,1,1], getEACycs(ea, 2))); iTab[op].p.ea = ea; iTab[op].f = dr == 0 ? I_LSR_M : I_LSL_M; iTab[op].d = mkDiss(0, false,false, D_EA,ea, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists LSx "+op); return false; } } } } } //ROL,ROR { for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var dr = 0; dr < 2; dr++) { for (var ir = 0; ir < 2; ir++) { for (var cr = 0; cr < 8; cr++) { for (var Dy = 0; Dy < 8; Dy++) { op = (14 << 12) | (cr << 9) | (dr << 8) | (z << 6) | (ir << 5) | (3 << 3) | Dy; if (iTab[op].op === -1) { iTab[op] = mkI(op, dr == 0 ? "ROR" : "ROL", z2 == 4 ? [8,1,0] : [6,1,0]); iTab[op].p.ir = ir; iTab[op].p.cr = ir == 0 ? (cr == 0 ? 8 : cr) : cr; iTab[op].p.Dy = Dy; if (dr == 0) iTab[op].f = z2 == 4 ? I_ROR_32 : (z2 == 2 ? I_ROR_16 : I_ROR_8); else iTab[op].f = z2 == 4 ? I_ROL_32 : (z2 == 2 ? I_ROL_16 : I_ROL_8); iTab[op].d = mkDiss(0, ir == 0 ? D_IMD : D_RDD,ir == 0 ? (cr == 0 ? 8 : cr) : cr, D_RDD,Dy, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ROx "+op); return false; } } } } } } var en = [M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var dr = 0; dr < 2; dr++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (115 << 9) | (dr << 8) | (3 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, dr == 0 ? "ROR" : "ROL", addCycs([8,1,1], getEACycs(ea, 2))); iTab[op].p.ea = ea; iTab[op].f = dr == 0 ? I_ROR_M : I_ROL_M; iTab[op].d = mkDiss(0, false,false, D_EA,ea, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ROx "+op); return false; } } } } } //ROXL,ROXR { for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var dr = 0; dr < 2; dr++) { for (var ir = 0; ir < 2; ir++) { for (var cr = 0; cr < 8; cr++) { for (var Dy = 0; Dy < 8; Dy++) { op = (14 << 12) | (cr << 9) | (dr << 8) | (z << 6) | (ir << 5) | (2 << 3) | Dy; if (iTab[op].op === -1) { iTab[op] = mkI(op, dr == 0 ? "ROR" : "ROL", z2 == 4 ? [8,1,0] : [6,1,0]); iTab[op].p.ir = ir; iTab[op].p.cr = ir == 0 ? (cr == 0 ? 8 : cr) : cr; iTab[op].p.Dy = Dy; if (dr == 0) iTab[op].f = z2 == 4 ? I_ROXR_32 : (z2 == 2 ? I_ROXR_16 : I_ROXR_8); else iTab[op].f = z2 == 4 ? I_ROXL_32 : (z2 == 2 ? I_ROXL_16 : I_ROXL_8); iTab[op].d = mkDiss(0, ir == 0 ? D_IMD : D_RDD,ir == 0 ? (cr == 0 ? 8 : cr) : cr, D_RDD,Dy, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ROx "+op); return false; } } } } } } var en = [M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var dr = 0; dr < 2; dr++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (114 << 9) | (dr << 8) | (3 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, dr == 0 ? "ROXR" : "ROXL", addCycs([8,1,1], getEACycs(ea, 2))); iTab[op].p.ea = ea; iTab[op].f = dr == 0 ? I_ROXR_M : I_ROXL_M; iTab[op].d = mkDiss(0, false,false, D_EA,ea, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ROx "+op); return false; } } } } } //SWAP { for (var Dn = 0; Dn < 8; Dn++) { op = (2312 << 3) | Dn; if (iTab[op].op === -1) { iTab[op] = mkI(op, "SWAP", [4,1,0]); iTab[op].p.Dn = Dn; iTab[op].f = I_SWAP; iTab[op].d = mkDiss(0, false,false, D_RDD,Dn, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists SWAP "+op); return false; } } } /*-----------------------------------------------------------------------*/ /* Bit Manipulation */ //BCHG { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var Dn = 0; Dn < 8; Dn++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (Dn << 9) | (5 << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); iTab[op] = mkI(op, "BCHG", m == M_rdd ? [8,1,0]:[8,1,1]); iTab[op].p.Dn = Dn; if (m == M_rdd) { iTab[op].p.Dd = ea & 7; iTab[op].f = I_BCHG_DD_32; } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, 1)); iTab[op].f = I_BCHG_DE_8; } iTab[op].d = mkDiss(0, D_RDD,Dn, D_EA,ea, m == M_rdd ? 4 : 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BCHG1 "+op); return false; } } } } for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (33 << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); iTab[op] = mkI(op, "BCHG", m == M_rdd ? [12,2,0]:[12,2,1]); if (m == M_rdd) { iTab[op].p.Dd = ea & 7; iTab[op].f = I_BCHG_ID_32; } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, 1)); iTab[op].f = I_BCHG_IE_8; } iTab[op].d = mkDiss(0, D_IME,1, D_EA,ea, m == M_rdd ? 4 : 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BCHG "+op); return false; } } } } //BCLR { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var Dn = 0; Dn < 8; Dn++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (Dn << 9) | (6 << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); iTab[op] = mkI(op, "BCLR", m == M_rdd ? [10,1,0]:[8,1,1]); iTab[op].p.Dn = Dn; if (m == M_rdd) { iTab[op].p.Dd = ea & 7; iTab[op].f = I_BCLR_DD_32; } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, 1)); iTab[op].f = I_BCLR_DE_8; } iTab[op].d = mkDiss(0, D_RDD,Dn, D_EA,ea, m == M_rdd ? 4 : 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BCLR "+op); return false; } } } } for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (34 << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); iTab[op] = mkI(op, "BCLR", m == M_rdd ? [14,2,0]:[12,2,1]); if (m == M_rdd) { iTab[op].p.Dd = ea & 7; iTab[op].f = I_BCLR_ID_32; } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, 1)); iTab[op].f = I_BCLR_IE_8; } iTab[op].d = mkDiss(0, D_IME,1, D_EA,ea, m == M_rdd ? 4 : 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BCLR "+op); return false; } } } } //BSET { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var Dn = 0; Dn < 8; Dn++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (Dn << 9) | (7 << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); iTab[op] = mkI(op, "BSET", m == M_rdd ? [8,1,0]:[8,1,1]); iTab[op].p.Dn = Dn; if (m == M_rdd) { iTab[op].p.Dd = ea & 7; iTab[op].f = I_BSET_DD_32; } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, 1)); iTab[op].f = I_BSET_DE_8; } iTab[op].d = mkDiss(0, D_RDD,Dn, D_EA,ea, m == M_rdd ? 4 : 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BSET "+op); return false; } } } } for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (35 << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); iTab[op] = mkI(op, "BSET", m == M_rdd ? [12,2,0]:[12,2,1]); if (m == M_rdd) { iTab[op].p.Dd = ea & 7; iTab[op].f = I_BSET_ID_32; } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, 1)); iTab[op].f = I_BSET_IE_8; } iTab[op].d = mkDiss(0, D_IME,1, D_EA,ea, m == M_rdd ? 4 : 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BSET "+op); return false; } } } } //BTST { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm]; for (var Dn = 0; Dn < 8; Dn++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (Dn << 9) | (4 << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); iTab[op] = mkI(op, "BTST", m == M_rdd ? [6,1,0]:[4,1,0]); iTab[op].p.Dn = Dn; if (m == M_rdd) { iTab[op].p.Dd = ea & 7; iTab[op].f = I_BTST_DD_32; } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, 1)); iTab[op].f = I_BTST_DE_8; } iTab[op].d = mkDiss(0, D_RDD,Dn, D_EA,ea, m == M_rdd ? 4 : 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BTST "+op); return false; } } } } en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (32 << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); iTab[op] = mkI(op, "BTST", m == M_rdd ? [12,2,0]:[8,2,0]); if (m == M_rdd) { iTab[op].p.Dd = ea & 7; iTab[op].f = I_BTST_ID_32; } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, 1)); iTab[op].f = I_BTST_IE_8; } iTab[op].d = mkDiss(0, D_IME,1, D_EA,ea, m == M_rdd ? 4 : 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BTST "+op); return false; } } } } /*-----------------------------------------------------------------------*/ /* Bitfield >= 68020 */ //BFCHG if (model >= 68020) { var en = [M_rdd, M_ria, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (939 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "BFCHG", [4,1,0]); //FIXME cycles iTab[op].p.id = ID_BFCHG; iTab[op].p.ea = ea; iTab[op].f = I_BFXXX; iTab[op].d = mkDiss(1, D_EA,ea, D_EXT_BITFIELD,0, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BFCHG "+op); return false; } } } } //BFCLR if (model >= 68020) { var en = [M_rdd, M_ria, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (947 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "BFCLR", [4,1,0]); //FIXME cycles iTab[op].p.id = ID_BFCLR; iTab[op].p.ea = ea; iTab[op].f = I_BFXXX; iTab[op].d = mkDiss(1, D_EA,ea, D_EXT_BITFIELD,0, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BFCLR "+op); return false; } } } } //BFEXTS if (model >= 68020) { var en = [M_rdd, M_ria, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (943 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "BFEXTS", [4,1,0]); //FIXME cycles iTab[op].p.id = ID_BFEXTS; iTab[op].p.ea = ea; iTab[op].f = I_BFXXX; iTab[op].d = mkDiss(1, D_EA,ea, D_EXT_BITFIELD,0, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BFEXTS "+op); return false; } } } } //BFEXTU if (model >= 68020) { var en = [M_rdd, M_ria, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (935 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "BFEXTU", [4,1,0]); //FIXME cycles iTab[op].p.id = ID_BFEXTU; iTab[op].p.ea = ea; iTab[op].f = I_BFXXX; iTab[op].d = mkDiss(1, D_EA,ea, D_EXT_BITFIELD,0, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BFEXTU "+op); return false; } } } } //BFFFO if (model >= 68020) { var en = [M_rdd, M_ria, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (951 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "BFFFO", [4,1,0]); //FIXME cycles iTab[op].p.id = ID_BFFFO; iTab[op].p.ea = ea; iTab[op].f = I_BFXXX; iTab[op].d = mkDiss(1, D_EA,ea, D_EXT_BITFIELD,0, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BFFFO "+op); return false; } } } } //BFINS if (model >= 68020) { var en = [M_rdd, M_ria, M_rid, M_rii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (959 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "BFINS", [4,1,0]); //FIXME cycles iTab[op].p.id = ID_BFINS; iTab[op].p.ea = ea; iTab[op].f = I_BFXXX; iTab[op].d = mkDiss(1, D_EA,ea, D_EXT_BITFIELD,0, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BFINS "+op); return false; } } } } //BFSET if (model >= 68020) { var en = [M_rdd, M_ria, M_rid, M_rii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (955 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "BFSET", [4,1,0]); //FIXME cycles iTab[op].p.id = ID_BFSET; iTab[op].p.ea = ea; iTab[op].f = I_BFXXX; iTab[op].d = mkDiss(1, D_EA,ea, D_EXT_BITFIELD,0, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BFSET "+op); return false; } } } } //BFTST if (model >= 68020) { var en = [M_rdd, M_ria, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (931 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "BFTST", [4,1,0]); //FIXME cycles iTab[op].p.id = ID_BFTST; iTab[op].p.ea = ea; iTab[op].f = I_BFXXX; iTab[op].d = mkDiss(1, D_EA,ea, D_EXT_BITFIELD,0, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BFTST "+op); return false; } } } } /*-----------------------------------------------------------------------*/ /* Binary-Coded Decimal */ //ABCD { for (var Rx = 0; Rx < 8; Rx++) { for (var rm = 0; rm < 2; rm++) { for (var Ry = 0; Ry < 8; Ry++) { op = (12 << 12) | (Rx << 9) | (1 << 8) | (rm << 3) | Ry; if (iTab[op].op === -1) { iTab[op] = mkI(op, "ABCD", rm == 0 ? [6,1,0] : [18,3,1]); iTab[op].p.Rx = Rx; iTab[op].p.Ry = Ry; if (rm == 0) { iTab[op].f = I_ABCD_D; iTab[op].d = mkDiss(0, D_RDD,Ry, D_RDD,Rx, 1,0); } else { iTab[op].f = I_ABCD_A; iTab[op].d = mkDiss(0, D_RIPR,Ry, D_RIPR,Rx, 1,0); } cnt++; } else { SAEF_error("cpu.mkITab() op exists ABCD "+op); return false; } } } } } //SBCD { for (var Ry = 0; Ry < 8; Ry++) { for (var rm = 0; rm < 2; rm++) { for (var Rx = 0; Rx < 8; Rx++) { op = (8 << 12) | (Ry << 9) | (1 << 8) | (rm << 3) | Rx; if (iTab[op].op === -1) { iTab[op] = mkI(op, "SBCD", rm == 0 ? [6,1,0] : [18,3,1]); iTab[op].p.Ry = Ry; iTab[op].p.Rx = Rx; if (rm == 0) { iTab[op].f = I_SBCD_D; iTab[op].d = mkDiss(0, D_RDD,Rx, D_RDD,Ry, 1,0); } else { iTab[op].f = I_SBCD_A; iTab[op].d = mkDiss(0, D_RIPR,Rx, D_RIPR,Ry, 1,0); } cnt++; } else { SAEF_error("cpu.mkITab() op exists SBCD "+op); return false; } } } } } //NBCD { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (288 << 6) | ea; if (iTab[op].op === -1) { var m = getEAMode(ea); iTab[op] = mkI(op, "NBCD", m == M_rdd ? [6,1,0] : [8,1,1]); if (m == M_rdd) { iTab[op].p.Dd = ea & 7; iTab[op].f = I_NBCD_D; } else { iTab[op].p.ea = ea; iTab[op].p.cyc = addCycs(iTab[op].p.cyc, getEACycs(ea, 1)); iTab[op].f = I_NBCD_E; } iTab[op].d = mkDiss(0, false,false, D_EA,ea, 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists NBCD "+op); return false; } } } } //PACK if (model >= 68020) { for (var Ry = 0; Ry < 8; Ry++) { for (var rm = 0; rm < 2; rm++) { for (var Rx = 0; Rx < 8; Rx++) { op = (8 << 12) | (Ry << 9) | (20 << 4) | (rm << 3) | Rx; if (iTab[op].op === -1) { iTab[op] = mkI(op, "PACK", [4,0,0]); //FIXME cycles iTab[op].p.Ry = Ry; iTab[op].p.Rx = Rx; if (rm == 0) { iTab[op].f = I_PACK_D; iTab[op].d = mkDiss(1, D_RDD,Rx, D_RDD,Ry, 0,0); //FIXME adjustment } else { iTab[op].f = I_PACK_A; iTab[op].d = mkDiss(1, D_RIPR,Rx, D_RIPR,Ry, 0,0); //FIXME adjustment } cnt++; } else { SAEF_error("cpu.mkITab() op exists PACK "+op); return false; } } } } } //UNPK if (model >= 68020) { for (var Ry = 0; Ry < 8; Ry++) { for (var rm = 0; rm < 2; rm++) { for (var Rx = 0; Rx < 8; Rx++) { op = (8 << 12) | (Ry << 9) | (24 << 4) | (rm << 3) | Rx; if (iTab[op].op === -1) { iTab[op] = mkI(op, "PACK", [4,0,0]); //FIXME cycles iTab[op].p.Ry = Ry; iTab[op].p.Rx = Rx; if (rm == 0) { iTab[op].f = I_UNPK_D; iTab[op].d = mkDiss(1, D_RDD,Rx, D_RDD,Ry, 0,0); //FIXME adjustment } else { iTab[op].f = I_UNPK_A; iTab[op].d = mkDiss(1, D_RIPR,Rx, D_RIPR,Ry, 0,0); //FIXME adjustment } cnt++; } else { SAEF_error("cpu.mkITab() op exists UNPK " + op); return false; } } } } } /*-----------------------------------------------------------------------*/ /* Program Control */ //Bcc { for (var cc = 2; cc < 16; cc++) { for (var dp = 0; dp < (model >= 68020 ? 256 : 255); dp++) { /* 0xff = long, 68020 only */ op = (6 << 12) | (cc << 8) | dp; if (iTab[op].op === -1) { iTab[op] = mkI(op, "B"+ccNames[cc], dp == 255 ? [12,1,0] : [8,1,0]); iTab[op].p.cc = cc; iTab[op].p.dp = dp; iTab[op].p.cycTaken = [10,2,2]; iTab[op].f = I_Bcc; iTab[op].d = mkDiss(0, false,false, D_IME_DP,dp, dp == 255 ? 2 : 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists B"+ccNames[cc]+" "+op); return false; } } } } //DBcc { for (var cc = 0; cc < 16; cc++) { for (var Dn = 0; Dn < 8; Dn++) { op = (5 << 12) | (cc << 8) | (25 << 3) | Dn; if (iTab[op].op === -1) { iTab[op] = mkI(op, "DB"+ccNames[cc], [10,2,0]); iTab[op].p.cc = cc; iTab[op].p.Dn = Dn; iTab[op].p.cycNotTakenTrue = [12,2,0]; iTab[op].p.cycNotTakenFalse = [14,3,0]; iTab[op].f = I_DBcc; iTab[op].d = mkDiss(0, D_RDD,Dn, D_IME_DP,0, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists DB"+ccNames[cc]+" "+op); return false; } } } } //Scc { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var cc = 0; cc < 16; cc++) { for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (5 << 12) | (cc << 8) | (3 << 6) | ea; if (iTab[op].op === -1) { var cyc = getEAMode(ea) == M_rdd ? [8,1,1] : addCycs([8,1,1], getEACycs(ea, 1)); iTab[op] = mkI(op, "S"+ccNames[cc], cyc); iTab[op].p.cc = cc; iTab[op].p.ea = ea; iTab[op].p.cycFalse = [4,1,0]; iTab[op].p.cycTrue = [6,1,0]; iTab[op].f = I_Scc; iTab[op].d = mkDiss(0, false,false, D_EA,ea, 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists S"+ccNames[cc]+" "+op); return false; } } } } } //BRA { for (var dp = 0; dp < (model >= 68020 ? 256 : 255); dp++) { /* 0xff = 68020 only */ op = (96 << 8) | dp; if (iTab[op].op === -1) { iTab[op] = mkI(op, "BRA", [10,2,0]); iTab[op].p.dp = dp; iTab[op].f = I_BRA; iTab[op].d = mkDiss(0, false,false, D_IME_DP,dp, dp == 0 ? 2 : (dp == 255 ? 4 : 1),0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BRA "+op); return false; } } } //BSR { for (var dp = 0; dp < (model >= 68020 ? 256 : 255); dp++) { /* 0xff = 68020 only */ op = (97 << 8) | dp; if (iTab[op].op === -1) { iTab[op] = mkI(op, "BSR", [18,2,2]); iTab[op].p.dp = dp; iTab[op].f = I_BSR; iTab[op].d = mkDiss(0, false,false, D_IME_DP,dp, dp == 0 ? 2 : (dp == 255 ? 4 : 1),0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BSR " + op); return false; } } } //JMP { var en = [M_ria, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (315 << 6) | ea; if (iTab[op].op === -1) { var cyc; switch (getEAMode(ea)) { case M_ria: cyc = [ 8,2,0]; break; case M_rid: cyc = [10,2,0]; break; case M_rii: cyc = [14,3,0]; break; case M_pcid: cyc = [10,2,0]; break; case M_pcii: cyc = [14,3,0]; break; case M_absw: cyc = [10,2,0]; break; case M_absl: cyc = [12,3,0]; break; } iTab[op] = mkI(op, "JMP", cyc); iTab[op].p.ea = ea; iTab[op].f = I_JMP; iTab[op].d = mkDiss(0, false,false, D_EA,ea, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists JMP "+op); return false; } } } } //JSR { var en = [M_ria, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (314 << 6) | ea; if (iTab[op].op === -1) { var cyc; switch (getEAMode(ea)) { case M_ria: cyc = [16,2,2]; break; case M_rid: cyc = [18,2,2]; break; case M_rii: cyc = [22,2,2]; break; case M_pcid: cyc = [18,2,2]; break; case M_pcii: cyc = [22,2,2]; break; case M_absw: cyc = [18,2,2]; break; case M_absl: cyc = [20,3,2]; break; } iTab[op] = mkI(op, "JSR", cyc); iTab[op].p.ea = ea; iTab[op].f = I_JSR; iTab[op].d = mkDiss(0, false,false, D_EA,ea, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists JSR " + op); return false; } } } } //NOP { op = 0x4E71; if (iTab[op].op === -1) { iTab[op] = mkI(op, "NOP", [4,1,0]); iTab[op].f = I_NOP; iTab[op].d = mkDiss(0, false,false, false,false, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists NOP "+op); return false; } } //RTD if (model >= 68010) { op = 0x4E74; if (iTab[op].op === -1) { iTab[op] = mkI(op, "RTD", [4,0,0]); //FIXME cycles iTab[op].f = I_RTD; iTab[op].d = mkDiss(0, false,false, D_IME,1, 0,0); //FIXME cnt++; } else { SAEF_error("cpu.mkITab() op exists RTD "+op); return false; } } //RTR { op = 0x4E77; if (iTab[op].op === -1) { iTab[op] = mkI(op, "RTR", [20,5,0]); iTab[op].f = I_RTR; iTab[op].d = mkDiss(0, false,false, false,false, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists RTR "+op); return false; } } //RTS { op = 0x4E75; if (iTab[op].op === -1) { iTab[op] = mkI(op, "RTS", [16,4,0]); iTab[op].f = I_RTS; iTab[op].d = mkDiss(0, false,false, false,false, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists RTS "+op); return false; } } //TST { var en = [M_rdd, M_rda, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl, M_imm]; if (model >= 68020) en.push(M_pcid, M_pcii); for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { var m = getEAMode(ea); if (model >= 68020 && z == 0 && m == M_rda) continue; //68020 An word and long only op = (74 << 8) | (z << 6) | ea; if (iTab[op].op === -1) { cyc = m == M_rdd || m == M_rda ? [4,1,0] : addCycs([4,1,0], getEACycs(ea, z2)); iTab[op] = mkI(op, "TST", cyc); iTab[op].p.ea = ea; iTab[op].p.zm = z2 == 4 ? 0x80000000 : (z2 == 2 ? 0x8000 : 0x80); iTab[op].f = z2 == 4 ? I_TST_32 : (z2 == 2 ? I_TST_16 : I_TST_8); iTab[op].d = mkDiss(0, false,false, D_EA,ea, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists TST "+op); return false; } } } } } /*-----------------------------------------------------------------------*/ /* System Control - CCR */ //ANDI_CCR { op = 0x23C; if (iTab[op].op === -1) { iTab[op] = mkI(op, "ANDI", [20,3,0]); iTab[op].f = I_ANDI_CCR; iTab[op].d = mkDiss(0, D_IME,1, D_CCR,0, 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ANDI_CCR "+op); return false; } } //EORI_CCR { op = 0xA3C; if (iTab[op].op === -1) { iTab[op] = mkI(op, "EORI", [20,3,0]); iTab[op].f = I_EORI_CCR; iTab[op].d = mkDiss(0, D_IME,1, D_CCR,0, 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists EORI "+op); return false; } } //ORI_CCR { op = 0x3C; if (iTab[op].op === -1) { iTab[op] = mkI(op, "ORI", [20,3,0]); iTab[op].f = I_ORI_CCR; iTab[op].d = mkDiss(0, D_IME,1, D_CCR,0, 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ORI_CCR "+op); return false; } } //MOVE_CCR2 if (model >= 68010) { var en = [M_rdd,M_ria,M_ripo,M_ripr,M_rid,M_rii,M_absw,M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (267 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "MOVE", [4,1,0]); iTab[op].p.ea = ea; iTab[op].f = I_MOVE_CCR2; iTab[op].d = mkDiss(0, D_CCR,0, D_EA,ea, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists MOVE_CCR2 "+op); return false; } } } } //MOVE_2CCR { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (275 << 6) | ea; if (iTab[op].op === -1) { var cyc = getEAMode(ea) == M_rdd ? [12,1,0] : addCycs([12,1,0], getEACycs(ea, 2)); iTab[op] = mkI(op, "MOVE", cyc); iTab[op].p.ea = ea; iTab[op].f = I_MOVE_2CCR; iTab[op].d = mkDiss(0, D_EA,ea, D_CCR,0, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists MOVE_2CCR "+op); return false; } } } } /*-----------------------------------------------------------------------*/ /* System Control - SR */ //ANDI_SR { op = 0x27C; if (iTab[op].op === -1) { iTab[op] = mkI(op, "ANDI", [20,3,0]); iTab[op].f = I_ANDI_SR; iTab[op].d = mkDiss(0, D_IME,1, D_SR,0, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ANDI_SR "+op); return false; } } //EORI_SR { op = 0xA7C; if (iTab[op].op === -1) { iTab[op] = mkI(op, "EORI", [20,3,0]); iTab[op].f = I_EORI_SR; iTab[op].d = mkDiss(0, D_IME,1, D_SR,0, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists EORI "+op); return false; } } //ORI_SR { op = 0x7C; if (iTab[op].op === -1) { iTab[op] = mkI(op, "ORI", [20,3,0]); iTab[op].f = I_ORI_SR; iTab[op].d = mkDiss(0, D_IME,1, D_SR,0, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ORI_SR "+op); return false; } } //MOVE_SR2 { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (259 << 6) | ea; if (iTab[op].op === -1) { var cyc = getEAMode(ea) == M_rdd ? [6,1,0] : addCycs([8,1,1], getEACycs(ea, 2)); iTab[op] = mkI(op, "MOVE", cyc); iTab[op].p.ea = ea; iTab[op].f = I_MOVE_SR2; iTab[op].d = mkDiss(0, D_SR,0, D_EA,ea, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists MOVE_SR2 " + op); return false; } } } } //MOVE_2SR { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (283 << 6) | ea; if (iTab[op].op === -1) { var cyc = getEAMode(ea) == M_rdd ? [12,1,0] : addCycs([12,1,0], getEACycs(ea, 2)); iTab[op] = mkI(op, "MOVE", cyc); iTab[op].p.ea = ea; iTab[op].f = I_MOVE_2SR; iTab[op].d = mkDiss(0, D_EA,ea, D_SR,0, 2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists MOVE_2SR " + op); return false; } } } } /*-----------------------------------------------------------------------*/ /* System Control - USP */ //MOVE_USP { for (var dr = 0; dr < 2; dr++) { for (var An = 0; An < 8; An++) { op = (1254 << 4) | (dr << 3) | An; if (iTab[op].op === -1) { iTab[op] = mkI(op, "MOVE", [4,1,0]); iTab[op].p.An = An; if (dr == 0) { iTab[op].f = I_MOVE_A2USP; iTab[op].d = mkDiss(0, D_RDA,An, D_USP,0, 4,0); } else { iTab[op].f = I_MOVE_USP2A; iTab[op].d = mkDiss(0, D_USP,0, D_RDA,An, 4,0); } cnt++; } else { SAEF_error("cpu.mkITab() op exists MOVE_USP "+op); return false; } } } } /*-----------------------------------------------------------------------*/ /* System Control - MOVEC */ //MOVEC if (model >= 68010) { for (var dr = 0; dr < 2; dr++) { op = (10045 << 1) | dr; if (iTab[op].op === -1) { iTab[op] = mkI(op, "MOVEC", [4,0,0]); //FIXME cycles iTab[op].f = dr == 0 ? I_MOVE_C2 : I_MOVE_2C; iTab[op].d = mkDiss(1, false,false, D_EXT_MOVEC,dr == 0, 4,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists MOVEC "+op); return false; } } } /*-----------------------------------------------------------------------*/ /* System Control - MOVES */ //MOVES if (model >= 68010) { var en = [M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (14 << 8) | (z << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "MOVES", [4,0,0]); //FIXME cycles iTab[op].p.ea = ea; iTab[op].f = z2 == 4 ? I_MOVES_32 : (z2 == 2 ? I_MOVES_16 : I_MOVES_8); iTab[op].d = mkDiss(1, false,false, D_EA,ea, z2,0); //FIXME //iTab[op].d = mkDiss(1, D_EA,ea, false,false, z2,0); //FIXME cnt++; } else { SAEF_error("cpu.mkITab() op exists MOVES " + op); return false; } } } } } /*-----------------------------------------------------------------------*/ /* System Control */ //BKPT if (model >= 68010) { for (var vec = 0; vec < 8; vec++) { op = (2313 << 3) | vec; if (iTab[op].op === -1) { iTab[op] = mkI(op, "BKPT", [45,5,4]); iTab[op].p.v = vec; iTab[op].f = I_BKPT; iTab[op].d = mkDiss(0, false,false, D_IMD,vec, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists BKPT " + op); return false; } } } //CHK { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm]; for (var Dn = 0; Dn < 8; Dn++) { for (var z = 0; z < (model >= 68020 ? 2 : 1); z++) { var z2 = z == 0 ? 2 : 4; var z3 = z == 0 ? 3 : 2; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (4 << 12) | (Dn << 9) | (z3 << 7) | ea; if (iTab[op].op === -1) { var cyc = getEAMode(ea) == M_rdd ? [10,1,0] : addCycs([10,1,0], getEACycs(ea, z2)); iTab[op] = mkI(op, "CHK", cyc); iTab[op].p.Dn = Dn; iTab[op].p.ea = ea; iTab[op].f = z2 == 2 ? I_CHK_16 : I_CHK_32; iTab[op].d = mkDiss(0, D_EA,ea, D_RDD,Dn, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists CHK "+op); return false; } } } } } } //CHK2 if (model >= 68020) { var en = [M_ria, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl]; for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 1 : (z == 1 ? 2 : 4); for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (z << 9) | (3 << 6) | ea; if (iTab[op].op === -1) { var cyc = getEAMode(ea) == M_rdd ? [10,1,0] : addCycs([10,1,0], getEACycs(ea, z2)); iTab[op] = mkI(op, "CHK2", cyc); iTab[op].p.ea = ea; iTab[op].f = z2 == 4 ? I_CHK2_32 : (z2 == 2 ? I_CHK2_16 : I_CHK2_8); //iTab[op].d = mkDiss(1, D_EA,ea, false,false, z2,0); //FIXME iTab[op].d = mkDiss(1, false,false, D_EA,ea, z2,0); //FIXME cnt++; } else { SAEF_error("cpu.mkITab() op exists CHK2 "+op); return false; } } } } } //ILLEGAL { op = 0x4AFC; if (iTab[op].op === -1) { iTab[op] = mkI(op, "ILLEGAL", [0,0,0]); iTab[op].f = I_ILLEGAL; iTab[op].d = mkDiss(0, false,false, false,false, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists ILLEGAL "+op); return false; } } //RESET { op = 0x4E70; if (iTab[op].op === -1) { iTab[op] = mkI(op, "RESET", [132,1,0]); iTab[op].f = I_RESET; iTab[op].d = mkDiss(0, false,false, false,false, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists RESET "+op); return false; } } //RTE { op = 0x4E73; if (iTab[op].op === -1) { iTab[op] = mkI(op, "RTE", [20,5,0]); iTab[op].f = I_RTE; iTab[op].d = mkDiss(0, false,false, false,false, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists RTE "+op); return false; } } //STOP { op = 0x4E72; if (iTab[op].op === -1) { iTab[op] = mkI(op, "STOP", [4,0,0]); iTab[op].f = I_STOP; iTab[op].d = mkDiss(0, false,false, D_IME,1, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists STOP "+op); return false; } } //TRAP { for (var v = 0; v < 16; v++) { op = (1252 << 4) | v; if (iTab[op].op === -1) { iTab[op] = mkI(op, "TRAP", [38,4,3]); iTab[op].p.v = v; iTab[op].f = I_TRAP; iTab[op].d = mkDiss(0, false,false, D_IMD,v, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists TRAP "+op); return false; } } } //TRAPCC if (model >= 68020) { for (var z = 0; z < 3; z++) { var z2 = z == 0 ? 0 : (z == 1 ? 2 : 4); var opm = z == 0 ? 4 : (z == 1 ? 2 : 3); for (var cc = 0; cc < 16; cc++) { op = (5 << 12) | (cc << 8) | (31 << 3) | opm; if (iTab[op].op === -1) { iTab[op] = mkI(op, "TRAP"+ccNames[cc], [4,1,0]); iTab[op].p.cc = cc; iTab[op].f = z2 == 4 ? I_TRAPCC_32 : (z2 == 2 ? I_TRAPCC_16 : I_TRAPCC); if (z2) iTab[op].d = mkDiss(0, false,false, D_IMD,z2 == 2 ? 1 : 2, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists TRAP"+ccNames[cc]+" "+op); return false; } } } } //TRAPV { op = 0x4E76; if (iTab[op].op === -1) { iTab[op] = mkI(op, "TRAPV", [4,1,0]); iTab[op].f = I_TRAPV; iTab[op].d = mkDiss(0, false,false, false,false, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists TRAPV "+op); return false; } } /*-----------------------------------------------------------------------*/ /* Multiprocessor */ //CAS if (model >= 68020) { var en = [M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var z = 1; z <= 3; z++) { var z2 = z == 1 ? 1 : (z == 2 ? 2 : 4); for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (1 << 11) | (z << 9) | (3 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "CAS", [4,0,0]); //FIXME cycles iTab[op].p.ea = ea; iTab[op].f = z2 == 4 ? I_CAS_32 : (z2 == 2 ? I_CAS_16 : I_CAS_8); iTab[op].d = mkDiss(1, false,false, D_EA,ea, z2,0); //FIXME cnt++; } else { SAEF_error("cpu.mkITab() op exists CAS "+op); return false; } } } } } //CAS2 if (model >= 68020) { for (var z = 2; z <= 3; z++) { var z2 = z == 2 ? 2 : 4; op = (1 << 11) | (z << 9) | 252; if (iTab[op].op === -1) { iTab[op] = mkI(op, "CAS2", [4,0,0]); //FIXME cycles iTab[op].f = z2 == 4 ? I_CAS2_32 : I_CAS2_16; iTab[op].d = mkDiss(2, false,false, false,false, z2,0); //FIXME cnt++; } else { SAEF_error("cpu.mkITab() op exists CAS2 "+op); return false; } } } //TAS { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (299 << 6) | ea; if (iTab[op].op === -1) { var cyc = getEAMode(ea) == M_rdd ? [4,1,0] : addCycs([10,1,1], getEACycs(ea, 1)); iTab[op] = mkI(op, "TAS", cyc); iTab[op].p.ea = ea; iTab[op].f = I_TAS; iTab[op].d = mkDiss(0, false,false, D_EA,ea, 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists TAS "+op); return false; } } } } /*-----------------------------------------------------------------------*/ //CALLM if (model == 68020) { var en = [M_ria, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (27 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "CALLM", [4,0,0]); //FIXME cycles iTab[op].p.ea = ea; iTab[op].f = I_CALLM; iTab[op].d = mkDiss(0, D_IME,1, D_EA,ea, 0,0); //FIXME cnt++; } else { SAEF_error("cpu.mkITab() op exists CALLM "+op); return false; } } } } //RTM if (model == 68020) { for (var da = 0; da < 1; da++) { for (var Rn = 0; Rn < 8; Rn++) { op = (108 << 4) | (da << 3) | Rn; if (iTab[op].op === -1) { iTab[op] = mkI(op, "RTM", [4,0,0]); //FIXME cycles iTab[op].p.da = da; iTab[op].p.Rn = Rn; iTab[op].f = I_RTM; iTab[op].d = mkDiss(0, false,false, da ? D_RDD : D_RDA,Rn, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists RTM "+op); return false; } } } } /*-----------------------------------------------------------------------*/ /* MMU 68851/68030/68040 */ /* S PBcc 1 S PDBcc 1 S PFLUSH 1 3 4 S PFLUSHA 1 3 S PFLUSHR 1 S PFLUSHS 1 S PLOAD 1 3 S PMOVE 1 3 S PRESTORE 1 S PSAVE 1 S PScc 1 S PTEST 1 3 4 S PTRAPcc 1 PVALID 1 */ if (model == 68030) { var cid = 0; /* page 4-86: coprocessor ID of 000 is reserved for MMU instructions for the MC68030 */ var en = [M_ria, M_rid, M_rii, M_absw, M_absl]; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (15 << 12) | (cid << 9) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "MMU", [4,0,0]); //FIXME name, cycles iTab[op].p.ea = ea; iTab[op].f = I_MMU; iTab[op].d = mkDiss(1, D_EA,ea, D_EXT_MMU,false, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists PFLUSH "+op); return false; } } } } /*-----------------------------------------------------------------------*/ /* 68040 */ /* S CINV (cache) S CPUSH (cache) MOVE16 */ /*-----------------------------------------------------------------------*/ /* Coprocessor 68020/68030 */ //cpBcc if (model == 68020 || model == 68030) { for (var cid = 0; cid < 8; cid++) { if (cid == 0 && model == 68030) /* page 4-86: coprocessor ID of 000 is reserved for MMU instructions for the MC68030 */ continue; for (var z = 0; z < 2; z++) { var z2 = z == 0 ? 2 : 4; for (var ccc = 0; ccc < 64; ccc++) { op = (15 << 12) | (cid << 9) | (1 << 7) | (z << 6) | ccc; if (iTab[op].op === -1) { iTab[op] = mkI(op, "cpBcc", [4,0,0]); //FIXME cycles iTab[op].p.cid = cid; iTab[op].p.ccc = ccc; iTab[op].p.z = z2; iTab[op].f = I_cpBcc; iTab[op].d = mkDiss(1 + (z2 == 2 ? 1 : 2), false,false, D_IME_DP,z == 0 ? 0 : 255, z2,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists cpBcc "+op); return false; } } } } } //cpDBcc if (model == 68020 || model == 68030) { for (var cid = 0; cid < 8; cid++) { if (cid == 0 && model == 68030) continue; for (var dn = 0; dn < 8; dn++) { op = (15 << 12) | (cid << 9) | (1 << 6) | (1 << 3) | dn; if (iTab[op].op === -1) { iTab[op] = mkI(op, "cpDBcc", [4,0,0]); //FIXME cycles iTab[op].p.cid = cid; iTab[op].p.dn = dn; iTab[op].f = I_cpDBcc; iTab[op].d = mkDiss(2, D_RDD,dn, false,false, 2,0); //FIXME cnt++; } else { SAEF_error("cpu.mkITab() op exists cpDBcc "+op); return false; } } } } //cpGEN if (model == 68020 || model == 68030) { for (var cid = 0; cid < 8; cid++) { if (cid == 0 && model == 68030) continue; for (var ea = 0; ea < 61; ea++) { op = (15 << 12) | (cid << 9) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "cpGEN", [4,0,0]); //FIXME cycles iTab[op].p.cid = cid; iTab[op].p.ea = ea; iTab[op].f = I_cpGEN; iTab[op].d = mkDiss(2, false,false, false,false, 0,0); //FIXME cnt++; } else { SAEF_error("cpu.mkITab() op exists cpGEN "+op); return false; } } } } //cpRESTORE if (model == 68020 || model == 68030) { var en = [M_ria, M_ripo, M_rid, M_rii, M_pcid, M_pcii, M_absw, M_absl, M_imm]; for (var cid = 0; cid < 8; cid++) { if (cid == 0 && model == 68030) continue; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (15 << 12) | (cid << 9) | (5 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "cpRESTORE", [4,0,0]); //FIXME cycles iTab[op].p.cid = cid; iTab[op].p.ea = ea; iTab[op].f = I_cpRESTORE; iTab[op].d = mkDiss(0, false,false, D_EA,ea, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists cpRESTORE "+op); return false; } } } } } //cpSAVE if (model == 68020 || model == 68030) { var en = [M_ria, M_ripo, M_rid, M_rii, M_absw, M_absl]; for (var cid = 0; cid < 8; cid++) { if (cid == 0 && model == 68030) continue; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (15 << 12) | (cid << 9) | (4 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "cpSAVE", [4,0,0]); //FIXME cycles iTab[op].p.cid = cid; iTab[op].p.ea = ea; iTab[op].f = I_cpSAVE; iTab[op].d = mkDiss(0, false,false, D_EA,ea, 0,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists cpSAVE "+op); return false; } } } } } //cpScc if (model == 68020 || model == 68030) { var en = [M_rdd, M_ria, M_ripo, M_ripr, M_rid, M_rii, M_absw, M_absl]; for (var cid = 0; cid < 8; cid++) { if (cid == 0 && model == 68030) continue; for (var ea = 0; ea < 61; ea++) { if (isEA(ea, en)) { op = (15 << 12) | (cid << 9) | (1 << 6) | ea; if (iTab[op].op === -1) { iTab[op] = mkI(op, "cpScc", [4,0,0]); //FIXME cycles iTab[op].p.cid = cid; iTab[op].p.ea = ea; iTab[op].f = I_cpScc; iTab[op].d = mkDiss(2, false,false, D_EA,ea, 1,0); cnt++; } else { SAEF_error("cpu.mkITab() op exists cpScc "+op); return false; } } } } } //cpTRAPcc if (model == 68020 || model == 68030) { for (var cid = 0; cid < 8; cid++) { if (cid == 0 && model == 68030) continue; for (var opm = 2; opm <= 4; opm++) { var z2 = opm == 2 ? 2 : (opm = 3 ? 4 : 0); op = (15 << 12) | (cid << 9) | (1 << 6) | (7 << 3) | opm; if (iTab[op].op === -1) { iTab[op] = mkI(op, "cpTRAPcc", [4,0,0]); //FIXME cycles iTab[op].p.cid = cid; iTab[op].p.opm = opm; iTab[op].f = I_cpTRAPcc; iTab[op].d = mkDiss(1 + (z2 == 1 ? 0 : (z2 == 2 ? 2 : 4)), false,false, false,false, z2,0); //FIXME cnt++; } else { SAEF_error("cpu.mkITab() op exists cpTRAPcc "+op); return false; } } } } //cpXXX /*if (model == 68020 || model == 68030) { for (var cid = 0; cid < 8; cid++) { if (cid == 0 && model == 68030) continue; for (var args = 0; args < 512; args++) { op = (15 << 12) | (cid << 9) | args; if (iTab[op].op === -1) { iTab[op] = mkI(op, "cpXXX", [4,0,0]); //FIXME cycles iTab[op].p.cid = cid; iTab[op].p.args = args; iTab[op].f = I_cpXXX; iTab[op].d = mkDiss(0, false,false, false,false, 0,0); //FIXME cnt++; } else { SAEF_error("cpu.mkITab() op exists cpXXX "+op); return false; } } } }*/ /*-----------------------------------------------------------------------*/ if (typeof SAER != "undefined") SAEF_log("cpu.mkiTab() %d instructions created", cnt); return true; } }