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;
|
||||
|
||||
private:
|
||||
void ensureFileOpen();
|
||||
std::fstream fileStream;
|
||||
std::string filename;
|
||||
bool fileCreated;
|
||||
};
|
||||
|
||||
#endif // FILE_DEVICE_H
|
||||
|
|
@ -3,21 +3,9 @@
|
|||
#include <fstream>
|
||||
|
||||
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<char*>(&value), sizeof(value));
|
||||
char ch;
|
||||
if (fileStream.get(ch)) {
|
||||
value = static_cast<unsigned char>(ch);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void FileDevice::write(unsigned char value)
|
||||
{
|
||||
ensureFileOpen();
|
||||
if (fileStream.is_open()) {
|
||||
fileStream.write(reinterpret_cast<const char*>(&value), sizeof(value));
|
||||
fileStream.put(static_cast<char>(value));
|
||||
fileStream.flush();
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,19 @@ Machine::Machine()
|
|||
devices[0] = make_shared<InputDevice>(std::cin);
|
||||
// device 1: standard output
|
||||
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;
|
||||
_instructionsTable = instructions;
|
||||
}
|
||||
|
|
@ -204,7 +215,8 @@ int Machine::getWord(int address)
|
|||
cerr << prefix << "Invalid memory address: " << address << endl;
|
||||
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
|
||||
|
|
@ -216,9 +228,10 @@ void Machine::setWord(int address, int value)
|
|||
}
|
||||
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 + 2] = static_cast<unsigned char>((value >> 16) & 0xFF);
|
||||
memory[address + 2] = static_cast<unsigned char>(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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue