Added a bunch of new indirect and absolute instructions

This commit is contained in:
MatCat 2021-04-07 00:54:31 -07:00
parent 0e06cfc332
commit 108b967a87
4 changed files with 819 additions and 90 deletions

44
examples/printstring.asm Normal file
View File

@ -0,0 +1,44 @@
; printstring.asm
;
; This is a simple demonstration routine for the emulator to take a null terminated string from RAM
; and display it out to the emulators text printer.
; 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
;
; Version: 0.2.0
GLOBAL START
GLOBAL PRINTSTRING
SECTION .text
START: LDAB MYSTRING ; Put string address into AB
PHAB ; and push to the stack
JSR PRINTSTRING ; Call PRINTSTRING routine
SECTION .printstring
PRINTSTRING: PLAB
PLCD
PHAB ; Get the address of the string ^^^
LDAB $DISPLAY ; Set the output address
PHAB
PRINTLOOP: LDAB CD
CMP %A,%B
BEQ RETURN ; If we pull a 0, or null then we are done
STAL [SP]
ADD %C,$1 ; Increment our string location by 1
BCS ROLLOVER ; If it rolls over we need to go handle high byte
PLAB
ADD %A,$1 ; Icrement our output by 1
PHAB
JMP PRINTLOOP ; Loop back and keep reading in the string
ROLLOVER: ADD %D, $1
PLAB
ADD %B, $1
PHAB
JMP PRINTLOOP ; Loop back and keep reading in the string
RETURN: PLAB ; To return we need to clean up our stack use first
RTS
SECTION .data
DISPLAY equ 8000h
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

134
js/cpu.js
View File

@ -33,6 +33,7 @@ const CONTROL_OEM2 = 0b00000000100000000000000000000000; // Outpu
const CONTROL_OEM3 = 0b00000001000000000000000000000000; // Output Enable MUX 3 const CONTROL_OEM3 = 0b00000001000000000000000000000000; // Output Enable MUX 3
const CONTROL_OEM4 = 0b00000010000000000000000000000000; // Output Enable MUX 4 const CONTROL_OEM4 = 0b00000010000000000000000000000000; // Output Enable MUX 4
const CONTROL_OEME = 0b00000100000000000000000000000000; // Output Enable MUX Enable const CONTROL_OEME = 0b00000100000000000000000000000000; // Output Enable MUX Enable
const CONTROL_AE = 0b00001000000000000000000000000000; // ALU Enable
const CONTROL_RI = 0b00010000000000000000000000000000; // RAM Input Enable const CONTROL_RI = 0b00010000000000000000000000000000; // RAM Input Enable
const CONTROL_IRI = 0b00100000000000000000000000000000; // Instruction Register Input Enable const CONTROL_IRI = 0b00100000000000000000000000000000; // Instruction Register Input Enable
const CONTROL_MCL0 = 0b01000000000000000000000000000000; // Microcode Counter to 0 const CONTROL_MCL0 = 0b01000000000000000000000000000000; // Microcode Counter to 0
@ -61,7 +62,6 @@ 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_AE = 0b11100 // ALU Enable
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
@ -351,6 +351,7 @@ class CPU_8SA1 {
if (this.MC_Controls & CONTROL_RCIH) this.GPC_In_HIGH_CLK(); if (this.MC_Controls & CONTROL_RCIH) this.GPC_In_HIGH_CLK();
if (this.MC_Controls & CONTROL_RDIL) this.GPD_In_LOW_CLK(); if (this.MC_Controls & CONTROL_RDIL) this.GPD_In_LOW_CLK();
if (this.MC_Controls & CONTROL_RDIH) this.GPD_In_HIGH_CLK(); if (this.MC_Controls & CONTROL_RDIH) this.GPD_In_HIGH_CLK();
if (this.MC_Controls & CONTROL_AE ) this.ALU_CLK();
} }
@ -359,6 +360,71 @@ class CPU_8SA1 {
this._FetchDecode_CLK_neg(); this._FetchDecode_CLK_neg();
} }
ALU_CLK() {
//console.log("ALU Enable");
let ALU_A = this.DATABUS & BITMASK_8;
let ALU_B = (this.DATABUS & (BITMASK_8 << 8)) >> 8;
let ALU_Result = 0;
let ALUMUX = (this.MC_Controls & CONTROL_ALUM1) ? 0b10 : 0;
ALUMUX |= (this.MC_Controls & CONTROL_ALUM0) ? 0b01 : 0;
//console.log(`ALU: A=${ALU_A}, B=${ALU_B}, MUX: ${ALUMUX}`);
if (this.MC_Controls & CONTROL_ALUI) console.log("ALU Inverting B");
let SHIFTING = false;
if (this.MC_Controls & CONTROL_ALUSL) SHIFTING = true;
if (this.MC_Controls & CONTROL_ALUSR) SHIFTING = true;
switch (ALUMUX) {
case 0: { // ADD
if (this.MC_Controls & CONTROL_ALUI) ALU_B = ~ALU_B;
ALU_Result = ALU_A + ALU_B;
if (this.MC_Controls & CONTROL_ALUC && !SHIFTING) ALU_Result += 1;
break;
}
case 1: { // AND
ALU_Result = ALU_A & ALU_B;
if (this.MC_Controls & CONTROL_ALUI) ALU_Result = ~ALU_Result;
if (this.MC_Controls & CONTROL_ALUC && !SHIFTING) ALU_Result += 1;
break;
}
case 2: { // OR
ALU_Result = ALU_A | ALU_B;
if (this.MC_Controls & CONTROL_ALUI) ALU_Result = ~ALU_Result;
if (this.MC_Controls & CONTROL_ALUC && !SHIFTING) ALU_Result += 1;
break;
}
case 3: { // XOR
ALU_Result = ALU_A ^ ALU_B;
if (this.MC_Controls & CONTROL_ALUI) ALU_Result = ~ALU_Result;
if (this.MC_Controls & CONTROL_ALUC && !SHIFTING) ALU_Result += 1;
break;
}
}
if (this.MC_Controls & CONTROL_ALUSL) ALU_Result = ALU_Result << 1;
if ((this.MC_Controls & CONTROL_ALUSL) && (this.MC_Controls & CONTROL_ALUC)) ALU_Result = ALU_Result | 0b00000001;
if (this.MC_Controls & CONTROL_ALUSR) ALU_Result = ALU_Result >> 1;
if ((this.MC_Controls & CONTROL_ALUSR) && (this.MC_Controls & CONTROL_ALUC)) ALU_Result = ALU_Result | 0b10000000;
if (ALU_Result & 0b100000000) {
// We have a carry
this.SR = this.SR | 0b00000001;
} else {
this.SR = this.SR & 0b11111110;
}
if (ALU_Result === 0) {
// We have a ZERO
this.SR = this.SR | 0b00000010;
} else {
this.SR = this.SR & 0b11111101;
}
this.ALUSUM = ALU_Result & BITMASK_8;
}
_FetchDecode_CLK_neg() { _FetchDecode_CLK_neg() {
// We actually setup all of our fetch and decode logic during the clocks low phase // We actually setup all of our fetch and decode logic during the clocks low phase
this.DATABUS = 0; this.DATABUS = 0;
@ -482,72 +548,6 @@ 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_AE: {
//console.log("ALU Enable");
this.DATABUS = (this.GPB << 8) | this.GPA;
let ALU_A = this.DATABUS & BITMASK_8;
let ALU_B = (this.DATABUS & (BITMASK_8 << 8)) >> 8;
let ALU_Result = 0;
let ALUMUX = (MC_Controls & CONTROL_ALUM1) ? 0b10 : 0;
ALUMUX |= (MC_Controls & CONTROL_ALUM0) ? 0b01 : 0;
//console.log(`ALU: A=${ALU_A}, B=${ALU_B}, MUX: ${ALUMUX}`);
if (MC_Controls & CONTROL_ALUI) console.log("ALU Inverting B");
let SHIFTING = false;
if (MC_Controls & CONTROL_ALUSL) SHIFTING = true;
if (MC_Controls & CONTROL_ALUSR) SHIFTING = true;
switch (ALUMUX) {
case 0: { // ADD
if (MC_Controls & CONTROL_ALUI) ALU_B = ~ALU_B;
ALU_Result = ALU_A + ALU_B;
if (MC_Controls & CONTROL_ALUC && !SHIFTING) ALU_Result += 1;
break;
}
case 1: { // AND
ALU_Result = ALU_A & ALU_B;
if (MC_Controls & CONTROL_ALUI) ALU_Result = ~ALU_Result;
if (MC_Controls & CONTROL_ALUC && !SHIFTING) ALU_Result += 1;
break;
}
case 2: { // OR
ALU_Result = ALU_A | ALU_B;
if (MC_Controls & CONTROL_ALUI) ALU_Result = ~ALU_Result;
if (MC_Controls & CONTROL_ALUC && !SHIFTING) ALU_Result += 1;
break;
}
case 3: { // XOR
ALU_Result = ALU_A ^ ALU_B;
if (MC_Controls & CONTROL_ALUI) ALU_Result = ~ALU_Result;
if (MC_Controls & CONTROL_ALUC && !SHIFTING) ALU_Result += 1;
break;
}
}
if (MC_Controls & CONTROL_ALUSL) ALU_Result = ALU_Result << 1;
if ((MC_Controls & CONTROL_ALUSL) && (MC_Controls & CONTROL_ALUC)) ALU_Result = ALU_Result | 0b00000001;
if (MC_Controls & CONTROL_ALUSR) ALU_Result = ALU_Result >> 1;
if ((MC_Controls & CONTROL_ALUSR) && (MC_Controls & CONTROL_ALUC)) ALU_Result = ALU_Result | 0b10000000;
if (ALU_Result & 0b100000000) {
// We have a carry
this.SR = this.SR | 0b00000001;
} else {
this.SR = this.SR & 0b11111110;
}
if (ALU_Result === 0) {
// We have a ZERO
this.SR = this.SR | 0b00000010;
} else {
this.SR = this.SR & 0b11111101;
}
this.ALUSUM = ALU_Result & BITMASK_8;
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");

View File

@ -35,12 +35,8 @@ cpu.RAM[3] = 0;
cpu.RAM[4] = is_CMP.Bytecode; cpu.RAM[4] = is_CMP.Bytecode;
*/ */
cpu.RAM[0] = is_LDAB_i.Bytecode;
cpu.RAM[1] = 0x0100;
cpu.RAM[2] = is_PHAB.Bytecode;
cpu.RAM[3] = is_JSR.Bytecode;
cpu.RAM[4] = 0x00D0;
/*
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;
@ -86,7 +82,46 @@ cpu.RAM[0xF9] = is_JMP_i.Bytecode;
cpu.RAM[0xFA] = 0x00D5; cpu.RAM[0xFA] = 0x00D5;
cpu.RAM[0xFB] = is_PLAB.Bytecode; cpu.RAM[0xFB] = is_PLAB.Bytecode;
cpu.RAM[0xFC] = is_RTS.Bytecode; cpu.RAM[0xFC] = is_RTS.Bytecode;
*/
cpu.RAM[0] = is_LDAB_i.Bytecode;
cpu.RAM[1] = 0x0100;
cpu.RAM[2] = is_PHAB.Bytecode;
cpu.RAM[3] = is_JSR.Bytecode;
cpu.RAM[4] = 0x00D0;
cpu.RAM[0xD0] = is_PLAB.Bytecode;
cpu.RAM[0xD1] = is_PLCD.Bytecode;
cpu.RAM[0xD2] = is_PHAB.Bytecode;
cpu.RAM[0xD3] = is_LDAB_i.Bytecode;
cpu.RAM[0xD4] = 0x8000;
cpu.RAM[0xD5] = is_PHAB.Bytecode;
cpu.RAM[0xD6] = is_LDAB_GPCD.Bytecode; // printloop
cpu.RAM[0xD7] = is_CMP_gpab.Bytecode;
cpu.RAM[0xD8] = is_BEQ_i.Bytecode;
cpu.RAM[0xD9] = 0x00ED;
cpu.RAM[0xDA] = is_STAL_spin.Bytecode;
cpu.RAM[0xDB] = is_ADD_gpci.Bytecode
cpu.RAM[0xDC] = 1;
cpu.RAM[0xDD] = is_BCS_i.Bytecode;
cpu.RAM[0xDE] = 0x00E5;
cpu.RAM[0xDF] = is_PLAB.Bytecode;
cpu.RAM[0xE0] = is_ADD_gpai.Bytecode;
cpu.RAM[0xE1] = 1;
cpu.RAM[0xE2] = is_PHAB.Bytecode;
cpu.RAM[0xE3] = is_JMP_i.Bytecode;
cpu.RAM[0xE4] = 0x00D6;
cpu.RAM[0xE5] = is_ADD_gpdi.Bytecode; // rollover
cpu.RAM[0xE6] = 1;
cpu.RAM[0xE7] = is_PLAB.Bytecode;
cpu.RAM[0xE8] = is_ADD_gpbi.Bytecode;
cpu.RAM[0xE9] = 1;
cpu.RAM[0xEA] = is_PHAB.Bytecode;
cpu.RAM[0xEB] = is_JMP_i.Bytecode;
cpu.RAM[0xEC] = 0x00D6;
cpu.RAM[0xED] = is_PLAB.Bytecode; // return
cpu.RAM[0xEE] = is_RTS.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("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);

File diff suppressed because it is too large Load Diff