From 1fb7d52842a6a36399508adece2556787d92296c Mon Sep 17 00:00:00 2001 From: zanostro Date: Fri, 5 Dec 2025 18:03:48 +0100 Subject: [PATCH] big endian fix --- simulator_SIC_XE/include/file_device.h | 3 ++ simulator_SIC_XE/src/file_device.cpp | 46 ++++++++++++++-------- simulator_SIC_XE/src/instructions.cpp | 7 +++- simulator_SIC_XE/src/machine.cpp | 54 ++++++++++++++++---------- 4 files changed, 73 insertions(+), 37 deletions(-) diff --git a/simulator_SIC_XE/include/file_device.h b/simulator_SIC_XE/include/file_device.h index e98bfc6..a08e2ac 100644 --- a/simulator_SIC_XE/include/file_device.h +++ b/simulator_SIC_XE/include/file_device.h @@ -13,7 +13,10 @@ public: void write(unsigned char value) override; private: + void ensureFileOpen(); std::fstream fileStream; + std::string filename; + bool fileCreated; }; #endif // FILE_DEVICE_H \ No newline at end of file diff --git a/simulator_SIC_XE/src/file_device.cpp b/simulator_SIC_XE/src/file_device.cpp index 3dd404f..8ca554f 100644 --- a/simulator_SIC_XE/src/file_device.cpp +++ b/simulator_SIC_XE/src/file_device.cpp @@ -3,21 +3,9 @@ #include FileDevice::FileDevice(const std::string &filename) + : filename(filename), fileCreated(false) { - fileStream.open(filename, std::ios::in | std::ios::out | std::ios::binary); - if (!fileStream.is_open()) { - std::ofstream create(filename, std::ios::binary); - if (!create) { - throw std::runtime_error("Failed to create file: " + filename); - } - create.close(); - - fileStream.clear(); - fileStream.open(filename, std::ios::in | std::ios::out | std::ios::binary); - if (!fileStream.is_open()) { - throw std::runtime_error("Failed to open file after creating: " + filename); - } - } + // Don't create the file yet - wait until first write } FileDevice::~FileDevice() @@ -27,19 +15,45 @@ FileDevice::~FileDevice() } } +void FileDevice::ensureFileOpen() +{ + if (!fileStream.is_open()) { + if (fileCreated) { + fileStream.open(filename, std::ios::in | std::ios::out); + } else { + std::ofstream create(filename); + if (!create) { + throw std::runtime_error("Failed to create file: " + filename); + } + create.close(); + fileCreated = true; + + fileStream.open(filename, std::ios::in | std::ios::out); + if (!fileStream.is_open()) { + throw std::runtime_error("Failed to open file after creating: " + filename); + } + } + } +} + unsigned char FileDevice::read() { unsigned char value = 0; + ensureFileOpen(); if (fileStream.is_open()) { - fileStream.read(reinterpret_cast(&value), sizeof(value)); + char ch; + if (fileStream.get(ch)) { + value = static_cast(ch); + } } return value; } void FileDevice::write(unsigned char value) { + ensureFileOpen(); if (fileStream.is_open()) { - fileStream.write(reinterpret_cast(&value), sizeof(value)); + fileStream.put(static_cast(value)); fileStream.flush(); } } \ No newline at end of file diff --git a/simulator_SIC_XE/src/instructions.cpp b/simulator_SIC_XE/src/instructions.cpp index 9a88a68..02124b9 100644 --- a/simulator_SIC_XE/src/instructions.cpp +++ b/simulator_SIC_XE/src/instructions.cpp @@ -262,7 +262,12 @@ void ldb_handler(Machine &m, int ea, AddressingMode mode) void ldch_handler(Machine &m, int ea, AddressingMode mode) { - int val = resolveWordOperand(m, ea, mode); + int val; + if (mode == AddressingMode::IMMEDIATE) { + val = ea & 0xFF; + } else { + val = m.getByte(ea); + } m.setA((m.getA() & 0xFFFF00) | (val & 0xFF)); } diff --git a/simulator_SIC_XE/src/machine.cpp b/simulator_SIC_XE/src/machine.cpp index 9570054..e15e6c1 100644 --- a/simulator_SIC_XE/src/machine.cpp +++ b/simulator_SIC_XE/src/machine.cpp @@ -19,8 +19,19 @@ Machine::Machine() devices[0] = make_shared(std::cin); // device 1: standard output devices[1] = make_shared(std::cout); - // device 2: standard error - devices[2] = make_shared(std::cerr); + + // Initialize devices >= 2 as FileDevice with hex names in devices directory + for (int i = 2; i < NUM_DEVICES; i++) { + char hex[3]; + snprintf(hex, sizeof(hex), "%02X", i); + std::string filename = "devices/" + std::string(hex) + ".dev"; + try { + devices[i] = std::make_shared(filename); + } catch (const std::exception &e) { + cerr << prefix << "Warning: Failed to initialize FileDevice for device " << i << ": " << e.what() << endl; + } + } + _exex_mode = false; _instructionsTable = instructions; } @@ -204,7 +215,8 @@ int Machine::getWord(int address) cerr << prefix << "Invalid memory address: " << address << endl; return -1; } - return static_cast(memory[address]) | (static_cast(memory[address + 1]) << 8) | (static_cast(memory[address + 2]) << 16); + // Big-endian: high byte first + return (static_cast(memory[address]) << 16) | (static_cast(memory[address + 1]) << 8) | static_cast(memory[address + 2]); } // Assuming word is 3 bytes @@ -216,9 +228,10 @@ void Machine::setWord(int address, int value) } value &= 0xFFFFFF; - memory[address] = static_cast(value & 0xFF); + // Big-endian: high byte first + memory[address] = static_cast((value >> 16) & 0xFF); memory[address + 1] = static_cast((value >> 8) & 0xFF); - memory[address + 2] = static_cast((value >> 16) & 0xFF); + memory[address + 2] = static_cast(value & 0xFF); } double Machine::getFloat(int address) @@ -228,14 +241,14 @@ double Machine::getFloat(int address) return 0.0; } - // load 6 bytes, little-endian → 48-bit word + // load 6 bytes, big-endian → 48-bit word unsigned long long raw = - (unsigned long long)memory[address] | - ((unsigned long long)memory[address+1] << 8) | - ((unsigned long long)memory[address+2] << 16) | - ((unsigned long long)memory[address+3] << 24) | - ((unsigned long long)memory[address+4] << 32) | - ((unsigned long long)memory[address+5] << 40); + ((unsigned long long)memory[address] << 40) | + ((unsigned long long)memory[address+1] << 32) | + ((unsigned long long)memory[address+2] << 24) | + ((unsigned long long)memory[address+3] << 16) | + ((unsigned long long)memory[address+4] << 8) | + (unsigned long long)memory[address+5]; int sign = (raw >> 47) & 0x1; int exponent = (raw >> 40) & 0x7F; @@ -290,13 +303,13 @@ void Machine::setFloat(int address, double value) ((unsigned long long)exp_field << 40) | frac; - // store 6 bytes little-endian - memory[address] = (unsigned char)( raw & 0xFF); - memory[address+1] = (unsigned char)((raw >> 8) & 0xFF); - memory[address+2] = (unsigned char)((raw >> 16) & 0xFF); - memory[address+3] = (unsigned char)((raw >> 24) & 0xFF); - memory[address+4] = (unsigned char)((raw >> 32) & 0xFF); - memory[address+5] = (unsigned char)((raw >> 40) & 0xFF); + // store 6 bytes big-endian + memory[address] = (unsigned char)((raw >> 40) & 0xFF); + memory[address+1] = (unsigned char)((raw >> 32) & 0xFF); + memory[address+2] = (unsigned char)((raw >> 24) & 0xFF); + memory[address+3] = (unsigned char)((raw >> 16) & 0xFF); + memory[address+4] = (unsigned char)((raw >> 8) & 0xFF); + memory[address+5] = (unsigned char)( raw & 0xFF); } @@ -353,6 +366,7 @@ int Machine::fetch() void Machine::execute() { if (_stopped) return; + int b1 = fetch(); InstructionInfo &info = _instructionsTable[b1]; @@ -445,7 +459,7 @@ bool Machine::execSICF3F4(int opcode, int ni, int x, int b, int p, int e, int op // PC-relative, signed 12-bit if (ea_part & 0x800) // bit 11 set? ea_part |= 0xFFFFF000; // sign-extend - base = getPC(); + base = getPC(); } } // format 4 (e=1): b/p ignored, ea_part is 20-bit absolute