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({ - + - .