ScriptedAmigaEmulator/sae/cpu.js
Rupert Hausberger fbf36a4fa5 update 0.9.0
2016-07-15 19:44:16 +02:00

10267 lines
308 KiB
JavaScript

/*-------------------------------------------------------------------------
| 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; /* <ea> {offset:width} */
const ID_BFCLR = 2; /* <ea> {offset:width} */
const ID_BFEXTS = 3; /* <ea> {offset:width},Dn */
const ID_BFEXTU = 4; /* <ea> {offset:width},Dn */
const ID_BFFFO = 5; /* <ea> {offset:width},Dn */
const ID_BFINS = 6; /* Dn, <ea> {offset:width} */
const ID_BFSET = 7; /* <ea> {offset:width} */
const ID_BFTST = 8; /* <ea> {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;
}
}