Skip to content

Commit

Permalink
Pop implementation + minor workarounds
Browse files Browse the repository at this point in the history
  • Loading branch information
darkzense committed Nov 19, 2023
1 parent 7e027c4 commit 87a3770
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 8 deletions.
4 changes: 2 additions & 2 deletions system/cpu/arch.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Push } from "../instructions/stack.js";
import { Push, Pop } from "../instructions/stack.js";
import { Executable } from "./interface.js";

const syntax: { [key: string]: RegExp } = {
Expand All @@ -18,7 +18,7 @@ const instructionSet: {
POP: {
code: 1,
type: "transfer",
executor: null,
executor: new Pop(),
},
ADD: {
code: 2,
Expand Down
3 changes: 3 additions & 0 deletions system/cpu/execution_unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { processInfo } from "../memory/data.js";
import { decodeInstruction } from "../assembler.js";
import { instructionSet } from "./arch.js";
import { Instruction, Executable } from "./interface.js";
import { resetSpOffset } from "../instructions/stack.js";

function fetch(): Instruction | null {
cpu.MAR = cpu.programCounter;
Expand Down Expand Up @@ -54,6 +55,8 @@ function resetRegisters(): void {
for (const reg of textRegisters) {
reg.value = "";
}

resetSpOffset();
}

function execute(instruction: Instruction): void {
Expand Down
2 changes: 1 addition & 1 deletion system/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { fetch, execute, resetRegisters } from "./cpu/execution_unit.js";

function run() {
try {
resetRegisters;
resetRegisters();
processInfo.objectCode = makeObjectCode();
while (true) {
const ins = fetch();
Expand Down
53 changes: 48 additions & 5 deletions system/instructions/stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,27 @@ import cpu from "../cpu/components.js";
import { Instruction, Executable } from "../cpu/interface.js";
import { getDataByAddress } from "../memory/data.js";

var spOffset = 0;

export function resetSpOffset() {
spOffset = 0;
}

export class Push implements Executable {
run(instruction: Instruction) {
var operandValue = instruction.operand;

let nextStackPointer = cpu.stackPointer.parseHex() + spOffset;
// Workaround when starting at "0000".
if (!spOffset) {
spOffset = 1;
}
cpu.stackPointer = nextStackPointer.asHex16();
const stackData = getDataByAddress("stack-data", cpu.stackPointer)!;
const stackPointer = cpu.stackPointer.parseHex();
cpu.stackPointer = (stackPointer + 1).asHex16();

const operandValue = instruction.operand;
if (!instruction.addressingMode) {
stackData.value = operandValue.toString();
} else {
const hexOperand = instruction.operand.asHex16();
const hexOperand = operandValue.asHex16();
cpu.MAR = hexOperand;

const actualData = getDataByAddress("main-data", hexOperand)!;
Expand All @@ -22,3 +31,37 @@ export class Push implements Executable {
}
}
}

export class Pop implements Executable {
run(instruction: Instruction) {
if (!instruction.addressingMode) {
throw new ReferenceError("You must 'POP' to a variable in main memory");
}

const topOfStack = getDataByAddress("stack-data", cpu.stackPointer)!;
if (!topOfStack.value) {
throw new ReferenceError("There is no data at the address of the stack pointer.");
}

let nextStackPointer = cpu.stackPointer.parseHex();
// Avoids going negative
if (nextStackPointer == 0) {
resetSpOffset();
} else {
nextStackPointer -= 1;
}
cpu.stackPointer = nextStackPointer.asHex16();

const hexOperand = instruction.operand.asHex16();
cpu.MAR = hexOperand;
const actualData = getDataByAddress("main-data", hexOperand)!;
// cpu.controlUnit = "IR(5-16)out, MARin, READ";

cpu.MDR = (+topOfStack.value).asHex16();
cpu.controlUnit = "SPout, MDRin, WRITE";
actualData.value = topOfStack.value;

topOfStack.variable = "";
topOfStack.value = "";
}
}

0 comments on commit 87a3770

Please sign in to comment.