Refactoring of the display and some 24 bit instructions

This commit is contained in:
MatCat 2021-04-09 01:39:21 -07:00
parent a572229c87
commit a76e01aca1
6 changed files with 394 additions and 150 deletions

View File

@ -5,7 +5,7 @@
; The routine takes a simple argument on the stack with the address of the string. ; The routine takes a simple argument on the stack with the address of the string.
; The routine will use the DISPLAY variable set in .data ; The routine will use the DISPLAY variable set in .data
; ;
; Version: 0.2.0 ; Version: 0.2.1
GLOBAL START GLOBAL START
GLOBAL PRINTSTRING GLOBAL PRINTSTRING
@ -13,32 +13,33 @@
SECTION .text SECTION .text
START: LDAB MYSTRING ; Put string address into AB START: LDAB MYSTRING ; Put string address into AB
PHAB ; and push to the stack PHAB ; and push to the stack
JSR PRINTSTRING ; Call PRINTSTRING routine PJSR PRINTSTRING ; Call PRINTSTRING routine
SECTION .printstring SECTION .printstring
PRINTSTRING: PLAB PRINTSTRING: PLAB
PLCD PHAB ; Get the address of the string
PHAB ; Get the address of the string ^^^ LDA $DISPLAY ; Set the output address
LDAB $DISPLAY ; Set the output address PHA
LDAB $DISPLAY+1 ; Set the output address
PHAB PHAB
PRINTLOOP: LDAB CD PRINTLOOP: LDAB CD
CMP %A,%B CMP A,B
BEQ RETURN ; If we pull a 0, or null then we are done BEQ RETURN ; If we pull a 0, or null then we are done
STAL [SP] STAL [SP]
ADD %C,$1 ; Increment our string location by 1 ADD C,$1 ; Increment our string location by 1
BCS ROLLOVER ; If it rolls over we need to go handle high byte BCS ROLLOVER ; If it rolls over we need to go handle high byte
PLAB PLAB
ADD %A,$1 ; Icrement our output by 1 ADD A,$1 ; Icrement our output by 1
PHAB PHAB
JMP PRINTLOOP ; Loop back and keep reading in the string JMP PRINTLOOP ; Loop back and keep reading in the string
ROLLOVER: ADD %D, $1 ROLLOVER: ADD D, $1
PLAB PLAB
ADD %B, $1 ADD B, $1
PHAB PHAB
JMP PRINTLOOP ; Loop back and keep reading in the string JMP PRINTLOOP ; Loop back and keep reading in the string
RETURN: PLAB ; To return we need to clean up our stack use first RETURN: PLAB ; To return we need to clean up our stack use first
RTS PRTS
SECTION .data SECTION .data
DISPLAY equ 8000h DISPLAY equ D00000h
MYSTRING DB "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc maximus erat mollis, fermentum quam at, blandit turpis. Pellentesque arcu tortor, smoke weed guam sagittis ac, posuere ut ipsum. Nulla facilisi. Mauris eget urna id sem porttitor consequat ultrices porttitor magna. Quisque condimentum porta viverra. Suspendisse ac condimentum ante. Duis accumsan augue urna, at ultricies nunc accumsan eget. Nullam eleifend.", 0 MYSTRING DB "Welcome to the MatCat 8SA1 Computer Simulator!\n\nThis is a full hardware simulation of the computer to allow for easy development testing. It is currently a heavy work in progress as it is very early alpha, so check back often for new features!\n\n\nThis demo can be seen in the examples folder on the git page at: \nhttps://mygit.space/MatCat.OpenSource/8SA1Sim", 0

View File

@ -3,56 +3,66 @@
<title>MatCat's 8SA1 CPU Emulator</title> <title>MatCat's 8SA1 CPU Emulator</title>
</head> </head>
<body style="font-family: monospace; font-size: 1.5em;"> <body style="font-family: monospace; font-size: 1.5em;">
<div style="display: flex;">
<div> <div>
<input type="button" id ="btn_rst" value="RESET" /> <span style="font-size: 0.7em;">Display (0xD00000-0xDFFFFF):</span><br />
<span style="font-size: 0.75em; display: inline-block; padding: 30px; background: rgb(213,206,166); background: -moz-radial-gradient(center, ellipse cover, rgba(213,206,166,1) 0%, rgba(201,193,144,1) 47%, rgba(183,173,112,1) 100%); background: -webkit-radial-gradient(center, ellipse cover, rgba(213,206,166,1) 0%,rgba(201,193,144,1) 47%,rgba(183,173,112,1) 100%); background: radial-gradient(ellipse at center, rgba(213,206,166,1) 0%,rgba(201,193,144,1) 47%,rgba(183,173,112,1) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#d5cea6', endColorstr='#b7ad70',GradientType=1 );">
<span id="TEXT_OUT" style="border: 1px solid black; width: 44em; height: 28em; display: inline-block; color: #ddd; padding: 2px; background-color: #222;">MatCat 8SA1 Computer<br /></span></span>
</div> </div>
<div> <div style="font-size: 0.8em; margin-left: 10px; margin-top: 30px;">
<span>DATA: </span><span id="Data_BUS"></span> <div>
<input type="button" id ="btn_rst" value="RESET" />
</div>
<div>
<span>DATA: </span><span id="Data_BUS"></span>
</div>
<div>
<span>PC&nbsp;&nbsp;: </span><span id="PC_Register"></span>
</div>
<div>
<span>MCC : </span><span id="MCC_Register"></span>
</div>
<div>
<span>CO&nbsp;&nbsp;: </span><span id="CO_Register"></span>
</div>
<div>
<span>SP&nbsp;&nbsp;: </span><span id="SP_Register"></span>
</div>
<div>
<span>SR&nbsp;&nbsp;: </span><span id="SR_Register"></span>
</div>
<div>
<span>IR&nbsp;&nbsp;: </span><span id="IR_Register"></span>
</div>
<div>
<span>IR2&nbsp;: </span><span id="IR2_Register"></span>
</div>
<div>
<span>GPA : </span><span id="GPA_Register"></span>
</div>
<div>
<span>GPB : </span><span id="GPB_Register"></span>
</div>
<div>
<span>GPC : </span><span id="GPC_Register"></span>
</div>
<div>
<span>GPD : </span><span id="GPD_Register"></span>
</div>
<div>
<input type="button" id ="btn_clk" value="CLOCK" />
<span id="clk_counter">0</span><input type="button" id ="btn_runtil" value="BREAK AT:" /> 0x<input id="addrbrk" type="text" value="07" pattern="[a-fA-F\d]+" /> <input type="button" id ="btn_stopclk" value="STOP CLOCK" disabled /><br />
<span>Clock Interval: </span><input id="clkinterval" type="number" value="1" size="4" min="1" max="999999" />mS
<span>Cycles Per Interval: </span><input id="clkcycles" type="number" value="25" size="4" min="1" max="999999" />
</div>
</div> </div>
<div>
<span>PC&nbsp;&nbsp;: </span><span id="PC_Register"></span>
</div> </div>
<div>
<span>MCC : </span><span id="MCC_Register"></span> <div style="font-size: 0.9em;">
</div>
<div>
<span>CO&nbsp;&nbsp;: </span><span id="CO_Register"></span>
</div>
<div>
<span>SP&nbsp;&nbsp;: </span><span id="SP_Register"></span>
</div>
<div>
<span>SR&nbsp;&nbsp;: </span><span id="SR_Register"></span>
</div>
<div>
<span>IR&nbsp;&nbsp;: </span><span id="IR_Register"></span>
</div>
<div>
<span>GPA : </span><span id="GPA_Register"></span>
</div>
<div>
<span>GPB : </span><span id="GPB_Register"></span>
</div>
<div>
<span>GPC : </span><span id="GPC_Register"></span>
</div>
<div>
<span>GPD : </span><span id="GPD_Register"></span>
</div>
<div>
<input type="button" id ="btn_clk" value="CLOCK" />
<span id="clk_counter">0</span><input type="button" id ="btn_runtil" value="BREAK AT:" /> 0x<input id="addrbrk" type="text" value="05" pattern="[a-fA-F\d]+" />
<span>Clock Interval: </span><input id="clkinterval" type="number" value="1" size="4" min="1" max="999999" />mS
<span>Cycles Per Interval: </span><input id="clkcycles" type="number" value="1" size="4" min="1" max="999999" />
</div>
<div>
<span>Text Output (0x8000-0x83ff):</span><br />
<span id="TEXT_OUT" style="border: 1px solid black; min-width: 48em; min-height: 2.2em; display: inline-block;"></span>
</div>
<div>
<span>RAM : [<span id="Address_BUS"></span>] <span>Lines: </span><input id="ramlines" type="number" value="4" size="4" min="1" max="1024" /></span><br /><span id="RAM"></span> <span>RAM : [<span id="Address_BUS"></span>] <span>Lines: </span><input id="ramlines" type="number" value="4" size="4" min="1" max="1024" /></span><br /><span id="RAM"></span>
</div> </div>
<div> <div style="font-size: 0.9em;">
<span>RAM (STACK): </span><br /><span id="STACK-RAM"></span> <span>RAM (STACK): </span><br /><span id="STACK-RAM"></span>
</div> </div>

View File

@ -32,6 +32,7 @@ function generateClocks_Interval(cycles_per_run=1) {
cpu.CLOCK(false); cpu.CLOCK(false);
if (cpu.ADDRBUS === breakpt) { if (cpu.ADDRBUS === breakpt) {
btn_stopclk.disabled = true;
clearInterval(intval); clearInterval(intval);
return; return;
} }
@ -53,9 +54,13 @@ function RunUntilBreak(addr,cycles = 1) {
function printTextOut(ram,startaddr,endaddr) { function printTextOut(ram,startaddr,endaddr) {
let outString = ""; let outString = "";
for (let a = startaddr; a <= endaddr; a++) { for (let a = startaddr; a <= endaddr; a++) {
if (ram[a] === 0) return outString; // kill on null if (ram[a] === 0) {
outString += String.fromCharCode(ram[a]); outString += " ";
} else {
outString += String.fromCharCode(ram[a]);
}
} }
return outString;
} }
function printRAM(ram) { function printRAM(ram) {
@ -82,9 +87,9 @@ function printRAM(ram) {
sp_ram.innerHTML = ramtext; sp_ram.innerHTML = ramtext;
let sp_stackram = document.getElementById("STACK-RAM"); let sp_stackram = document.getElementById("STACK-RAM");
ramtext = "ADDR&nbsp;&nbsp;:&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;&nbsp;&nbsp;&nbsp;B&nbsp;&nbsp;&nbsp;&nbsp;C&nbsp;&nbsp;&nbsp;&nbsp;D&nbsp;&nbsp;&nbsp;&nbsp;E&nbsp;&nbsp;&nbsp;&nbsp;F<br />"; ramtext = "ADDR&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;&nbsp;&nbsp;&nbsp;B&nbsp;&nbsp;&nbsp;&nbsp;C&nbsp;&nbsp;&nbsp;&nbsp;D&nbsp;&nbsp;&nbsp;&nbsp;E&nbsp;&nbsp;&nbsp;&nbsp;F<br />";
for (let a = 0xffe0; a < 0x10000; a+=16) { for (let a = (0xffe0 | cpu.SPP << 16); a < ((0xffe0 | cpu.SPP << 16)+0x20); a+=16) {
ramtext += "0x" + formatHex(a,4) + ": "; ramtext += "0x" + formatHex(a,6) + ": ";
for (let b = 0; b < 16; b++) { for (let b = 0; b < 16; b++) {
if (cpu.ADDRBUS === (a)+b) ramtext += '<span style="background-color: #ffff55">'; if (cpu.ADDRBUS === (a)+b) ramtext += '<span style="background-color: #ffff55">';
ramtext += formatHex(ram[(a)+b],4) + " "; ramtext += formatHex(ram[(a)+b],4) + " ";
@ -103,8 +108,8 @@ function updateHTML() {
let sp_pc = document.getElementById("PC_Register"); let sp_pc = document.getElementById("PC_Register");
sp_pc.innerText = "0x" + formatHex(cpu.PC,4); sp_pc.innerText = "0x" + formatHex(cpu.PC,4);
sp_pc.style.backgroundColor = "transparent"; sp_pc.style.backgroundColor = "transparent";
if (cpu.MC_Controls & CONTROL_PCI) sp_pc.style.backgroundColor = "#ff5555";
if (cpu.MC_Controls & CONTROL_PCC) sp_pc.style.backgroundColor = "#55ff55"; if (cpu.MC_Controls & CONTROL_PCC) sp_pc.style.backgroundColor = "#55ff55";
if (cpu.MC_Controls & CONTROL_PCI) sp_pc.style.backgroundColor = "#ff5555";
let sp_mcc = document.getElementById("MCC_Register"); let sp_mcc = document.getElementById("MCC_Register");
sp_mcc.innerText = "0x" + cpu.MCC.toString(16).toUpperCase(); sp_mcc.innerText = "0x" + cpu.MCC.toString(16).toUpperCase();
let sp_co = document.getElementById("CO_Register"); let sp_co = document.getElementById("CO_Register");
@ -114,13 +119,18 @@ function updateHTML() {
if (cpu.MC_Controls & CONTROL_SPI) sp_sp.style.backgroundColor = "#ff5555"; if (cpu.MC_Controls & CONTROL_SPI) sp_sp.style.backgroundColor = "#ff5555";
if (cpu.MC_Controls & CONTROL_SPC) sp_sp.style.backgroundColor = "#55ff55"; if (cpu.MC_Controls & CONTROL_SPC) sp_sp.style.backgroundColor = "#55ff55";
if (cpu.MC_Controls & CONTROL_SPD) sp_sp.style.backgroundColor = "#7777ff"; if (cpu.MC_Controls & CONTROL_SPD) sp_sp.style.backgroundColor = "#7777ff";
sp_sp.innerText = "0x" + formatHex(cpu.SP,4); sp_sp.innerText = "0x" + formatHex(cpu.SP | cpu.SPP << 16,6);
let sp_sr = document.getElementById("SR_Register"); let sp_sr = document.getElementById("SR_Register");
sp_sr.innerHTML = "0b" + formatBinary(cpu.SR,8,4,["","","","","","Negative","Zero","Carry"]); sp_sr.innerHTML = "0b" + formatBinary(cpu.SR,8,4,["","","","","","Negative","Zero","Carry"]);
let sp_ir = document.getElementById("IR_Register"); let sp_ir = document.getElementById("IR_Register");
sp_ir.innerText = "0b" + formatBinary(cpu.IR,16,4) + " (" + GetMnemonic(Instructions,cpu.IR) + ")"; sp_ir.innerText = `[0x${formatHex(cpu.IR,4)}] 0b` + formatBinary(cpu.IR,16,4) + " (" + GetMnemonic(Instructions,cpu.IR) + ")";
sp_ir.style.backgroundColor = "transparent"; sp_ir.style.backgroundColor = "transparent";
if (cpu.MC_Controls & CONTROL_IRI) sp_ir.style.backgroundColor = "#ff5555"; if (cpu.MC_Controls & CONTROL_IRI) sp_ir.style.backgroundColor = "#ff5555";
let sp_ir2 = document.getElementById("IR2_Register");
sp_ir2.innerText = `[0x${formatHex(cpu.IR2,4)}] 0b` + formatBinary(cpu.IR2,16,4);
sp_ir2.style.backgroundColor = "transparent";
if (cpu.OUTMUX === OECONTROL_I2) sp_ir2.style.backgroundColor = "#ff5555";
if (cpu.OUTMUX === OECONTROL_2O) sp_ir2.style.backgroundColor = "#55ff55";
let sp_gpa = document.getElementById("GPA_Register"); let sp_gpa = document.getElementById("GPA_Register");
sp_gpa.innerText = "0x" + formatHex(cpu.GPA,2); sp_gpa.innerText = "0x" + formatHex(cpu.GPA,2);
sp_gpa.style.backgroundColor = "transparent"; sp_gpa.style.backgroundColor = "transparent";
@ -151,7 +161,7 @@ function updateHTML() {
if (cpu.OUTMUX === OECONTROL_AD || cpu.OUTMUX === OECONTROL_BD || cpu.OUTMUX === OECONTROL_CD || cpu.OUTMUX === OECONTROL_DH) sp_gpd.style.backgroundColor = "#55ff55"; if (cpu.OUTMUX === OECONTROL_AD || cpu.OUTMUX === OECONTROL_BD || cpu.OUTMUX === OECONTROL_CD || cpu.OUTMUX === OECONTROL_DH) sp_gpd.style.backgroundColor = "#55ff55";
printRAM(cpu.RAM); printRAM(cpu.RAM);
let sp_textout = document.getElementById("TEXT_OUT"); let sp_textout = document.getElementById("TEXT_OUT");
sp_textout.innerText = printTextOut(cpu.RAM,0x8000,0x83ff); sp_textout.innerText = printTextOut(cpu.RAM,0xd00000,0xd00000 + (80*24));
} }
@ -162,6 +172,7 @@ class CPU_8SA1 {
this.PC = 0; // Set PC register to 0 this.PC = 0; // Set PC register to 0
this.SP = BITMASK_16; // Set SP register to 0xFFFF this.SP = BITMASK_16; // Set SP register to 0xFFFF
this.SPP = BITMASK_8;
this.SR = 0; // Set the STATUS register this.SR = 0; // Set the STATUS register
this.RR = 0; // Set lower RAM register to 0 this.RR = 0; // Set lower RAM register to 0
@ -174,6 +185,7 @@ class CPU_8SA1 {
this.MCC = 0xF; // Set the microcode counter this.MCC = 0xF; // Set the microcode counter
this.IR = 0; // Set the initial IR this.IR = 0; // Set the initial IR
this.IR2 = 0; // IR2 is used for 3 word instructions
this.MC_Controls = 0; // Set the control output lines this.MC_Controls = 0; // Set the control output lines
this.ALUSUM = 0; // ALU Register to hold SUM this.ALUSUM = 0; // ALU Register to hold SUM
@ -197,6 +209,7 @@ class CPU_8SA1 {
if (!clk_val && this._CLK) { if (!clk_val && this._CLK) {
// Clock going LOW // Clock going LOW
this._CLK = false; this._CLK = false;
this.DATABUS = 0;
this._CLOCK_LOW(); this._CLOCK_LOW();
} }
@ -204,20 +217,31 @@ class CPU_8SA1 {
} }
_CLOCK_HIGH() { _CLOCK_HIGH() {
// Call anything that needs to be called on positive clock edge // Call anything that needs to be called on positive clock edge
let OUTMUX = false;
if (this.MC_Controls & CONTROL_OEME) { if (this.MC_Controls & CONTROL_OEME) {
let OUTMUX = (this.MC_Controls & CONTROL_OEM4) ? 0b10000 : 0; OUTMUX = (this.MC_Controls & CONTROL_OEM4) ? 0b10000 : 0;
OUTMUX |= (this.MC_Controls & CONTROL_OEM3) ? 0b01000 : 0; OUTMUX |= (this.MC_Controls & CONTROL_OEM3) ? 0b01000 : 0;
OUTMUX |= (this.MC_Controls & CONTROL_OEM2) ? 0b00100 : 0; OUTMUX |= (this.MC_Controls & CONTROL_OEM2) ? 0b00100 : 0;
OUTMUX |= (this.MC_Controls & CONTROL_OEM1) ? 0b00010 : 0; OUTMUX |= (this.MC_Controls & CONTROL_OEM1) ? 0b00010 : 0;
OUTMUX |= (this.MC_Controls & CONTROL_OEM0) ? 0b00001 : 0; OUTMUX |= (this.MC_Controls & CONTROL_OEM0) ? 0b00001 : 0;
if (OUTMUX === OECONTROL_RO) { if (OUTMUX === OECONTROL_RO) {
//console.log("DATABUS = RAM");
this.DATABUS = this.RAM[this.ADDRBUS]; this.DATABUS = this.RAM[this.ADDRBUS];
if (this.DATABUS === undefined) this.DATABUS = 0; if (this.DATABUS === undefined) this.DATABUS = 0;
} }
if (OUTMUX === OECONTROL_I2) {
this.DATABUS = this.RAM[this.ADDRBUS];
if (this.DATABUS === undefined) this.DATABUS = 0;
this.IR2 = this.DATABUS;
}
if (OUTMUX === OECONTROL_HS) {
this.DATABUS = this.RAM[this.ADDRBUS];
if (this.DATABUS === undefined) this.DATABUS = 0;
this.SPP = this.DATABUS & BITMASK_8;
}
} }
if (this.MC_Controls & CONTROL_PCC ) this.PC_CLK(); if (this.MC_Controls & CONTROL_PCC ) this.PC_CLK();
if (this.MC_Controls & CONTROL_PCI ) this.PC_In_CLK(); if (this.MC_Controls & CONTROL_PCI ) this.PC_In_CLK();
if (this.MC_Controls & CONTROL_SPC ) this.SP_CLK(); if (this.MC_Controls & CONTROL_SPC ) this.SP_CLK();
@ -226,6 +250,7 @@ class CPU_8SA1 {
if (this.MC_Controls & CONTROL_IRI ) this.IR_In_CLK(); if (this.MC_Controls & CONTROL_IRI ) this.IR_In_CLK();
if (this.MC_Controls & CONTROL_RRI ) this.RR_In_CLK(); if (this.MC_Controls & CONTROL_RRI ) this.RR_In_CLK();
if (this.MC_Controls & CONTROL_RHI ) this.RH_In_CLK(); if (this.MC_Controls & CONTROL_RHI ) this.RH_In_CLK();
if ((OUTMUX === OECONTROL_SP) && (this.MC_Controls & CONTROL_RRI)) this.ADDRBUS = (this.ADDRBUS & BITMASK_16) | (this.SPP << 16);
if (this.MC_Controls & CONTROL_RAIL) this.GPA_In_LOW_CLK(); if (this.MC_Controls & CONTROL_RAIL) this.GPA_In_LOW_CLK();
if (this.MC_Controls & CONTROL_RAIH) this.GPA_In_HIGH_CLK(); if (this.MC_Controls & CONTROL_RAIH) this.GPA_In_HIGH_CLK();
if (this.MC_Controls & CONTROL_RBIL) this.GPB_In_LOW_CLK(); if (this.MC_Controls & CONTROL_RBIL) this.GPB_In_LOW_CLK();
@ -341,7 +366,7 @@ class CPU_8SA1 {
} }
case OECONTROL_SP: { case OECONTROL_SP: {
this.DATABUS = this.SP; this.DATABUS = this.SP;
//console.log("DATABUS = SP"); if (OECONTROL_SP && (MC_Controls & CONTROL_RRI)) this.ADDRBUS = (this.ADDRBUS & BITMASK_16) | (this.SPP << 16);
break; break;
} }
case OECONTROL_AL: { case OECONTROL_AL: {
@ -431,6 +456,22 @@ class CPU_8SA1 {
this.DATABUS = ((this.GPC & BITMASK_8) << 8) | (this.GPD & BITMASK_8); this.DATABUS = ((this.GPC & BITMASK_8) << 8) | (this.GPD & BITMASK_8);
break; break;
} }
case OECONTROL_I2: {
if (OECONTROL_I2 && (MC_Controls & CONTROL_SPC)) this.ADDRBUS = (this.ADDRBUS & BITMASK_16) | (this.SPP << 16);
break;
}
case OECONTROL_2O: {
this.DATABUS = this.IR2;
break;
}
case OECONTROL_HO: {
this.DATABUS = this.RH;
break;
}
case OECONTROL_HS: {
// this is done @ clock
break;
}
case OECONTROL_AO: { case OECONTROL_AO: {
this.DATABUS = (this.DATABUS & (BITMASK_8 << 8)) | this.ALUSUM; this.DATABUS = (this.DATABUS & (BITMASK_8 << 8)) | this.ALUSUM;
//console.log("DATABUS = SUM"); //console.log("DATABUS = SUM");
@ -493,7 +534,7 @@ class CPU_8SA1 {
} }
RH_In_CLK() { RH_In_CLK() {
this.RH = this.DATABUS; this.RH = (this.DATABUS & BITMASK_8);
this.ADDRBUS = this.RR | this.RH << 16; this.ADDRBUS = this.RR | this.RH << 16;
} }

View File

@ -62,10 +62,46 @@ const OECONTROL_CD = 0b10010 // GPD to HIGH, GPC to LOW
const OECONTROL_DA = 0b10011 // GPA to HIGH, GPD to LOW const OECONTROL_DA = 0b10011 // GPA to HIGH, GPD to LOW
const OECONTROL_DB = 0b10100 // GPB to HIGH, GPD to LOW const OECONTROL_DB = 0b10100 // GPB to HIGH, GPD to LOW
const OECONTROL_DC = 0b10101 // GPC to HIGH, GPD to LOW const OECONTROL_DC = 0b10101 // GPC to HIGH, GPD to LOW
const OECONTROL_I2 = 0b11000 // RAM Out, IR2 In
const OECONTROL_2O = 0b11001 // IR2 Out
const OECONTROL_HO = 0b11010 // HIGH Ram to DATABUS LOW
const OECONTROL_HS = 0b11011 // Stack Page Byte out to ADDRBUS HIGH (disables RH out)
const OECONTROL_AO = 0b11101 // ALU Output to LOW const OECONTROL_AO = 0b11101 // ALU Output to LOW
const OECONTROL_SR = 0b11110 // Status Register to LOW const OECONTROL_SR = 0b11110 // Status Register to LOW
const OECONTROL_RO = 0b11111 // RAM to DATABUS Enable const OECONTROL_RO = 0b11111 // RAM to DATABUS Enable
const CONTROL_OUT_PC = CONTROL_OEME;
const CONTROL_OUT_SP = CONTROL_OEME | CONTROL_OEM0;
const CONTROL_OUT_AL = CONTROL_OEME | CONTROL_OEM1;
const CONTROL_OUT_AH = CONTROL_OEME | CONTROL_OEM1 | CONTROL_OEM0;
const CONTROL_OUT_BL = CONTROL_OEME | CONTROL_OEM2;
const CONTROL_OUT_BH = CONTROL_OEME | CONTROL_OEM2 | CONTROL_OEM0;
const CONTROL_OUT_CL = CONTROL_OEME | CONTROL_OEM2 | CONTROL_OEM1;
const CONTROL_OUT_CH = CONTROL_OEME | CONTROL_OEM2 | CONTROL_OEM1 | CONTROL_OEM0;
const CONTROL_OUT_DL = CONTROL_OEME | CONTROL_OEM3;
const CONTROL_OUT_DH = CONTROL_OEME | CONTROL_OEM3 | CONTROL_OEM0;
const CONTROL_OUT_AB = CONTROL_OEME | CONTROL_OEM3 | CONTROL_OEM1;
const CONTROL_OUT_CA = CONTROL_OEME | CONTROL_OEM4;
const CONTROL_OUT_CD = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM1;
const CONTROL_OUT_DA = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM1 | CONTROL_OEM0;
const CONTROL_OUT_I2 = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM3;
const CONTROL_OUT_2O = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM3 | CONTROL_OEM0;
const CONTROL_OUT_HO = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM3 | CONTROL_OEM1;
const CONTROL_OUT_HS = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM3 | CONTROL_OEM1 | CONTROL_OEM0;
const CONTROL_OUT_AE = CONTROL_AE;
const CONTROL_OUT_AO = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM3 | CONTROL_OEM2 | CONTROL_OEM0;
const CONTROL_OUT_RO = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM3 | CONTROL_OEM2 | CONTROL_OEM1 | CONTROL_OEM0;
const CONTROL_ALU_ADD = CONTROL_OUT_AE;
const CONTROL_ALU_SUB = CONTROL_OUT_AE | CONTROL_ALUI | CONTROL_ALUC;
const CONTROL_ALU_NOT = CONTROL_OUT_AE | CONTROL_ALUI;
const CONTROL_ALU_AND = CONTROL_OUT_AE | CONTROL_ALUM0;
const CONTROL_ALU_NAND = CONTROL_OUT_AE | CONTROL_ALUM0 | CONTROL_ALUI;
const CONTROL_ALU_OR = CONTROL_OUT_AE | CONTROL_ALUM1;
const CONTROL_ALU_NOR = CONTROL_OUT_AE | CONTROL_ALUM1 | CONTROL_ALUI;
const CONTROL_ALU_XOR = CONTROL_OUT_AE | CONTROL_ALUM1 | CONTROL_ALUM0;
const CONTROL_ALU_XNOR = CONTROL_OUT_AE | CONTROL_ALUM1 | CONTROL_ALUM0 | CONTROL_ALUI;
function reverseString(str) { function reverseString(str) {
return str.split("").reverse().join(""); return str.split("").reverse().join("");

View File

@ -1,52 +1,63 @@
let cpu = new CPU_8SA1(); let cpu = new CPU_8SA1();
GenerateMicrocode(Instructions,cpu); GenerateMicrocode(Instructions,cpu);
cpu.RAM[0] = is_LDSPP_i.Bytecode;
cpu.RAM[1] = 0xCF;
cpu.RAM[2] = is_LDAB_i.Bytecode;
cpu.RAM[3] = 0x0100;
cpu.RAM[4] = is_PHAB.Bytecode;
cpu.RAM[5] = is_PJSR.Bytecode;
cpu.RAM[6] = 0x00D0;
cpu.RAM[0x80000] = is_RTS.Bytecode;
cpu.RAM[0] = is_LDAB_i.Bytecode; let v_printloop = 0xd9;
cpu.RAM[1] = 0x0100; let v_rollover = 0xe8;
cpu.RAM[2] = is_PHAB.Bytecode; let v_return = 0xf0;
cpu.RAM[3] = is_JSR.Bytecode; let v_displayh = 0xd0;
cpu.RAM[4] = 0x00D0; let v_displayl = 0x0;
cpu.RAM[0xD0] = is_PLAB.Bytecode; cpu.RAM[0xD0] = is_PLAB.Bytecode;
cpu.RAM[0xD1] = is_PLCD.Bytecode; cpu.RAM[0xD1] = is_PLCD.Bytecode;
cpu.RAM[0xD2] = is_PHAB.Bytecode; cpu.RAM[0xD2] = is_PHAB.Bytecode;
cpu.RAM[0xD3] = is_LDAB_i.Bytecode; cpu.RAM[0xD3] = is_LDA_i.Bytecode;
cpu.RAM[0xD4] = 0x8000; cpu.RAM[0xD4] = v_displayh;
cpu.RAM[0xD5] = is_PHAB.Bytecode; cpu.RAM[0xD5] = is_PHA.Bytecode;
cpu.RAM[0xD6] = is_LDAB_GPCD.Bytecode; // printloop cpu.RAM[0xD6] = is_LDAB_i.Bytecode;
cpu.RAM[0xD7] = is_CMP.Bytecode; cpu.RAM[0xD7] = v_displayl;
cpu.RAM[0xD8] = is_BEQ_i.Bytecode; cpu.RAM[0xD8] = is_PHAB.Bytecode;
cpu.RAM[0xD9] = 0x00ED; cpu.RAM[0xD9] = is_LDAB_GPCD.Bytecode; // printloop
cpu.RAM[0xDA] = is_STAL_spin.Bytecode; cpu.RAM[0xDA] = is_CMP.Bytecode;
cpu.RAM[0xDB] = is_ADD_gpci.Bytecode cpu.RAM[0xDB] = is_BEQ_i.Bytecode;
cpu.RAM[0xDC] = 1; cpu.RAM[0xDC] = v_return;
cpu.RAM[0xDD] = is_BCS_i.Bytecode; cpu.RAM[0xDD] = is_STAL_spin.Bytecode;
cpu.RAM[0xDE] = 0x00E5; cpu.RAM[0xDE] = is_ADD_gpci.Bytecode
cpu.RAM[0xDF] = is_PLAB.Bytecode; cpu.RAM[0xDF] = 1;
cpu.RAM[0xE0] = is_ADD_gpai.Bytecode; cpu.RAM[0xE0] = is_BCS_i.Bytecode;
cpu.RAM[0xE1] = 1; cpu.RAM[0xE1] = v_rollover;
cpu.RAM[0xE2] = is_PHAB.Bytecode; cpu.RAM[0xE2] = is_PLAB.Bytecode;
cpu.RAM[0xE3] = is_JMP_i.Bytecode; cpu.RAM[0xE3] = is_ADD_gpai.Bytecode;
cpu.RAM[0xE4] = 0x00D6; cpu.RAM[0xE4] = 1;
cpu.RAM[0xE5] = is_ADD_gpdi.Bytecode; // rollover cpu.RAM[0xE5] = is_PHAB.Bytecode;
cpu.RAM[0xE6] = 1; cpu.RAM[0xE6] = is_JMP_i.Bytecode;
cpu.RAM[0xE7] = is_PLAB.Bytecode; cpu.RAM[0xE7] = v_printloop;
cpu.RAM[0xE8] = is_ADD_gpbi.Bytecode; cpu.RAM[0xE8] = is_ADD_gpdi.Bytecode; // rollover
cpu.RAM[0xE9] = 1; cpu.RAM[0xE9] = 1;
cpu.RAM[0xEA] = is_PHAB.Bytecode; cpu.RAM[0xEA] = is_PLAB.Bytecode;
cpu.RAM[0xEB] = is_JMP_i.Bytecode; cpu.RAM[0xEB] = is_ADD_gpbi.Bytecode;
cpu.RAM[0xEC] = 0x00D6; cpu.RAM[0xEC] = 1;
cpu.RAM[0xED] = is_PLAB.Bytecode; // return cpu.RAM[0xED] = is_PHAB.Bytecode;
cpu.RAM[0xEE] = is_RTS.Bytecode; cpu.RAM[0xEE] = is_JMP_i.Bytecode;
cpu.RAM[0xEF] = v_printloop;
cpu.RAM[0xF0] = is_PLAB.Bytecode; // return
cpu.RAM[0xF1] = is_PRTS.Bytecode;
stringToRAM("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc maximus erat mollis, fermentum quam at, blandit turpis. Pellentesque arcu tortor, smoke weed guam sagittis ac, posuere ut ipsum. Nulla facilisi. Mauris eget urna id sem porttitor consequat ultrices porttitor magna. Quisque condimentum porta viverra. Suspendisse ac condimentum ante. Duis accumsan augue urna, at ultricies nunc accumsan eget. Nullam eleifend.",cpu.RAM,0x100); stringToRAM("Welcome to the MatCat 8SA1 Computer Simulator!\n\nThis is a full hardware simulation of the computer to allow for easy development testing. It is currently a heavy work in progress as it is very early alpha, so check back often for new features!\n\n\nThis demo can be seen in the examples folder on the git page at: \nhttps://mygit.space/MatCat.OpenSource/8SA1Sim",cpu.RAM,0x100);
//stringToRAM("Blackbeard420 is a Butt Fuckers",cpu.RAM,0x100); //stringToRAM("Blackbeard420 is a Butt Fuckers",cpu.RAM,0x100);
updateHTML(); updateHTML();
let btn_clk = document.getElementById("btn_clk"); let btn_clk = document.getElementById("btn_clk");
let btn_stopclk = document.getElementById("btn_stopclk");
let btn_runtil = document.getElementById("btn_runtil"); let btn_runtil = document.getElementById("btn_runtil");
let brkpt = document.getElementById("addrbrk"); let brkpt = document.getElementById("addrbrk");
let clkinterval = document.getElementById("clkinterval"); let clkinterval = document.getElementById("clkinterval");
@ -71,13 +82,23 @@ btn_runtil.addEventListener('click', function(evt) {
let addr = parseInt("0x" + brkpt.value); let addr = parseInt("0x" + brkpt.value);
let cpi = parseInt(clkcycles.value); let cpi = parseInt(clkcycles.value);
console.log(`Running ${cpi} cycles per interval`); console.log(`Running ${cpi} cycles per interval`);
btn_stopclk.disabled = false;
RunUntilBreak(addr,cpi); RunUntilBreak(addr,cpi);
}); });
btn_stopclk.addEventListener('click', function(evt) {
btn_stopclk.disabled = true;
clearInterval(intval);
});
btn_rst.addEventListener('click', function(evt) { btn_rst.addEventListener('click', function(evt) {
btn_stopclk.disabled = true;
clearInterval(intval);
cpu.PC = 0; cpu.PC = 0;
cpu.MCC = 0xf; cpu.MCC = 0xf;
cpu.IR = 0; cpu.IR = 0;
cpu.IR2 = 0;
cpu.DATABUS = 0; cpu.DATABUS = 0;
cpu.ADDRBUS = 0; cpu.ADDRBUS = 0;
cpu.MC_Controls = 0; cpu.MC_Controls = 0;
@ -89,9 +110,14 @@ btn_rst.addEventListener('click', function(evt) {
cpu.GPD = 0; cpu.GPD = 0;
cpu.SR = 0; cpu.SR = 0;
cpu.SP = BITMASK_16; cpu.SP = BITMASK_16;
cpu.SPP = BITMASK_8;
clk_count = 0; clk_count = 0;
clk_counter.innerText = clk_count; clk_counter.innerText = clk_count;
for (let a = 0xd00000; a < 0xe00000; a++) {
cpu.RAM[a] = 0;
}
}); });
window.requestAnimationFrame(drawCPUInfo); window.requestAnimationFrame(drawCPUInfo);

View File

@ -31,33 +31,6 @@ const CONTROL_IRI = 0b00100000000000000000000000000000; // Instr
const CONTROL_MCL0 = 0b01000000000000000000000000000000; // Microcode Counter to 0 const CONTROL_MCL0 = 0b01000000000000000000000000000000; // Microcode Counter to 0
const CONTROL_MCL8 = 0b10000000000000000000000000000000; // Microcode Counter to 8 const CONTROL_MCL8 = 0b10000000000000000000000000000000; // Microcode Counter to 8
*/ */
const CONTROL_OUT_PC = CONTROL_OEME;
const CONTROL_OUT_SP = CONTROL_OEME | CONTROL_OEM0;
const CONTROL_OUT_AL = CONTROL_OEME | CONTROL_OEM1;
const CONTROL_OUT_AH = CONTROL_OEME | CONTROL_OEM1 | CONTROL_OEM0;
const CONTROL_OUT_BL = CONTROL_OEME | CONTROL_OEM2;
const CONTROL_OUT_BH = CONTROL_OEME | CONTROL_OEM2 | CONTROL_OEM0;
const CONTROL_OUT_CL = CONTROL_OEME | CONTROL_OEM2 | CONTROL_OEM1;
const CONTROL_OUT_CH = CONTROL_OEME | CONTROL_OEM2 | CONTROL_OEM1 | CONTROL_OEM0;
const CONTROL_OUT_DL = CONTROL_OEME | CONTROL_OEM3;
const CONTROL_OUT_DH = CONTROL_OEME | CONTROL_OEM3 | CONTROL_OEM0;
const CONTROL_OUT_AB = CONTROL_OEME | CONTROL_OEM3 | CONTROL_OEM1;
const CONTROL_OUT_CA = CONTROL_OEME | CONTROL_OEM4;
const CONTROL_OUT_CD = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM1;
const CONTROL_OUT_DA = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM1 | CONTROL_OEM0;
const CONTROL_OUT_AE = CONTROL_AE;
const CONTROL_OUT_AO = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM3 | CONTROL_OEM2 | CONTROL_OEM0;
const CONTROL_OUT_RO = CONTROL_OEME | CONTROL_OEM4 | CONTROL_OEM3 | CONTROL_OEM2 | CONTROL_OEM1 | CONTROL_OEM0;
const CONTROL_ALU_ADD = CONTROL_OUT_AE;
const CONTROL_ALU_SUB = CONTROL_OUT_AE | CONTROL_ALUI | CONTROL_ALUC;
const CONTROL_ALU_NOT = CONTROL_OUT_AE | CONTROL_ALUI;
const CONTROL_ALU_AND = CONTROL_OUT_AE | CONTROL_ALUM0;
const CONTROL_ALU_NAND = CONTROL_OUT_AE | CONTROL_ALUM0 | CONTROL_ALUI;
const CONTROL_ALU_OR = CONTROL_OUT_AE | CONTROL_ALUM1;
const CONTROL_ALU_NOR = CONTROL_OUT_AE | CONTROL_ALUM1 | CONTROL_ALUI;
const CONTROL_ALU_XOR = CONTROL_OUT_AE | CONTROL_ALUM1 | CONTROL_ALUM0;
const CONTROL_ALU_XNOR = CONTROL_OUT_AE | CONTROL_ALUM1 | CONTROL_ALUM0 | CONTROL_ALUI;
let Instructions = new Array(); let Instructions = new Array();
@ -91,8 +64,19 @@ const InstructionTypes = {
toString() { toString() {
return this.Name; return this.Name;
} }
},
RegisterImmediate: {
Name: `Register Immediate`,
toString() {
return this.Name;
}
},
RegisterAbsolute: {
Name: `Register Absolute`,
toString() {
return this.Name;
}
} }
}; };
function IsRegister(reg) { function IsRegister(reg) {
@ -516,7 +500,7 @@ is_LDAB_a = new IS_LDAB_abs;
Instructions.push(is_LDAB_a); Instructions.push(is_LDAB_a);
class IS_STAL_imm extends Microcode_Instruction { class IS_STAL_imm24 extends Microcode_Instruction {
constructor(props) { constructor(props) {
super(props); super(props);
this.Bytecode = 0x030; this.Bytecode = 0x030;
@ -525,15 +509,22 @@ class IS_STAL_imm extends Microcode_Instruction {
this.Aliases = new Array(); this.Aliases = new Array();
this.Type = InstructionTypes.Immediate; this.Type = InstructionTypes.Immediate;
this.Operands = new Array({Operand: "$", Bitwidth: 8}); this.Operands = new Array({Operand: "$", Bitwidth: 24});
this.Words = 2; this.Words = 3;
this.Cycles = 5; this.Cycles = 11;
this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI; this.Microcode[2] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_RO | CONTROL_RRI | CONTROL_PCC; this.Microcode[3] = CONTROL_OUT_HO | CONTROL_RI;
this.Microcode[4] = CONTROL_OUT_AL | CONTROL_RI; this.Microcode[4] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[5] = CONTROL_OUT_I2 | CONTROL_PCC;
this.Microcode[6] = CONTROL_OUT_2O | CONTROL_RHI | CONTROL_PCC;
this.Microcode[7] = CONTROL_RRI;
this.Microcode[8] = CONTROL_OUT_AL | CONTROL_RI;
this.Microcode[9] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[10] = CONTROL_OUT_RO | CONTROL_RHI;
} }
} }
is_STAL_i = new IS_STAL_imm; is_STAL_i = new IS_STAL_imm24;
Instructions.push(is_STAL_i); Instructions.push(is_STAL_i);
class IS_STAH_imm extends Microcode_Instruction { class IS_STAH_imm extends Microcode_Instruction {
@ -704,7 +695,7 @@ class IS_STAB_sp extends Microcode_Instruction {
this.LongName = "STORE Register A and B"; this.LongName = "STORE Register A and B";
this.Aliases = new Array(); this.Aliases = new Array();
this.Type = InstructionTypes.Register; this.Type = InstructionTypes.RegisterAbsolute;
this.Operands = new Array({Operand: "SP", Bitwidth: 16}); this.Operands = new Array({Operand: "SP", Bitwidth: 16});
this.Words = 1; this.Words = 1;
this.Cycles = 6; this.Cycles = 6;
@ -717,12 +708,12 @@ class IS_STAB_sp extends Microcode_Instruction {
is_STAB_sp = new IS_STAB_sp; is_STAB_sp = new IS_STAB_sp;
Instructions.push(is_STAB_sp); Instructions.push(is_STAB_sp);
class IS_STAL_sp_ind extends Microcode_Instruction { class IS_PSTAL_sp_ind extends Microcode_Instruction {
constructor(props) { constructor(props) {
super(props); super(props);
this.Bytecode = 0x03A; this.Bytecode = 0x03A;
this.Mnemonic = "STAL"; this.Mnemonic = "PSTAL";
this.LongName = "STORE Register A to LOW Byte"; this.LongName = "Page STORE Register A to LOW Byte";
this.Aliases = new Array(); this.Aliases = new Array();
this.Type = InstructionTypes.Indirect; this.Type = InstructionTypes.Indirect;
@ -735,7 +726,55 @@ class IS_STAL_sp_ind extends Microcode_Instruction {
this.Microcode[5] = CONTROL_OUT_AL | CONTROL_RI; this.Microcode[5] = CONTROL_OUT_AL | CONTROL_RI;
} }
} }
is_STAL_spin = new IS_STAL_sp_ind; is_PSTAL_spin = new IS_PSTAL_sp_ind;
Instructions.push(is_PSTAL_spin);
class IS_PSTAL_imm extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x03B;
this.Mnemonic = "PSTAL";
this.LongName = "Page STORE Register A to LOW Byte";
this.Aliases = new Array();
this.Type = InstructionTypes.Immediate;
this.Operands = new Array({Operand: "$", Bitwidth: 8});
this.Words = 2;
this.Cycles = 5;
this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_RO | CONTROL_RRI | CONTROL_PCC;
this.Microcode[4] = CONTROL_OUT_AL | CONTROL_RI;
}
}
is_PSTAL_i = new IS_PSTAL_imm;
Instructions.push(is_PSTAL_i);
class IS_STAL_sp_ind24 extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x03C;
this.Mnemonic = "STAL";
this.LongName = "STORE Register A to LOW Byte";
this.Aliases = new Array();
this.Type = InstructionTypes.Indirect;
this.Operands = new Array({Operand: "[SP]", Bitwidth: 16});
this.Words = 1;
this.Cycles = 12;
this.Microcode[2] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_HO | CONTROL_RI | CONTROL_SPC;
this.Microcode[4] = CONTROL_SPC;
this.Microcode[5] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[6] = CONTROL_OUT_RO | CONTROL_RHI | CONTROL_SPD | CONTROL_SPC;
this.Microcode[7] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[8] = CONTROL_OUT_RO | CONTROL_RRI | CONTROL_SPD | CONTROL_SPC;
this.Microcode[9] = CONTROL_OUT_AL | CONTROL_RI;
this.Microcode[10] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[11] = CONTROL_OUT_RO | CONTROL_RHI;
//this.Microcode[12] = 0;
}
}
is_STAL_spin = new IS_STAL_sp_ind24;
Instructions.push(is_STAL_spin); Instructions.push(is_STAL_spin);
@ -1694,6 +1733,32 @@ class IS_JSR extends Microcode_Instruction {
this.LongName = "JUMP to Subroutine"; this.LongName = "JUMP to Subroutine";
this.Aliases = new Array(); this.Aliases = new Array();
this.Type = InstructionTypes.Immediate;
this.Operands = new Array({Operand: "$", Bitwidth: 24});
this.Words = 3;
this.Cycles = 11;
this.Microcode[2] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_PC | CONTROL_RI | CONTROL_SPD | CONTROL_SPC;
this.Microcode[4] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[5] = CONTROL_OUT_HO | CONTROL_RI | CONTROL_SPD | CONTROL_SPC;
this.Microcode[6] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[7] = CONTROL_OUT_I2 | CONTROL_PCC;
this.Microcode[8] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[9] = CONTROL_OUT_RO | CONTROL_PCI;
this.Microcode[10] = CONTROL_OUT_2O | CONTROL_RHI;
}
}
is_JSR = new IS_JSR;
Instructions.push(is_JSR);
class IS_PJSR extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x206;
this.Mnemonic = "PJSR";
this.LongName = "Page JUMP to Subroutine";
this.Aliases = new Array();
this.Type = InstructionTypes.Immediate; this.Type = InstructionTypes.Immediate;
this.Operands = new Array({Operand: "$", Bitwidth: 16}); this.Operands = new Array({Operand: "$", Bitwidth: 16});
this.Words = 2; this.Words = 2;
@ -1705,17 +1770,41 @@ class IS_JSR extends Microcode_Instruction {
} }
} }
is_JSR = new IS_JSR; is_PJSR = new IS_PJSR;
Instructions.push(is_JSR); Instructions.push(is_PJSR);
class IS_RTS extends Microcode_Instruction { class IS_RTS extends Microcode_Instruction {
constructor(props) { constructor(props) {
super(props); super(props);
this.Bytecode = 0x206; this.Bytecode = 0x207;
this.Mnemonic = "RTS"; this.Mnemonic = "RTS";
this.LongName = "RETURN from Subroutine"; this.LongName = "RETURN from Subroutine";
this.Aliases = new Array(); this.Aliases = new Array();
this.Type = InstructionTypes.SingleWord;
this.Operands = new Array();
this.Words = 1;
this.Cycles = 9;
this.Microcode[2] = CONTROL_SPC;
this.Microcode[3] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[4] = CONTROL_OUT_I2 | CONTROL_SPC;
this.Microcode[5] = CONTROL_OUT_SP | CONTROL_RRI;
this.Microcode[6] = CONTROL_OUT_RO | CONTROL_PCI;
this.Microcode[7] = CONTROL_OUT_2O | CONTROL_RHI | CONTROL_PCC;
this.Microcode[8] = CONTROL_PCC;
}
}
is_RTS = new IS_RTS;
Instructions.push(is_RTS);
class IS_PRTS extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x208;
this.Mnemonic = "PRTS";
this.LongName = "Page RETURN from Subroutine";
this.Aliases = new Array();
this.Type = InstructionTypes.SingleWord; this.Type = InstructionTypes.SingleWord;
this.Operands = new Array(); this.Operands = new Array();
this.Words = 1; this.Words = 1;
@ -1726,8 +1815,49 @@ class IS_RTS extends Microcode_Instruction {
this.Microcode[5] = CONTROL_PCC; this.Microcode[5] = CONTROL_PCC;
} }
} }
is_RTS = new IS_RTS; is_PRTS = new IS_PRTS;
Instructions.push(is_RTS); Instructions.push(is_PRTS);
class IS_JMP_imm24 extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x209;
this.Mnemonic = "JMP";
this.LongName = "JUMP to address";
this.Aliases = new Array();
this.Type = InstructionTypes.Immediate;
this.Operands = new Array({Operand: "$", Bitwidth: 24});
this.Words = 3;
this.Cycles = 7;
this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_I2 | CONTROL_PCC;
this.Microcode[4] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[5] = CONTROL_OUT_RO | CONTROL_PCI;
this.Microcode[6] = CONTROL_OUT_2O | CONTROL_RHI;
}
}
is_JMP_i24 = new IS_JMP_imm24;
Instructions.push(is_JMP_i24);
class IS_LDSPP_imm extends Microcode_Instruction {
constructor(props) {
super(props);
this.Bytecode = 0x20A;
this.Mnemonic = "LDSPP";
this.LongName = "LOAD Stack Pointer Page";
this.Aliases = new Array();
this.Type = InstructionTypes.Register;
this.Operands = new Array({Operand: "$", Bitwidth: 8});
this.Words = 2;
this.Cycles = 4;
this.Microcode[2] = CONTROL_OUT_PC | CONTROL_RRI;
this.Microcode[3] = CONTROL_OUT_HS | CONTROL_PCC;
}
}
is_LDSPP_i = new IS_LDSPP_imm;
Instructions.push(is_LDSPP_i);