diff --git a/architecture/RISCV/RV32IMFD.yml b/architecture/RISCV/RV32IMFD.yml
index b7a2e1d3a..90dca4e80 100644
--- a/architecture/RISCV/RV32IMFD.yml
+++ b/architecture/RISCV/RV32IMFD.yml
@@ -4171,3 +4171,22 @@ timer:
registers.mie |= 2n ** 7n; // MTIE = 1
disable: |
registers.mie &= ~(2n ** 7n); // MTIE = 0
+
+devices:
+ - id: console
+ cls: ConsoleDevice
+ ctrl_addr: 0xf0000000
+ status_addr: 0xf0000004
+ data:
+ start: 0xf0000008
+ end: 0xf000000f
+ enabled: true
+
+ - id: os
+ cls: OSDriver
+ ctrl_addr: 0xf0000010
+ status_addr: 0xf0000014
+ data:
+ start: 0xf0000018
+ end: 0xf000001f
+ enabled: true
diff --git a/architecture/RISCV/RV64IMFD.yml b/architecture/RISCV/RV64IMFD.yml
index 2fe89a521..32af4ab14 100644
--- a/architecture/RISCV/RV64IMFD.yml
+++ b/architecture/RISCV/RV64IMFD.yml
@@ -4373,3 +4373,22 @@ timer:
registers.mie |= 2n ** 7n; // MTIE = 1
disable: |
registers.mie &= ~(2n ** 7n); // MTIE = 0
+
+devices:
+ - id: console
+ cls: ConsoleDevice
+ ctrl_addr: 0xf0000000
+ status_addr: 0xf0000004
+ data:
+ start: 0xf0000008
+ end: 0xf000000f
+ enabled: true
+
+ - id: os
+ cls: OSDriver
+ ctrl_addr: 0xf0000010
+ status_addr: 0xf0000014
+ data:
+ start: 0xf0000018
+ end: 0xf000001f
+ enabled: true
diff --git a/bun.lock b/bun.lock
index e915327c5..89ae46b75 100644
--- a/bun.lock
+++ b/bun.lock
@@ -18,7 +18,7 @@
"@uiw/codemirror-themes": "^4.25.1",
"@xterm/addon-fit": "^0.10.0",
"@xterm/addon-web-links": "^0.11.0",
- "ajv": "^8.17.1",
+ "ajv": "^8.20.0",
"ansicolor": "^2.0.3",
"bootstrap": "^5.3.8",
"bootstrap-vue-next": "^0.40.6",
@@ -581,7 +581,7 @@
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
- "ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="],
+ "ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="],
"alien-signals": ["alien-signals@3.1.2", "", {}, "sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw=="],
diff --git a/creator-assembler b/creator-assembler
index 2b4e4c1bf..548330384 160000
--- a/creator-assembler
+++ b/creator-assembler
@@ -1 +1 @@
-Subproject commit 2b4e4c1bfb35e016020c3a1139b67e92035027e7
+Subproject commit 548330384563285aef3179396dfde11aa113b29a
diff --git a/deno.lock b/deno.lock
index 0ea81da64..ca861f070 100644
--- a/deno.lock
+++ b/deno.lock
@@ -33,7 +33,6 @@
"npm:@vueuse/core@14": "14.1.0_vue@3.5.27__typescript@5.9.3_typescript@5.9.3",
"npm:@xterm/addon-fit@0.10": "0.10.0_@xterm+xterm@5.5.0",
"npm:@xterm/addon-web-links@0.11": "0.11.0_@xterm+xterm@5.5.0",
- "npm:ajv@^8.17.1": "8.17.1",
"npm:ansicolor@^2.0.3": "2.0.3",
"npm:bootstrap-vue-next@~0.40.6": "0.40.9_@floating-ui+vue@1.1.9__vue@3.5.27___typescript@5.9.3__typescript@5.9.3_@vueuse+core@14.1.0__vue@3.5.27___typescript@5.9.3__typescript@5.9.3_vue@3.5.27__typescript@5.9.3_vue-router@4.6.4__vue@3.5.27___typescript@5.9.3__typescript@5.9.3_typescript@5.9.3",
"npm:bootstrap@^5.3.8": "5.3.8_@popperjs+core@2.11.8",
@@ -4176,7 +4175,7 @@
"npm:@vueuse/core@14",
"npm:@xterm/addon-fit@0.10",
"npm:@xterm/addon-web-links@0.11",
- "npm:ajv@^8.17.1",
+ "npm:ajv@^8.20.0",
"npm:ansicolor@^2.0.3",
"npm:bootstrap-vue-next@~0.40.6",
"npm:bootstrap@^5.3.8",
diff --git a/docs/schema/architecture.json b/docs/schema/architecture.json
index cc49f8269..196bdf8fb 100644
--- a/docs/schema/architecture.json
+++ b/docs/schema/architecture.json
@@ -17,13 +17,6 @@
"description": "Architecture version",
"type": "string"
},
- "register_files": {
- "description": "Register files of the architecture",
- "type": "array",
- "items": {
- "$ref": "#/definitions/RegisterFile"
- }
- },
"config": {
"description": "Metadata about the architecture",
"allOf": [
@@ -32,6 +25,13 @@
}
]
},
+ "devices": {
+ "description": "Device configuration",
+ "type": ["array", "null"],
+ "items": {
+ "$ref": "#/definitions/Device"
+ }
+ },
"directives": {
"description": "Directives allowed",
"type": "array",
@@ -106,6 +106,13 @@
}
}
},
+ "register_files": {
+ "description": "Register files of the architecture",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/RegisterFile"
+ }
+ },
"timer": {
"description": "Timer configuration",
"anyOf": [
@@ -154,70 +161,11 @@
}
]
},
- "RegisterFile": {
- "description": "Register file",
- "type": "object",
- "required": ["double_precision", "registers", "name", "type"],
- "properties": {
- "double_precision": {
- "description": "Whether the registers have double the word size",
- "type": "boolean"
- },
- "registers": {
- "description": "Registers in this file",
- "type": "array",
- "items": {
- "$ref": "#/definitions/Register"
- }
- },
- "name": {
- "description": "Name of the register file",
- "type": "string"
- },
- "type": {
- "description": "Type of the registers",
- "allOf": [
- {
- "$ref": "#/definitions/RegisterType"
- }
- ]
- }
- }
- },
- "RegisterType": {
- "description": "Types of register files allowed",
- "oneOf": [
- {
- "description": "Control registers",
- "type": "string",
- "enum": ["ctrl"]
- },
- {
- "description": "Integer registers",
- "type": "string",
- "enum": ["int"]
- },
- {
- "description": "Floating point registers",
- "type": "string",
- "enum": ["float"]
- },
- {
- "description": "Vector registers",
- "type": "string",
- "enum": ["v_registers"]
- },
- {
- "description": "Control state registers",
- "type": "string",
- "enum": ["csr_registers"]
- }
- ]
- },
"Config": {
"description": "Architecture metadata attributes",
"type": "object",
"required": [
+ "comment_prefix",
"description",
"endianness",
"main_function",
@@ -310,6 +258,50 @@
}
}
},
+ "Device": {
+ "type": "object",
+ "required": ["cls", "ctrl_addr", "data", "id", "status_addr"],
+ "properties": {
+ "cls": {
+ "description": "Device class",
+ "allOf": [
+ {
+ "$ref": "#/definitions/DeviceClasses"
+ }
+ ]
+ },
+ "ctrl_addr": {
+ "description": "Device's control register's address",
+ "type": "integer",
+ "minimum": 0.0
+ },
+ "data": {
+ "description": "Device's data segment",
+ "allOf": [
+ {
+ "$ref": "#/definitions/Range_of_Integer"
+ }
+ ]
+ },
+ "enabled": {
+ "description": "Device's default status (default: enabled)",
+ "type": ["boolean", "null"]
+ },
+ "id": {
+ "description": "Device ID",
+ "type": "string"
+ },
+ "status_addr": {
+ "description": "Device's status register's address",
+ "type": "integer",
+ "minimum": 0.0
+ }
+ }
+ },
+ "DeviceClasses": {
+ "type": "string",
+ "enum": ["ConsoleDevice", "OSDriver"]
+ },
"Assembler": {
"description": "CREATOR Assembler",
"type": "object",
@@ -523,6 +515,7 @@
"nwords": {
"description": "Size of the instruction",
"type": "integer",
+
"minimum": 0.0
},
"properties": {
@@ -1164,7 +1157,6 @@
"Function call",
"Transfer between registers",
"Memory access",
- "Vector Set Length Instruction with an inmediate",
"Other"
]
},
@@ -1199,7 +1191,7 @@
],
"properties": {
"check": {
- "description": "JS code to be executed in order to check what type of interrupt ocurred. It must return an `InterruptType` (if an interrupt happened) or `null` (if it didn't)",
+ "description": "JS code to be executed in order to check what type of interrupt occurred. It must return an `InterruptType` (if an interrupt happened) or `null` (if it didn't)",
"type": "string"
},
"clear": {
@@ -1375,14 +1367,10 @@
"required": ["end", "start"],
"properties": {
"end": {
- "type": "integer",
- "minimum": 0,
- "maximum": 18446744073709551615
+ "type": "integer"
},
"start": {
- "type": "integer",
- "minimum": 0,
- "maximum": 18446744073709551615
+ "type": "integer"
}
}
},
@@ -1424,6 +1412,63 @@
}
}
},
+ "RegisterFile": {
+ "description": "Register file",
+ "type": "object",
+ "oneOf": [
+ {
+ "description": "Control registers",
+ "type": "object",
+ "required": ["type"],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": ["ctrl"]
+ }
+ }
+ },
+ {
+ "description": "Integer registers",
+ "type": "object",
+ "required": ["type"],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": ["int"]
+ }
+ }
+ },
+ {
+ "description": "Floating point registers",
+ "type": "object",
+ "required": ["double_precision", "type"],
+ "properties": {
+ "double_precision": {
+ "description": "Whether the registers have double the word size",
+ "type": "boolean"
+ },
+ "type": {
+ "type": "string",
+ "enum": ["float"]
+ }
+ }
+ }
+ ],
+ "required": ["name", "registers"],
+ "properties": {
+ "name": {
+ "description": "Name of the register file",
+ "type": "string"
+ },
+ "registers": {
+ "description": "Registers in this file",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/Register"
+ }
+ }
+ }
+ },
"RegisterProperty": {
"description": "Properties of a register",
"oneOf": [
diff --git a/package.json b/package.json
index 4e04622b2..aa08b9942 100644
--- a/package.json
+++ b/package.json
@@ -35,7 +35,7 @@
"@uiw/codemirror-themes": "^4.25.1",
"@xterm/addon-fit": "^0.10.0",
"@xterm/addon-web-links": "^0.11.0",
- "ajv": "^8.17.1",
+ "ajv": "^8.20.0",
"ansicolor": "^2.0.3",
"bootstrap": "^5.3.8",
"bootstrap-vue-next": "^0.40.6",
diff --git a/src/core/capi/memory.mts b/src/core/capi/memory.mts
index 146440b3a..f7df840a7 100644
--- a/src/core/capi/memory.mts
+++ b/src/core/capi/memory.mts
@@ -17,12 +17,17 @@
* along with CREATOR. If not, see .
*/
-import { main_memory, stackTracker, BYTESIZE, REGISTERS } from "../core.mjs";
+import {
+ main_memory,
+ stackTracker,
+ deviceManager,
+ BYTESIZE,
+ REGISTERS,
+} from "../core.mjs";
import { exit } from "../executor/executor.mjs";
import { raise } from "./validation.mts";
import { crex_findReg } from "../register/registerLookup.mjs";
import { sentinel } from "../sentinel/sentinel.mts";
-import { checkDeviceAddr, devices } from "../executor/devices.mts";
import type { Memory } from "../memory/Memory.mts";
import { toHex } from "../utils/utils.mjs";
@@ -48,11 +53,7 @@ function writeValueToMemory(
}
// get memory
- const deviceID = checkDeviceAddr(Number(address));
- const memory =
- deviceID === null
- ? (main_memory as Memory)
- : devices.get(deviceID)!.memory;
+ const memory = selectMemory(address);
const wordSize = memory.getWordSize();
@@ -116,11 +117,7 @@ function writeValueToMemory(
*/
function readValueFromMemory(address: bigint, bytes: number): bigint {
// get memory
- const deviceID = checkDeviceAddr(Number(address));
- const memory =
- deviceID === null
- ? (main_memory as Memory)
- : devices.get(deviceID)!.memory;
+ const memory = selectMemory(address);
const wordSize = memory.getWordSize();
if (bytes === 1) {
@@ -167,6 +164,17 @@ function readValueFromMemory(address: bigint, bytes: number): bigint {
}
}
+/**
+ * Selects the memory instance (main memory or device memory) depending on the
+ * address
+ */
+function selectMemory(address: bigint): Memory {
+ const deviceID = deviceManager.checkDeviceAddr(Number(address));
+ return deviceID === null
+ ? (main_memory as Memory)
+ : deviceManager.devices.get(deviceID)!.memory;
+}
+
/*
* Name: mp_write - Write value into a memory address
* Sypnosis: mp_write (destination_address, value2store, byte_or_half_or_word)
@@ -182,12 +190,7 @@ export const MEM = {
hint?: string,
noSegFault: boolean = true,
): void {
- // get memory
- const deviceID = checkDeviceAddr(Number(address));
- const memory =
- deviceID === null
- ? (main_memory as Memory)
- : devices.get(deviceID)!.memory;
+ const memory = selectMemory(address);
// Check if the address is in a writable segment using memory functions
const segment = memory.getSegmentForAddress(address);
@@ -261,11 +264,7 @@ export const MEM = {
noSegFault: boolean = true,
): bigint {
// get memory
- const deviceID = checkDeviceAddr(Number(address));
- const memory =
- deviceID === null
- ? (main_memory as Memory)
- : devices.get(deviceID)!.memory;
+ const memory = selectMemory(address);
// Implementation of capi_mem_read
let val = 0n;
@@ -339,11 +338,7 @@ export const MEM = {
*/
addHint(address: bigint, hint: string, sizeInBits?: number): boolean {
// get memory
- const deviceID = checkDeviceAddr(Number(address));
- const memory =
- deviceID === null
- ? (main_memory as Memory)
- : devices.get(deviceID)!.memory;
+ const memory = selectMemory(address);
try {
memory.addHint(address, [], hint, sizeInBits);
diff --git a/src/core/core.d.ts b/src/core/core.d.ts
index f9e723374..eae11ff27 100644
--- a/src/core/core.d.ts
+++ b/src/core/core.d.ts
@@ -120,6 +120,8 @@ type ArchitectureInterrupts = {
create: string;
};
+import type { DeviceList } from "./executor/DeviceManager.mts";
+
type Architecture = {
config: {
name: string;
@@ -153,6 +155,7 @@ type Architecture = {
enable: string;
disable: string;
};
+ devices?: DeviceList;
};
export declare const architecture: Architecture;
diff --git a/src/core/core.mjs b/src/core/core.mjs
index 2341b38ac..fdd2679d4 100644
--- a/src/core/core.mjs
+++ b/src/core/core.mjs
@@ -45,7 +45,7 @@ import {
InterruptManager,
} from "./executor/InterruptManager.mts";
import { init, compileArchitectureFunctions } from "./executor/executor.mjs";
-import { resetDevices } from "./executor/devices.mts";
+import { DeviceManager } from "./executor/DeviceManager.mts";
import { compileTimerFunctions } from "./executor/timers.mts";
import * as archProcessor from "./utils/architectureProcessor.mjs";
import { writeDataDumpMemory32, writeDataDumpMemory64 } from "./assembler/sailAssembler/web/CNAssambler.mjs";
@@ -111,6 +111,8 @@ export let interruptManager;
export function setInterruptManager(value) {
interruptManager = value;
}
+/** @type {DeviceManager} */
+export let deviceManager;
/** @type {MemoryBackup} */
export let main_memory_backup;
export function updateMainMemoryBackup(value) {
@@ -221,6 +223,9 @@ export function loadArchitecture(architectureYaml, isa = []) {
endianness: ENDIANNESSARR,
});
+ // setup devices
+ deviceManager = new DeviceManager(architecture.devices ?? []);
+
// Initialize stack tracker and other related components
// This must happen before creating the register backup
stackTracker = new StackTracker();
@@ -437,7 +442,7 @@ export function reset() {
interruptManager.reset();
// reset devices
- resetDevices();
+ deviceManager.resetDevices();
// Initialize execution environment
init();
@@ -687,7 +692,6 @@ export function setPC(value) {
}
export function updateCacheMem(index, type, addr, value) {
-
// Identificamps primero a que cache afecta
// Despues comprobamos si ese bloque de cache ya existe
// Si existe se reemplaza, sino se hace un push de una nueva línea
diff --git a/src/core/executor/devices.mts b/src/core/executor/DeviceManager.mts
similarity index 79%
rename from src/core/executor/devices.mts
rename to src/core/executor/DeviceManager.mts
index 4c16fb46f..9f44a7d33 100644
--- a/src/core/executor/devices.mts
+++ b/src/core/executor/DeviceManager.mts
@@ -26,6 +26,13 @@ import { MEM } from "../capi/memory.mts";
import { Memory, type MemoryBackup } from "../memory/Memory.mts";
import { coreEvents, CoreEventTypes } from "../events.mts";
+type DeviceConfig = {
+ ctrl_addr: number;
+ status_addr: number;
+ data: { start: number; end: number };
+ enabled?: boolean;
+};
+
/**
* A CREATOR device.
*
@@ -47,31 +54,26 @@ export abstract class Device {
memory: Memory;
private memoryBackup: MemoryBackup;
- constructor(
- // we use destructuring in order to have a cleaner interface later
- {
- ctrl_addr,
- status_addr,
- data: { start, end },
- enabled = true,
- }: {
- ctrl_addr: number;
- status_addr: number;
- data: { start: number; end: number };
- enabled: boolean;
- },
- ) {
- this.ctrl_addr = ctrl_addr;
- this.status_addr = status_addr;
- this.data = { start, end };
- this.enabled = enabled;
+ constructor(config: DeviceConfig) {
+ this.ctrl_addr = config.ctrl_addr;
+ this.status_addr = config.status_addr;
+ this.data = config.data;
+ this.enabled = config.enabled ?? true;
// TODO: check it doesn't conflict w/ main memory... or maybe not...?
// we don't know if ctrl_addr & status_addr will be lower or higher
// than the data segment... so we'll have to handle that
- const minAddr = Math.min(start, ctrl_addr, status_addr);
- const maxAddr = Math.max(end, ctrl_addr, status_addr);
+ const minAddr = Math.min(
+ config.data.start,
+ config.ctrl_addr,
+ config.status_addr,
+ );
+ const maxAddr = Math.max(
+ config.data.end,
+ config.ctrl_addr,
+ config.status_addr,
+ );
this.memory = new Memory({
sizeInBytes: maxAddr - minAddr + 1,
@@ -251,7 +253,7 @@ class ConsoleDevice extends Device {
}
// Decode the UTF-8 data to a string
- const buffer = new Uint8Array(bytes)
+ const buffer = new Uint8Array(bytes);
const msg = new TextDecoder().decode(buffer);
this.#write(msg, DataType.String);
@@ -385,84 +387,94 @@ class OSDriver extends Device {
}
}
-// TODO: device handler class
-// TODO: Enable/Disable devices
-// TODO: configure devices from arch definition
-
-// { : Device, ...}
-export const devices = new Map([
- [
- "console",
- new ConsoleDevice({
- ctrl_addr: 0xf0000000,
- status_addr: 0xf0000004,
- data: {
- start: 0xf0000008,
- end: 0xf000000f,
- },
- enabled: true,
- }),
- ],
- [
- "os",
- new OSDriver({
- ctrl_addr: 0xf0000010,
- status_addr: 0xf0000014,
- data: {
- start: 0xf0000018,
- end: 0xf000001f,
- },
- enabled: true,
- }),
- ],
-]);
-
-/* Memory */
+// list of available devices
+const AvailableDevices: Record Device> = {
+ ConsoleDevice,
+ OSDriver,
+};
-/**
- * Checks if an address is a device address.
- *
- * @param addr Address to check.
- *
- * @return ID of the device that the address belongs to, else `null`.
- */
-export function checkDeviceAddr(addr: number): string | null {
- for (const [id, device] of devices) {
- if (!device.enabled) continue;
- if (device.isDeviceAddr(addr)) return id;
+export type DeviceList = ({ id: string; cls: string } & DeviceConfig)[];
+
+export class DeviceManager {
+ constructor(devices: DeviceList) {
+ for (const { id, cls, ...cfg } of devices) {
+ // get device type
+ const DeviceClass = AvailableDevices[cls];
+ if (!DeviceClass) {
+ throw new Error(`Invalid device class '${cls}'`);
+ }
+
+ this.devices.set(id, new DeviceClass(cfg));
+ }
}
- return null;
-}
+ public devices = new Map();
-/* Handlers */
+ /* Memory */
-/**
- * 'Wakes up' a device, by executing its callback function.
- *
- * @param id ID of the device.
- *
- */
-export function wakeDevice(id: string): void {
- const device = devices.get(id);
- if (device !== undefined) device.handler();
-}
+ /**
+ * Checks if an address is a device address.
+ *
+ * @param addr Address to check.
+ *
+ * @return ID of the device that the address belongs to, else `null`.
+ */
+ public checkDeviceAddr(addr: number): string | null {
+ for (const [id, device] of this.devices) {
+ if (!device.enabled) continue;
-/**
- * Calls all the devices' handlers.
- */
-export function handleDevices(): void {
- for (const [_id, device] of devices) {
- if (device.enabled) device.handler();
+ if (device.isDeviceAddr(addr)) return id;
+ }
+
+ return null;
}
-}
-/**
- * Resets all the devices.
- */
-export function resetDevices(): void {
- for (const [_id, device] of devices) {
- device.reset();
+ /* Handlers */
+
+ /**
+ * Calls all the devices' handlers.
+ */
+ public handleDevices(): void {
+ for (const [_id, device] of this.devices) {
+ if (device.enabled) device.handler();
+ }
+ }
+
+ /**
+ * Resets all the devices.
+ */
+ public resetDevices(): void {
+ for (const [_id, device] of this.devices) {
+ device.reset();
+ }
+ }
+
+ /**
+ * Enables the specified device
+ *
+ * @param id ID of the device to enable
+ */
+ public enableDevice(id: string) {
+ const dev = this.devices.get(id);
+ if (!dev) {
+ throw new Error(`Invalid device ID '${id}'`);
+ }
+
+ dev.enabled = true;
+ }
+
+ /**
+ * Disables the specified device
+ *
+ * @param id ID of the device to disable
+ */
+ public disableDevice(id: string) {
+ const dev = this.devices.get(id);
+ if (!dev) {
+ throw new Error(`Invalid device ID '${id}'`);
+ }
+
+ dev.enabled = false;
}
}
diff --git a/src/core/executor/executor.mjs b/src/core/executor/executor.mjs
index be6f43100..c9bdecd5d 100644
--- a/src/core/executor/executor.mjs
+++ b/src/core/executor/executor.mjs
@@ -19,8 +19,10 @@
import { instructions, tag_instructions } from "../assembler/assembler.mjs";
import {
+ architecture,
status,
interruptManager,
+ deviceManager,
WORDSIZE,
BYTESIZE,
main_memory,
@@ -43,12 +45,10 @@ import { getPrimaryKey } from "../utils/utils.mjs";
import { decode } from "./decoder.mjs";
import { updateStats } from "./stats.mts";
import { ExecutionMode } from "./InterruptManager.mts";
-import { handleDevices } from "./devices.mts";
import { handleTimer } from "./timers.mts";
import { compileInstruction } from "./instructionCompiler.mts";
import { coreEvents } from "../events.mts";
import { clearAllRegisterGlows } from "../register/registerGlowState.mjs";
-import { architecture } from "../core.mjs";
const instructionCache = new Map();
const compiledFunctions = new Map();
@@ -386,7 +386,7 @@ function executeInstructionCycle() {
handleTimer();
// Handle Devices
- handleDevices();
+ deviceManager.handleDevices();
// Update execution status and determine next instruction
const statusResult = updateExecutionStatus();
diff --git a/src/core/utils/architectureProcessor.mjs b/src/core/utils/architectureProcessor.mjs
index db1af34a8..eaa515376 100644
--- a/src/core/utils/architectureProcessor.mjs
+++ b/src/core/utils/architectureProcessor.mjs
@@ -744,8 +744,8 @@ export function processArchitectureFromYaml(architectureYaml, isa = []) {
// validate schema
if (!validateArchSchema(architectureObj)) {
return {
- errorcode: "invalid_schema",
- token: "Invalid Schema",
+ errorcode: "invalid_arch",
+ token: "Invalid architecture",
type: "error",
update: "",
status: "ko",
diff --git a/src/core/utils/schema.mts b/src/core/utils/schema.mts
index 28791e6c0..30e8a37a6 100644
--- a/src/core/utils/schema.mts
+++ b/src/core/utils/schema.mts
@@ -36,6 +36,12 @@ export function validateSchema(object: object, schema: object): boolean {
// we need to do this, else the validator screams
delete (schema as unknown as { $schema?: string }).$schema;
- const validator = new Ajv().compile(schema);
- return validator(object);
+ try {
+ const validator = new Ajv().compile(schema);
+ return validator(object);
+ }
+ catch (error) {
+ throw new Error(`Invalid JSON schema: ${error}`)
+ }
+
}
diff --git a/src/web/components/SimulatorView.vue b/src/web/components/SimulatorView.vue
index 0522bfb3d..0a0e466bd 100644
--- a/src/web/components/SimulatorView.vue
+++ b/src/web/components/SimulatorView.vue
@@ -20,9 +20,8 @@ along with CREATOR. If not, see .
import { defineComponent, type PropType } from "vue";
import type { StackFrame } from "@/core/memory/StackTracker.mjs";
-import { architecture, loadedCreatino } from "@/core/core.mjs";
+import { architecture, deviceManager } from "@/core/core.mjs";
import { main_memory } from "@/core/core";
-import { type Device, devices } from "@/core/executor/devices.mts";
import TableExecution from "./simulator/TableExecution.vue";
import DataViewSelector from "./simulator/DataViewSelector.vue";
@@ -34,6 +33,7 @@ import Terminal from "./simulator/Terminal.vue";
import Stats from "./simulator/Stats.vue";
import Flash from "./simulator/Flash.vue";
import ArduinoTerminal from "./simulator/ArduinoTerminal.vue";
+import type { Device } from "@/core/executor/DeviceManager.mjs";
export default defineComponent({
props: {
@@ -76,7 +76,7 @@ export default defineComponent({
Stats,
Flash,
Terminal,
- ArduinoTerminal
+ ArduinoTerminal,
// App
},
@@ -84,7 +84,7 @@ export default defineComponent({
return {
architecture,
main_memory: main_memory as any,
- devices: devices as Map,
+ devices: deviceManager.devices as Map,
};
},
});
@@ -119,7 +119,7 @@ export default defineComponent({
-
+
- .