Added a bunch of new indirect and absolute instructions
This commit is contained in:
parent
0e06cfc332
commit
108b967a87
44
examples/printstring.asm
Normal file
44
examples/printstring.asm
Normal 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
134
js/cpu.js
@ -33,6 +33,7 @@ const CONTROL_OEM2 = 0b00000000100000000000000000000000; // Outpu
|
||||
const CONTROL_OEM3 = 0b00000001000000000000000000000000; // Output Enable MUX 3
|
||||
const CONTROL_OEM4 = 0b00000010000000000000000000000000; // Output Enable MUX 4
|
||||
const CONTROL_OEME = 0b00000100000000000000000000000000; // Output Enable MUX Enable
|
||||
const CONTROL_AE = 0b00001000000000000000000000000000; // ALU Enable
|
||||
const CONTROL_RI = 0b00010000000000000000000000000000; // RAM Input Enable
|
||||
const CONTROL_IRI = 0b00100000000000000000000000000000; // Instruction Register Input Enable
|
||||
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_DB = 0b10100 // GPB 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_SR = 0b11110 // Status Register to LOW
|
||||
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_RDIL) this.GPD_In_LOW_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();
|
||||
}
|
||||
|
||||
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() {
|
||||
// We actually setup all of our fetch and decode logic during the clocks low phase
|
||||
this.DATABUS = 0;
|
||||
@ -482,72 +548,6 @@ class CPU_8SA1 {
|
||||
this.DATABUS = ((this.GPC & BITMASK_8) << 8) | (this.GPD & BITMASK_8);
|
||||
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: {
|
||||
this.DATABUS = (this.DATABUS & (BITMASK_8 << 8)) | this.ALUSUM;
|
||||
//console.log("DATABUS = SUM");
|
||||
|
45
js/main.js
45
js/main.js
@ -35,12 +35,8 @@ cpu.RAM[3] = 0;
|
||||
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[0xD1] = is_PLCD.Bytecode;
|
||||
cpu.RAM[0xD2] = is_PHAB.Bytecode;
|
||||
@ -86,7 +82,46 @@ cpu.RAM[0xF9] = is_JMP_i.Bytecode;
|
||||
cpu.RAM[0xFA] = 0x00D5;
|
||||
cpu.RAM[0xFB] = is_PLAB.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);
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user