big endian fix
This commit is contained in:
parent
f98e4b323c
commit
1fb7d52842
4 changed files with 73 additions and 37 deletions
|
|
@ -13,7 +13,10 @@ public:
|
||||||
void write(unsigned char value) override;
|
void write(unsigned char value) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void ensureFileOpen();
|
||||||
std::fstream fileStream;
|
std::fstream fileStream;
|
||||||
|
std::string filename;
|
||||||
|
bool fileCreated;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FILE_DEVICE_H
|
#endif // FILE_DEVICE_H
|
||||||
|
|
@ -3,21 +3,9 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
FileDevice::FileDevice(const std::string &filename)
|
FileDevice::FileDevice(const std::string &filename)
|
||||||
|
: filename(filename), fileCreated(false)
|
||||||
{
|
{
|
||||||
fileStream.open(filename, std::ios::in | std::ios::out | std::ios::binary);
|
// Don't create the file yet - wait until first write
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileDevice::~FileDevice()
|
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 FileDevice::read()
|
||||||
{
|
{
|
||||||
unsigned char value = 0;
|
unsigned char value = 0;
|
||||||
|
ensureFileOpen();
|
||||||
if (fileStream.is_open()) {
|
if (fileStream.is_open()) {
|
||||||
fileStream.read(reinterpret_cast<char*>(&value), sizeof(value));
|
char ch;
|
||||||
|
if (fileStream.get(ch)) {
|
||||||
|
value = static_cast<unsigned char>(ch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDevice::write(unsigned char value)
|
void FileDevice::write(unsigned char value)
|
||||||
{
|
{
|
||||||
|
ensureFileOpen();
|
||||||
if (fileStream.is_open()) {
|
if (fileStream.is_open()) {
|
||||||
fileStream.write(reinterpret_cast<const char*>(&value), sizeof(value));
|
fileStream.put(static_cast<char>(value));
|
||||||
fileStream.flush();
|
fileStream.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -262,7 +262,12 @@ void ldb_handler(Machine &m, int ea, AddressingMode mode)
|
||||||
|
|
||||||
void ldch_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));
|
m.setA((m.getA() & 0xFFFF00) | (val & 0xFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,19 @@ Machine::Machine()
|
||||||
devices[0] = make_shared<InputDevice>(std::cin);
|
devices[0] = make_shared<InputDevice>(std::cin);
|
||||||
// device 1: standard output
|
// device 1: standard output
|
||||||
devices[1] = make_shared<OutputDevice>(std::cout);
|
devices[1] = make_shared<OutputDevice>(std::cout);
|
||||||
// device 2: standard error
|
|
||||||
devices[2] = make_shared<OutputDevice>(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<FileDevice>(filename);
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
cerr << prefix << "Warning: Failed to initialize FileDevice for device " << i << ": " << e.what() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_exex_mode = false;
|
_exex_mode = false;
|
||||||
_instructionsTable = instructions;
|
_instructionsTable = instructions;
|
||||||
}
|
}
|
||||||
|
|
@ -204,7 +215,8 @@ int Machine::getWord(int address)
|
||||||
cerr << prefix << "Invalid memory address: " << address << endl;
|
cerr << prefix << "Invalid memory address: " << address << endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return static_cast<int>(memory[address]) | (static_cast<int>(memory[address + 1]) << 8) | (static_cast<int>(memory[address + 2]) << 16);
|
// Big-endian: high byte first
|
||||||
|
return (static_cast<int>(memory[address]) << 16) | (static_cast<int>(memory[address + 1]) << 8) | static_cast<int>(memory[address + 2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assuming word is 3 bytes
|
// Assuming word is 3 bytes
|
||||||
|
|
@ -216,9 +228,10 @@ void Machine::setWord(int address, int value)
|
||||||
}
|
}
|
||||||
value &= 0xFFFFFF;
|
value &= 0xFFFFFF;
|
||||||
|
|
||||||
memory[address] = static_cast<unsigned char>(value & 0xFF);
|
// Big-endian: high byte first
|
||||||
|
memory[address] = static_cast<unsigned char>((value >> 16) & 0xFF);
|
||||||
memory[address + 1] = static_cast<unsigned char>((value >> 8) & 0xFF);
|
memory[address + 1] = static_cast<unsigned char>((value >> 8) & 0xFF);
|
||||||
memory[address + 2] = static_cast<unsigned char>((value >> 16) & 0xFF);
|
memory[address + 2] = static_cast<unsigned char>(value & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
double Machine::getFloat(int address)
|
double Machine::getFloat(int address)
|
||||||
|
|
@ -228,14 +241,14 @@ double Machine::getFloat(int address)
|
||||||
return 0.0;
|
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 raw =
|
||||||
(unsigned long long)memory[address] |
|
((unsigned long long)memory[address] << 40) |
|
||||||
((unsigned long long)memory[address+1] << 8) |
|
((unsigned long long)memory[address+1] << 32) |
|
||||||
((unsigned long long)memory[address+2] << 16) |
|
((unsigned long long)memory[address+2] << 24) |
|
||||||
((unsigned long long)memory[address+3] << 24) |
|
((unsigned long long)memory[address+3] << 16) |
|
||||||
((unsigned long long)memory[address+4] << 32) |
|
((unsigned long long)memory[address+4] << 8) |
|
||||||
((unsigned long long)memory[address+5] << 40);
|
(unsigned long long)memory[address+5];
|
||||||
|
|
||||||
int sign = (raw >> 47) & 0x1;
|
int sign = (raw >> 47) & 0x1;
|
||||||
int exponent = (raw >> 40) & 0x7F;
|
int exponent = (raw >> 40) & 0x7F;
|
||||||
|
|
@ -290,13 +303,13 @@ void Machine::setFloat(int address, double value)
|
||||||
((unsigned long long)exp_field << 40) |
|
((unsigned long long)exp_field << 40) |
|
||||||
frac;
|
frac;
|
||||||
|
|
||||||
// store 6 bytes little-endian
|
// store 6 bytes big-endian
|
||||||
memory[address] = (unsigned char)( raw & 0xFF);
|
memory[address] = (unsigned char)((raw >> 40) & 0xFF);
|
||||||
memory[address+1] = (unsigned char)((raw >> 8) & 0xFF);
|
memory[address+1] = (unsigned char)((raw >> 32) & 0xFF);
|
||||||
memory[address+2] = (unsigned char)((raw >> 16) & 0xFF);
|
memory[address+2] = (unsigned char)((raw >> 24) & 0xFF);
|
||||||
memory[address+3] = (unsigned char)((raw >> 24) & 0xFF);
|
memory[address+3] = (unsigned char)((raw >> 16) & 0xFF);
|
||||||
memory[address+4] = (unsigned char)((raw >> 32) & 0xFF);
|
memory[address+4] = (unsigned char)((raw >> 8) & 0xFF);
|
||||||
memory[address+5] = (unsigned char)((raw >> 40) & 0xFF);
|
memory[address+5] = (unsigned char)( raw & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -353,6 +366,7 @@ int Machine::fetch()
|
||||||
|
|
||||||
void Machine::execute() {
|
void Machine::execute() {
|
||||||
if (_stopped) return;
|
if (_stopped) return;
|
||||||
|
|
||||||
int b1 = fetch();
|
int b1 = fetch();
|
||||||
|
|
||||||
InstructionInfo &info = _instructionsTable[b1];
|
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
|
// PC-relative, signed 12-bit
|
||||||
if (ea_part & 0x800) // bit 11 set?
|
if (ea_part & 0x800) // bit 11 set?
|
||||||
ea_part |= 0xFFFFF000; // sign-extend
|
ea_part |= 0xFFFFF000; // sign-extend
|
||||||
base = getPC();
|
base = getPC();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// format 4 (e=1): b/p ignored, ea_part is 20-bit absolute
|
// format 4 (e=1): b/p ignored, ea_part is 20-bit absolute
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue