/* * sc61860.js -- SHARP SC61860 (for Pocket/Portable Computer) Emulator * JavaScript version * * Original C Language version: Copyright (C) 1994-2016 by Dai ISHIJIMA * 0.1: Oct. 3, 1995 by Dai ISHIJIMA * 0.2: May 1, 2014 (ina/keyscan/termios improvement) * 0.3: Jan. 4, 2016 (FreeBSD/Linux/MacOSX) * * JavaScript version: * 0.0: Jan. 24, 2016 */ /* SC61860 registers */ var pc = 0x0000; var opcode = 0; var dp = 0x0000; var preg = 0; var qreg = 0; var rreg = 0; var dreg = 0; var alu = 0; var cflag = 0; var zflag = 0; var xin = 0; var opcode = 0; var ticks = 0; var ticks2 = 0; var div500 = 0; var div2 = 0; var XTICKS = 500; var XTICK2 = 200; var power_on = 0; var disp_on = 0; var kon = 1; var keychar = 'c'; var iaval = 0; var ibval = 0; var foval = 0; var ctrlval = 0; var IRAMSIZ = (0x005f + 1) var iram = new Array(); /* registers on IRAM */ var IREG = 0; var JREG = 1; var AREG = 2; var BREG = 3; var XLREG = 4; var XHREG = 5; var YLREG = 6; var YHREG = 7; var KREG = 8; var LREG = 9; var MREG = 10; var NREG = 11; var IAPORT = 0x5c var IBPORT = 0x5d var FOPORT = 0x5e var CTRLPORT = 0x5f /* */ var keyque = -1; /* length of keyboard input buffer */ var nloops = 0; /* loops */ var oloops = 0; var MAXNLOOP = 1000; var mainid; var statid; //var step = 1; var step = 0; var stepdebug = 0; var ndsteps = 0; var MAXNDS = 4096; var keym = new Array(); /* 8bit, 16bit */ function hibyte(x) { return((parseInt(x) & 0xff00) >> 8); } function lobyte(x) { return(parseInt(x) & 0x00ff); } function hilo(hi, lo) { return(((parseInt(hi) & 0x00ff) << 8) | (parseInt(lo) & 0x00ff)); } function hex4(x) { var xx; var s; xx = parseInt(x); s = '' + "0000" + xx.toString(16); if (s.substr(s.length - 5, 1) != '0') { //scstatus(); alert('converted: ' + s); if (s.substr(s.length - 3, 3) == 'NaN') { scstatus(); alert('NaN4'); } } return(s.substr(s.length - 4, 4)); } function hex2(x) { var xx; var s; xx = parseInt(x); s = '' + "00" + xx.toString(16); if (s.substr(s.length - 3, 1) != '0') { //scstatus(); alert('converted: ' + s); if (s.substr(s.length - 3, 3) == 'NaN') { alert('NaN2 at ' + opcode + 'on' + pc); } } return(s.substr(s.length - 2, 2)); } function iramr(adr) { var dat = 0; if ((adr < 0) || (0x5f < adr)) { scstatus(); alert('Invalid iram address to read: ' + hex4(adr)); } dat = iram[adr]; if ((dat < 0) || (0x00ff < dat)) { alert('Invalid iram value read: ' + hex4(dat) + ' at ' + hex4(adr)); } return(dat); } function iramw(adr, dat) { if ((adr < 0) || (0x5f < adr)) { scstatus(); alert('Invalid iram address to write:' + hex4(adr)); } if ((dat < 0) || (0x00ff < dat)) { alert('Invalid iram value written:' + hex4(dat) + ' at ' + hex4(adr)); } iram[adr] = dat; } /* read memory */ function memr(adr) { var dat = 0; if ((adr < 0) || (0xffff < adr)) { alert('Invalid mainram address to read:' + adr.toString(16)); } dat = mainram[adr]; if ((dat < 0) || (0x00ff < dat)) { alert('Invalid mainram value read:' + hex4(dat) + ' at ' + hex4(adr)); } return(dat); } /* write memory, check ROM address */ function memw(adr, dat) { if ((adr < 0) || (0xffff < adr)) { alert('Invalid mainram address to write: ' + adr.toString(16)); } if ((dat < 0) || (0x00ff < dat)) { alert('Invalid mainram value written: ' + hex4(dat) + ' at ' + hex4(adr)); } if ((0x2000 <= adr) && (adr <= 0x7fff)) { mainram[adr] = lobyte(dat); } else { alert('Wrote to ROM: ' + hex2(dat) + ' at ' + hex4(adr)); } } /* * short/unsigned char add/sub */ function add16(a, b) { var c = a + b; return(0xffff & c); } function sub16(a, b) { var c = a - b; return(0xffff & c); } function decr16(dat) { return(sub16(dat, 1)); } function incr16(dat) { return(add16(dat, 1)); } function add8(a, b) { var c = a + b; return(0x00ff & c); } function sub8(a, b) { var c = a - b; return(0x00ff & c); } function incr8(dat) { return(add8(dat, 1)); } function decr8(dat) { return(sub8(dat, 1)); } /* * operations */ /* secret */ function op35_mvwp() { pc = decr16(pc); dreg = incr8(iramr(IREG)); rreg = decr8(rreg); iramw(rreg, hibyte(pc)); rreg = decr8(rreg); iramw(rreg, lobyte(pc)); pc = hilo(iramr(BREG), iramr(AREG)); do { iramw(preg, memr(pc)); preg = incr8(preg); pc = incr16(pc); dreg = decr8(dreg); } while (dreg != 0); pc = incr16(hilo(iramr(rreg + 1), iramr(rreg))); rreg = add8(rreg, 2); } function opc6_tsma() { if ((iramr(preg) & iramr(AREG)) == 0) { zflag = 1 } else { zflag = 0; } } function op23_clra() { iramw(AREG, 0); } function op54_mvmp() { iramw(preg, memr(pc)); } function op56_ldpc() { iramw(AREG, memr(pc)); } function opd7_sz() { iramw(rreg - 1, memr(dp)); pc = incr16(pc); zflag = 1; } function op72_rz() { pc = incr16(pc); zflag = 0; } /* 8bits load */ function op20_ldp() { iramw(AREG, preg); } function op21_ldq() { iramw(AREG, qreg); } function op22_ldr() { iramw(AREG, rreg); } function op59_ldm() { iramw(AREG, iramr(preg)); } function op57_ldd() { iramw(AREG, memr(dp)); } function op02_lia() { iramw(AREG, memr(pc)); pc = incr16(pc); } function op03_lib() { iramw(BREG, memr(pc)); pc = incr16(pc); } function op01_lij() { iramw(JREG, memr(pc)); pc = incr16(pc); } function op00_lii() { iramw(IREG, memr(pc)); pc = incr16(pc); } function op12_lip() { preg = memr(pc); pc = incr16(pc); } function op80_lp() { preg = opcode & 0x3f; } function op30_stp() { preg = iramr(AREG); } function op31_stq() { qreg = iramr(AREG); } function op13_liq() { qreg = memr(pc); pc = incr16(pc); } function op32_str() { rreg = iramr(AREG); } function op11_lidl() { dp = hilo(hibyte(dp), memr(pc)); pc = incr16(pc); } function op52_std() { memw(dp, iramr(AREG)); } function op53_mvdm() { memw(dp, iramr(preg)); } function op55_mvmd() { iramw(preg, memr(dp)); } function opd8_leave() { iramw(rreg, 0); } function op5b_pop() { iramw(AREG, iramr(rreg)); rreg = incr8(rreg); } function op34_push() { rreg = decr8(rreg); iramw(rreg, iramr(AREG)); } /* 16bits load */ function op10_lidp() { dp = hilo(memr(pc), memr(pc + 1)); pc = add16(pc, 2); } /* block load, exchange */ function op0a_mvb() { dreg = incr8(iramr(JREG)); do { iramw(preg, iramr(qreg)); preg = incr8(preg); qreg = incr8(qreg); dreg = decr8(dreg); } while (dreg != 0); } function op08_mvw() { dreg = incr8(iramr(IREG)); do { iramw(preg, iramr(qreg)); preg = incr8(preg); qreg = incr8(qreg); dreg = decr8(dreg); } while (dreg != 0); } function op1a_mvbd() { dreg = incr8(iramr(JREG)); do { iramw(preg, memr(dp)); preg = incr8(preg); dp = incr16(dp); dreg = decr8(dreg); } while (dreg != 0); } function op18_mvwd() { dreg = incr8(iramr(IREG)); do { iramw(preg, memr(dp)); preg = incr8(preg); dp = incr16(dp); dreg = decr8(dreg); } while (dreg != 0); } function op1e_film() { dreg = incr8(iramr(IREG)); do { iramw(preg, iramr(AREG)); preg = incr8(preg); dreg = decr8(dreg); } while (dreg != 0); } function op1f_fild() { dreg = incr8(iramr(IREG)); do { memw(dp, iramr(AREG)); dp = incr16(dp); dreg = decr8(dreg); } while (dreg != 0); } function opda_exab() { var tempval = iramr(AREG); iramw(AREG, iramr(BREG)); iramw(BREG, tempval); } function opdb_exam() { var tempval = iramr(AREG); iramw(AREG, iramr(preg)); iramw(preg, tempval); } function op0b_exb() { var tempval = 0; dreg = incr8(iramr(JREG)); do { tempval = iramr(preg); iramw(preg, iramr(qreg)); iramw(qreg, tempval); preg = incr8(preg); qreg = incr8(qreg); dreg = decr8(dreg); } while (dreg != 0); } function op09_exw() { var tempval = 0; dreg = incr8(iramr(IREG)); do { tempval = iramr(preg); iramw(preg, iramr(qreg)); iramw(qreg, tempval); preg = incr8(preg); qreg = incr8(qreg); dreg = decr8(dreg); } while (dreg != 0); } function op19_exwd() { var tempval = 0; dreg = incr8(iramr(IREG)); do { tempval = memr(dp); memw(dp, iramr(preg)); iramw(preg, tempval); preg = incr8(preg); dp = incr16(dp); dreg = decr8(dreg); } while (dreg != 0); } function op1b_exbd() { var tempval = 0; dreg = incr8(iramr(JREG)); do { tempval = memr(dp); memw(dp, iramr(preg)); iramw(preg, tempval); preg = incr8(preg); dp = incr16(dp); dreg = decr8(dreg); } while (dreg!= 0); } function op58_swp() { var tempval = 0; /* shift low nibble << 4 shift hi nibble >> 4 */ tempval = ((iramr(AREG) & 0x000f) << 4) | ((iramr(AREG) & 0x00f0) >> 4); iramw(AREG, tempval); } /* check condition, set flag */ function chkcz() { if ((alu & 0x00ff) == 0) { zflag = 1; } else { zflag = 0; } if ((alu & 0xff00) != 0) { cflag = 1; } else { cflag = 0; } } /* 8bits operation */ function op74_adia() { alu = iramr(AREG) + memr(pc); pc = incr16(pc); iramw(AREG, lobyte(alu)); chkcz(); } function op70_adim() { alu = iramr(preg) + memr(pc); pc = incr16(pc); iramw(preg, lobyte(alu)); chkcz(); } function op44_adm() { alu = iramr(preg) + iramr(AREG); iramw(preg, lobyte(alu)); chkcz(); } function opc4_adcm() { alu = iramr(preg) + iramr(AREG) + cflag; iramw(preg, lobyte(alu)); chkcz(); } function op75_sbia() { alu = iramr(AREG) - memr(pc); pc = incr16(pc); iramw(AREG, lobyte(alu)); chkcz(); } function op71_sbim() { alu = iramr(preg) - memr(pc); pc = incr16(pc); iramw(preg, lobyte(alu)); chkcz(); } function op45_sbm() { alu = iramr(preg) - iramr(AREG); iramw(preg, lobyte(alu)); chkcz(); } function opc5_sbcm() { alu = iramr(preg) - iramr(AREG) - cflag; iramw(preg, lobyte(alu)); chkcz(); } function op42_inca() { qreg = 2; alu = iramr(AREG) + 1; iramw(AREG, lobyte(alu)); chkcz(); } function opc2_incb() { qreg = 3; alu = iramr(BREG) + 1; iramw(BREG, lobyte(alu)); chkcz(); } function op40_inci() { qreg = 0; alu = iramr(IREG) + 1; iramw(IREG, lobyte(alu)); chkcz(); } function opc0_incj() { qreg = 1; alu = iramr(JREG) + 1; iramw(JREG, lobyte(alu)); chkcz(); } function op48_inck() { qreg = 8; alu = iramr(KREG) + 1; iramw(KREG, lobyte(alu)); chkcz(); } function opc8_incl() { qreg = 9; alu = iramr(LREG) + 1; iramw(LREG, lobyte(alu)); chkcz(); } function op4a_incm() { qreg = 10; alu = iramr(MREG) + 1; iramw(MREG, lobyte(alu)); chkcz(); } function opca_incn() { qreg = 11; alu = iramr(NREG) + 1; iramw(NREG, lobyte(alu)); chkcz(); } function op50_incp() { preg = incr8(preg); } function op43_deca() { qreg = 2; alu = iramr(AREG) - 1; iramw(AREG, lobyte(alu)); chkcz(); } function opc3_decb() { qreg = 3; alu = iramr(BREG) - 1; iramw(BREG, lobyte(alu)); chkcz(); } function op41_deci() { qreg = 0; alu = iramr(IREG) - 1; iramw(IREG, lobyte(alu)); chkcz(); } function opc1_decj() { qreg = 1; alu = iramr(JREG) - 1; iramw(JREG, lobyte(alu)); chkcz(); } function op49_deck() { qreg = 8; alu = iramr(KREG) - 1; iramw(KREG, lobyte(alu)); chkcz(); } function opc9_decl() { qreg = 9; alu = iramr(LREG) - 1; iramw(LREG, lobyte(alu)); chkcz(); } function op4b_decm() { qreg = 10; alu = iramr(MREG) - 1; iramw(MREG, lobyte(alu)); chkcz(); } function opcb_decn() { qreg = 11; alu = iramr(NREG) - 1; iramw(NREG, lobyte(alu)); chkcz(); } function op51_decp() { preg = decr8(preg); } function op64_ania() { alu = iramr(AREG) & memr(pc); pc = incr16(pc); iramw(AREG, alu); if (alu == 0) { zflag = 1; } else { zflag = 0; } } function op46_anma() { alu = iramr(AREG) & memr(pc); iramw(preg, alu); if (alu == 0) { zflag = 1; } else { zflag = 0; } } function op60_anim() { alu = iramr(preg) & memr(pc); pc = incr16(pc); iramw(preg, alu); if (alu == 0) { zflag = 1; } else { zflag = 0; } } function opd4_anid() { iramw(rreg - 1, memr(dp)); memw(dp, memr(dp) & memr(pc)); pc = incr16(pc); if (memr(dp) == 0) { zflag = 1; } else { zflag = 0; } } function op65_oria() { alu = iramr(AREG) | memr(pc); pc = incr16(pc); iramw(AREG, alu); if (alu == 0) { zflag = 1; } else { zflag = 0; } } function op47_orma() { alu = iramr(preg) | iramr(AREG); iramw(preg, alu); if (alu == 0) { zflag = 1; } else { zflag = 0; } } function op61_orim() { alu = iramr(preg) | memr(pc); pc = incr16(pc); iramw(preg, alu); if (alu == 0) { zflag = 1; } else { zflag = 0; } } function opd5_orid() { iramw(rreg - 1, memr(dp)); memw(dp, memr(dp) | memr(pc)); pc = incr16(pc); if (memr(dp) == 0) { zflag = 1; } else { zflag = 0; } } function op67_cpia() { alu = iramr(AREG) - memr(pc); pc = incr16(pc); chkcz(); } function opc7_cpma() { alu = iramr(preg) - iramr(AREG); chkcz(); } function op63_cpim() { alu = iramr(preg) - memr(pc); pc = incr16(pc); chkcz(); } /* 16bits operation */ function op14_adb() { var xx; var pp; xx = hilo(iramr(preg + 1), iramr(preg)); xx += hilo(iramr(BREG), iramr(AREG)); iramw(preg, lobyte(xx)); pp = incr8(preg) iramw(pp, hibyte(xx)); preg = pp; if ((xx & 0x0000ffff) == 0) { zflag = 1; } else { zflag = 0; } if ((xx & 0xffff0000) != 0) { cflag = 1; } else { cflag = 0; } } function op15_sbb() { var xx; var pp; xx = hilo(iramr(preg + 1), iramr(preg)); xx -= hilo(iramr(BREG), iramr(AREG)); iramw(preg, lobyte(xx)); pp = incr8(preg); iramw(pp, hibyte(xx)); preg = pp; if ((xx & 0x0000ffff) == 0) { zflag = 1; } else { zflag = 0; } if ((xx & 0xffff0000) != 0) { cflag = 1; } else { cflag = 0; } } /* inc/dec load/store */ function op04_ix() { qreg = 5; dp = incr16(hilo(iramr(XHREG), iramr(XLREG))); iramw(XHREG, hibyte(dp)); iramw(XLREG, lobyte(dp)); } function op06_iy() { qreg = 7; dp = incr16(hilo(iramr(YHREG), iramr(YLREG))); iramw(YHREG, hibyte(dp)); iramw(YLREG, lobyte(dp)); } function op05_dx() { qreg = 5; dp = decr16(hilo(iramr(XHREG), iramr(XLREG))); iramw(XHREG, hibyte(dp)); iramw(XLREG, lobyte(dp)); } function op07_dy() { qreg = 7; dp = decr16(hilo(iramr(YHREG), iramr(YLREG))); iramw(YHREG, hibyte(dp)); iramw(YLREG, lobyte(dp)); } function op24_ixl() { qreg = 5; dp = incr16(hilo(iramr(XHREG), iramr(XLREG))); iramw(AREG, memr(dp)); iramw(XHREG, hibyte(dp)); iramw(XLREG, lobyte(dp)); } function op26_iys() { qreg = 7; dp = incr16(hilo(iramr(YHREG), iramr(YLREG))); memw(dp, iramr(AREG)); iramw(YHREG, hibyte(dp)); iramw(YLREG, lobyte(dp)); } function op25_dxl() { qreg = 5; dp = decr16(hilo(iramr(XHREG), iramr(XLREG))); iramw(AREG, memr(dp)); iramw(XHREG, hibyte(dp)); iramw(XLREG, lobyte(dp)); } function op27_dys() { qreg = 7; dp = decr16(hilo(iramr(YHREG), iramr(YLREG))); memw(dp, iramr(AREG)); iramw(YHREG, hibyte(dp)); iramw(YLREG, lobyte(dp)); } /* rotate / shift */ function opd2_sr() { alu = (cflag << 8) | iramr(AREG); iramw(AREG, lobyte(alu >> 1)); if ((alu & 1) != 0) { cflag = 1; } else { cflag = 0; } } function op5a_sl() { alu = (iramr(AREG) << 1) | cflag; iramw(AREG, lobyte(alu)); if ((alu & 0xff00) != 0) { cflag = 1; } else { cflag = 0; } } function op1c_srw() { dreg = incr8(iramr(IREG)); alu = 0; do { alu = (alu << 8) | iramr(preg); iramw(preg, lobyte(alu >> 4)); preg = incr8(preg); dreg = decr8(dreg); } while (dreg != 0); } function op1d_slw() { dreg = incr8(iramr(IREG)); alu = 0; do { alu = (iramr(preg) << 8) | (alu >> 8); iramw(preg, lobyte(alu >> 4)); preg = decr8(preg); dreg = decr8(dreg); } while (dreg != 0); } /* bit test */ function op66_tsia() { if ((iramr(AREG) & memr(pc)) == 0) { zflag = 1; } else { zflag = 0; } pc = incr16(pc); } function op62_tsim() { if ((iramr(preg) & memr(pc)) == 0) { zflag = 1; } else { zflag = 0; } pc = incr16(pc); } function opd6_tsid() { iramw(rreg - 1, memr(dp)); if ((memr(dp) & memr(pc)) == 0) { zflag = 1; } else { zflag = 0; } pc = incr16(pc); } function op4f_cup() { dreg = incr8(iramr(IREG)); zflag = 0; if (xin == 0) { do { preg = incr8(preg); dreg = decr8(dreg); } while ((!xin) && (dreg != 0x00ff)); if (xin == 0) { zflag = 1; } } } function op6f_cdn() { dreg = incr8(iramr(IREG)); zflag = 0; if (xin) { do { preg = incr8(preg); dreg = decr8(dreg); } while (xin && (dreg != 0xff)); if (xin) { zflag = 1; } } } /* BCD operation */ function deciadd(p, q) { var ans = 0; ans = (p & 0x000f) + (q & 0x000f); if (ans > 0x0009) { ans += 6; } ans += (p & 0x00f0) + (q & 0x00f0); if ((ans & 0xfff0) > 0x0090) { ans += 0x60; } return(ans & 0x01ff); } function decisub(p, q) { var ans = 0; ans = (p & 0x000f) - (q & 0x000f); if (ans > 0x0009) { ans -= 0x06; } ans += (p & 0x00f0) - (q & 0x00f0); if ((ans & 0xfff0) > 0x0090) { ans -= 0x60; } return(ans & 0x1ff); } function op0c_adn() { dreg = incr8(iramr(IREG)); alu = iramr(AREG); zflag = 1; do { alu = deciadd(iramr(preg), alu); iramw(preg, lobyte(alu)); if ((zflag != 0) && (iramr(preg) == 0)) { zflag = 1; } preg = decr8(preg); dreg = decr8(dreg); alu >>= 8; } while (dreg != 0); if (alu != 0) { cflag = 1; } else { cflag = 0; } } function op0d_sbn() { dreg = incr8(iramr(IREG)); alu = iramr(AREG); zflag = 1; do { alu = decisub(iramr(preg), alu); iramw(preg, lobyte(alu)); if ((zflag != 0) && (iramr(preg) == 0)) { zflag = 1; } preg = decr8(preg); dreg = decr8(dreg); alu >>= 8; } while (dreg != 0); if (alu != 0) { cflag = 1; } else { cflag = 0; } } function op0e_adw() { dreg = incr8(iramr(IREG)); alu = 0; zflag = 1; do { alu = deciadd(iramr(preg), alu); alu = (alu & 0x0100) | deciadd(lobyte(alu), iramr(qreg)); iramw(preg, lobyte(alu)); if ((zflag != 0) && (iramr(preg) == 0)) { zflag = 1; } preg = decr8(preg); qreg = decr8(qreg); dreg = decr8(dreg); alu >>= 8; } while (dreg != 0); if (alu != 0) { cflag = 1; } else { cflag = 0; } } function op0f_sbw() { dreg = incr8(iramr(IREG)); alu = 0; zflag = 1; do { alu = decisub(iramr(preg), alu); alu = (alu & 0x0100) | decisub(lobyte(alu), iramr(qreg)); iramw(preg, lobyte(alu)); if ((zflag != 0) && (iramr(preg) == 0)) { zflag = 1; } preg = decr8(preg); qreg = decr8(qreg); dreg = decr8(dreg); alu >>= 8; } while (dreg != 0); if (alu != 0) { cflag = 1; } else { cflag = 0; } } /* jumps */ function op2c_jrp() { pc = add16(pc, memr(pc)); } function op2d_jrm() { pc = sub16(pc, memr(pc)); } function op38_jrzp() { if (zflag != 0) { pc = add16(pc, memr(pc)); } else { pc = incr16(pc); } } function op39_jrzm() { if (zflag != 0) { pc = sub16(pc, memr(pc)); } else { pc = incr16(pc); } } function op28_jrnzp() { if (zflag == 0) { pc = add16(pc, memr(pc)); } else { pc = incr16(pc); } } function op29_jrnzm() { if (zflag == 0) { pc = sub16(pc, memr(pc)); } else { pc = incr16(pc); } } function op3a_jrcp() { if (cflag != 0) { pc = add16(pc, memr(pc)); } else { pc = incr16(pc); } } function op3b_jrcm() { if (cflag != 0) { pc = sub16(pc, memr(pc)); } else { pc = incr16(pc); } } function op2a_jrncp() { if (cflag == 0) { pc = add16(pc, memr(pc)); } else { pc = incr16(pc); } } function op2b_jrncm() { if (cflag == 0) { pc = sub16(pc, memr(pc)); } else { pc = incr16(pc); } } function op79_jp() { pc = hilo(memr(pc), memr(pc + 1)); } function op7e_jpz() { if (zflag != 0) { pc = hilo(memr(pc), memr(pc + 1)); } else { pc = add16(pc, 2); } } function op7c_jpnz() { if (zflag == 0) { pc = hilo(memr(pc), memr(pc + 1)); } else { pc = add16(pc, 2); } } function op7f_jpc() { if (cflag != 0) { pc = hilo(memr(pc), memr(pc + 1)); } else { pc = add16(pc, 2); } } function op7d_jpnc() { if (cflag == 0) { pc = hilo(memr(pc), memr(pc + 1)); } else { pc = add16(pc, 2); } } function op2f_loop() { alu = iramr(rreg); --alu; iramw(rreg, lobyte(alu)); chkcz(); if (cflag != 0) { pc = incr16(pc); } else { pc = sub16(pc, memr(pc)); } } function op7a_case1() { dreg = memr(pc); pc = incr16(pc); rreg = decr8(rreg); iramw(rreg, memr(pc)); pc = incr16(pc); rreg = decr8(rreg); iramw(rreg, memr(pc)); pc = incr16(pc); } function op69_case2() { do { pc = incr16(pc); if (iramr(AREG) == memr(pc - 1)) { pc = hilo(memr(pc), memr(pc + 1)); break; } else { pc = add16(pc, 2); } dreg = decr8(dreg); } while (dreg != 0); if (dreg == 0) { pc = hilo(memr(pc), memr(pc + 1)); } } function opex_cal() { pc = incr16(pc); rreg = decr8(rreg); iramw(rreg, hibyte(pc)); rreg = decr8(rreg); iramw(rreg, lobyte(pc)); pc = hilo(opcode & 0x001f, memr(pc - 1)); } function op78_call() { pc = add16(pc, 2); rreg = decr8(rreg); iramw(rreg, hibyte(pc)); rreg = decr8(rreg); iramw(rreg, lobyte(pc)); pc = hilo(memr(pc - 2), memr(pc - 1)); } function op37_rtn() { pc = hilo(iramr(rreg + 1), iramr(rreg)); rreg = add8(rreg, 2); } function op5d_outa() { var ch; /* if (kbdcheck()) { keyque = 1; if ((iaport != 0) && (iramr(ia) == 0)) { ++iacnt; if (iacnt > 2) { keychar = ttyin(); ch = keychar; if (ch > 0) { keyscan(ch); } else { keyscan(0); } } } iacnt = 0; } else { keyque = 0; } */ qreg = IAPORT; iaval = iramr(IAPORT); } function opdd_outb() { qreg= IBPORT; ibval = iramr(IBPORT); } function op5f_outf() { qreg= FOPORT foval = iramr(FOPORT); } function opdf_outc() { qreg = CTRLPORT; ctrlval = iramr(CTRLPORT); disp_on = ctrlval & 1; if (!disp_on) { // busy(); ; } if (ctrlval & 2) { ticks = 0; ticks2 = 0; div500 = 0; div2 = 0; } if ((ctrlval & 8) != 0) { power_on = 1; } else { //power_on = 0; power_on = 1; } } function bit(ii) { var jj; for (jj = 0; jj < 8; jj++) { if (ii & 1) { break; } ii >>= 1; } return(jj); } function op4c_ina() { var ii; var jj; iramw(AREG, 0); if ((iaval == 0) && (memr(0x7e00) != 0)) { jj = bit(memr(0x7e00)); if (jj < 7) { iramw(AREG, keym[jj]); } } else { jj = bit(iaval); if (jj < 7) { iramw(AREG, keym[jj + 7]); } } if (iramr(AREG) == 0) { zflag = 1; } else { zflag = 0; } } function opcc_inb() { iramw(AREG, 0x38); if (iramr(AREG) == 0) { zflag = 1; } else { zflag = 0; } } function opd0_sc() { cflag = 1; zflag = 1; } function opd1_rc() { cflag = 0; zflag = 1; } function opxx_nop() { /* no operation */ } function op4e_wait() { pc = incr16(pc); } function op6b_test() { testport = 0; if (div2 != 0) { testport |= 1; } if (div500 != 0) { testport |= 2; } if (kon != 0) { testport |= 8; } if ((testport & memr(pc)) == 0) { zflag = 1; } else { zflag = 0; } pc = incr16(pc); } /* undefined code */ function opxx_undef() { alert("Undefined code: " + hex2(opcode) + " at " + hex4(pc)); } /* */ var opfunc = new Array( op00_lii, op01_lij, op02_lia, op03_lib, op04_ix, op05_dx, op06_iy, op07_dy, op08_mvw, op09_exw, op0a_mvb, op0b_exb, op0c_adn, op0d_sbn, op0e_adw, op0f_sbw, /* 1x */ op10_lidp, op11_lidl, op12_lip, op13_liq, op14_adb, op15_sbb, opxx_undef, opxx_undef, op18_mvwd, op19_exwd, op1a_mvbd, op1b_exbd, op1c_srw, op1d_slw, op1e_film, op1f_fild, /* 2x */ op20_ldp, op21_ldq, op22_ldr, op23_clra, op24_ixl, op25_dxl, op26_iys, op27_dys, op28_jrnzp, op29_jrnzm, op2a_jrncp, op2b_jrncm, op2c_jrp, op2d_jrm, opxx_undef, op2f_loop, /* 3x */ op30_stp, op31_stq, op32_str, opxx_nop, op34_push, op35_mvwp, opxx_undef, op37_rtn, op38_jrzp, op39_jrzm, op3a_jrcp, op3b_jrcm, opxx_undef, opxx_undef, opxx_undef, opxx_undef, /* 4x */ op40_inci, op41_deci, op42_inca, op43_deca, op44_adm, op45_sbm, op46_anma, op47_orma, op48_inck, op49_deck, op4a_incm, op4b_decm, op4c_ina, opxx_nop, op4e_wait, op4f_cup, /* 5x */ op50_incp, op51_decp, op52_std, op53_mvdm, op54_mvmp, op55_mvmd, op56_ldpc, op57_ldd, op58_swp, op59_ldm, op5a_sl, op5b_pop, opxx_undef, op5d_outa, opxx_undef, op5f_outf, /* 6x */ op60_anim, op61_orim, op62_tsim, op63_cpim, op64_ania, op65_oria, op66_tsia, op67_cpia, opxx_nop, op69_case2, opxx_nop, op6b_test, opxx_undef, opxx_undef, opxx_undef, op6f_cdn, /* 7x */ op70_adim, op71_sbim, op72_rz, op72_rz, op74_adia, op75_sbia, op72_rz, op72_rz, op78_call, op79_jp, op7a_case1, opxx_undef, op7c_jpnz, op7d_jpnc, op7e_jpz, op7f_jpc, /* 8x */ op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, /* 9x */ op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, /* Ax */ op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, /* Bx */ op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, op80_lp, /* Cx */ opc0_incj, opc1_decj, opc2_incb, opc3_decb, opc4_adcm, opc5_sbcm, opc6_tsma, opc7_cpma, opc8_incl, opc9_decl, opca_incn, opcb_decn, opcc_inb, opxx_nop, opxx_nop, opxx_undef, /* Dx */ opd0_sc, opd1_rc, opd2_sr, opxx_nop, opd4_anid, opd5_orid, opd6_tsid, opd7_sz, opd8_leave, opxx_nop, opda_exab, opdb_exam, opxx_undef, opdd_outb, opxx_undef, opdf_outc, /* Ex */ opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, /* Fx */ opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal, opex_cal ); function tictac() { if (++ticks >= XTICKS) { div500 = !div500; if (++ticks2 >= XTICK2) { div2 = !div2; ticks2 = 0; } ticks = 0; } } function interpret() { var dname; tictac(); opcode = memr(pc); if (step != 0) { scstatus(); alert( '' + opfunc[opcode].name + '(' + hex2(opcode) + ') at ' + hex4(pc) ); } if ((ndsteps < MAXNDS) && (stepdebug != 0)) { dname = opfunc[opcode].name + ' '; dwin.document.forms[0].debuginfo.value += hex4(pc) + ' ' + hex2(memr(pc)) + ' ' + hex2(memr(pc + 1)) + ' ' + hex2(memr(pc + 2)) + ' ' + dname.substr(5, 8) + ' P = ' + hex2(preg) + ' Q = ' + hex2(qreg) + ' R = ' + hex2(rreg) + ' I = ' + hex2(iramr(IREG)) + ' J = ' + hex2(iramr(JREG)) + ' A = ' + hex2(iramr(AREG)) + ' B = ' + hex2(iramr(BREG)) + "\n" ; ++ndsteps; } pc = incr16(pc); opfunc[opcode](); if (preg >= 0x60) { scstatus(); alert('invalid preg value: ' + hex2(preg) + ' at ' + hex4(pc)); } return(pc); } /* main loop */ function mainloop() { ++oloops; power_on = 1; keyque = -1; /* 何かキー入力が残っていることにする */ nloops = 0; do { interpret(); /* OPコード解釈 */ /* キー入力待ち状態になったら keyque = 0 になる */ ++nloops; if (nloops > MAXNLOOP) { nloops = 0; msecwait = 50; } if (keyque == 0) { msecwait = 100; } } while ((keyque != 0) && (nloops > 0)); mainid = setTimeout("mainloop()", msecwait); } function initsc() { var i; pc = 0x0000; dp = 0x0000; preg = 0; qreg = 0; rreg = IRAMSIZ; cflag = 0; zflag = 0; ticks = 0; power_on = 1; kon = 1; iaval = 0; ibval = 0; foval = 0; for (i = 0; i < IRAMSIZ; i++) { iram[i] = 0; } for (i = 0; i < 128; i++) { keym[i] = 0; } } function scstatus() { var kbchar; var code; document.getElementById("showpc").innerHTML = hex4(pc); document.getElementById("showpreg").innerHTML = hex2(preg); document.getElementById("showqreg").innerHTML = hex2(qreg); document.getElementById("showrreg").innerHTML = hex2(rreg); document.getElementById("showdp").innerHTML = hex4(dp); document.getElementById("showireg").innerHTML = hex2(iramr(IREG)); document.getElementById("showjreg").innerHTML = hex2(iramr(JREG)); document.getElementById("showareg").innerHTML = hex2(iramr(AREG)); document.getElementById("showbreg").innerHTML = hex2(iramr(BREG)); document.getElementById("showxlreg").innerHTML = hex2(iramr(XLREG)); document.getElementById("showxhreg").innerHTML = hex2(iramr(XHREG)); document.getElementById("showylreg").innerHTML = hex2(iramr(YLREG)); document.getElementById("showyhreg").innerHTML = hex2(iramr(YHREG)); document.getElementById("showkreg").innerHTML = hex2(iramr(KREG)); document.getElementById("showlreg").innerHTML = hex2(iramr(LREG)); document.getElementById("showmreg").innerHTML = hex2(iramr(MREG)); document.getElementById("shownreg").innerHTML = hex2(iramr(NREG)); document.getElementById("showcflag").innerHTML = hex2(cflag); document.getElementById("showzflag").innerHTML = hex2(zflag); document.getElementById("showpower").innerHTML = hex2(power_on); code = keychar.charCodeAt(0); kbchar = hex2(code); if ((' ' <= keychar) && (keychar <= '~')) { kbchar = kbchar + '(' + keychar + ')'; } else { kbchar = kbchar + '(.)'; } document.getElementById("showkb").innerHTML = kbchar; document.getElementById("nowop").innerHTML = opfunc[opcode].name; } function statusloop() { scstatus(); statid = setTimeout("statusloop()", 100); } /* EOF */