From a31a1bc322af0c0852e040d60fa0680d62633587 Mon Sep 17 00:00:00 2001 From: David Souther Date: Thu, 11 Jan 2024 22:32:32 -0500 Subject: [PATCH 1/2] Start VM Builtins --- simulator/src/vm/builtins.test.ts | 21 ++++++++++++++++++++ simulator/src/vm/builtins.ts | 16 +++++++++++++++ simulator/src/vm/vm.ts | 33 +++++++++++++++++++------------ 3 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 simulator/src/vm/builtins.test.ts create mode 100644 simulator/src/vm/builtins.ts diff --git a/simulator/src/vm/builtins.test.ts b/simulator/src/vm/builtins.test.ts new file mode 100644 index 000000000..0f46da450 --- /dev/null +++ b/simulator/src/vm/builtins.test.ts @@ -0,0 +1,21 @@ +import { unwrap } from "@davidsouther/jiffies/lib/esm/result.js"; +import { Vm } from "./vm.js"; + +describe("builtins", () => { + describe("Math", () => { + test("multiply", () => { + const vm = unwrap( + Vm.build([ + { op: "push", segment: "constant", offset: 7 }, + { op: "push", segment: "constant", offset: 8 }, + { op: "call", name: "Math.multiply", nArgs: 2 }, + ]) + ); + + vm.step(); + vm.step(); + vm.step(); + expect(vm.read([0, 256])).toEqual([257, 56]); + }); + }); +}); diff --git a/simulator/src/vm/builtins.ts b/simulator/src/vm/builtins.ts new file mode 100644 index 000000000..67d867e3a --- /dev/null +++ b/simulator/src/vm/builtins.ts @@ -0,0 +1,16 @@ +import { SCREEN_SIZE } from "../cpu/memory.js"; +import { VmMemory } from "./memory.js"; + +export type VmBuiltin = (memory: VmMemory) => number; + +const BLANK_SCREEN = new Array(SCREEN_SIZE).fill(0); +export const VM_BUILTINS: Record = { + "Math.multiply": (memory) => { + const sp = memory.SP; + return (memory.get(sp - 2) * memory.get(sp - 1)) & 0xffff; + }, + "Screen.clearScreen": (memory) => { + memory.screen.loadBytes(BLANK_SCREEN); + return 0; + }, +}; diff --git a/simulator/src/vm/vm.ts b/simulator/src/vm/vm.ts index 6d1c3b3ab..ec7f2b4e5 100644 --- a/simulator/src/vm/vm.ts +++ b/simulator/src/vm/vm.ts @@ -8,6 +8,8 @@ import { import { FunctionInstruction, VmInstruction } from "../languages/vm.js"; import { VmMemory } from "./memory.js"; import { MemoryAdapter, RAM } from "../cpu/memory.js"; +import { VM_BUILTINS } from "./builtins.js"; +import { op } from "../util/asm.js"; export type VmOperation = | FunctionOperation @@ -492,19 +494,24 @@ export class Vm { } case "call": { const fnName = operation.name; - const fn = this.functionMap[fnName]; - if (!fn) throw new Error(`Calling unknown function ${fnName}`); - const base = this.memory.pushFrame( - this.invocation.opPtr, - operation.nArgs, - fn.nVars - ); - this.executionStack.push({ - function: fnName, - opPtr: 0, - nArgs: operation.nArgs, - frameBase: base, - }); + if (this.functionMap[fnName]) { + const base = this.memory.pushFrame( + this.invocation.opPtr, + operation.nArgs, + this.functionMap[fnName].nVars + ); + this.executionStack.push({ + function: fnName, + opPtr: 0, + nArgs: operation.nArgs, + frameBase: base, + }); + } else if (VM_BUILTINS[fnName]) { + const ret = VM_BUILTINS[fnName](this.memory); + const sp = this.memory.SP - operation.nArgs; + this.memory.set(sp, ret); + this.memory.SP = sp + 1; + } break; } case "return": { From c9e68b52ef8e51b1635b50f5fa677a0c83430ab5 Mon Sep 17 00:00:00 2001 From: David Souther Date: Thu, 18 Jan 2024 08:31:56 -0500 Subject: [PATCH 2/2] Unused import --- simulator/src/vm/vm.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/simulator/src/vm/vm.ts b/simulator/src/vm/vm.ts index ec7f2b4e5..93ec6df5e 100644 --- a/simulator/src/vm/vm.ts +++ b/simulator/src/vm/vm.ts @@ -9,7 +9,6 @@ import { FunctionInstruction, VmInstruction } from "../languages/vm.js"; import { VmMemory } from "./memory.js"; import { MemoryAdapter, RAM } from "../cpu/memory.js"; import { VM_BUILTINS } from "./builtins.js"; -import { op } from "../util/asm.js"; export type VmOperation = | FunctionOperation