execf34s restructuring

This commit is contained in:
aljazbrodar. 2025-12-06 16:37:07 +01:00
parent b105f4cc6a
commit 4c6c4b8a22
2 changed files with 218 additions and 160 deletions

View file

@ -170,15 +170,15 @@ bool Machine::execF2(int opcode, int operand) {
bool Machine::execSICF3F4(int opcode, int ni, int operand) {
int x_val = 0;
int operand2 = fetch();
int UA;
int UV;
int temp;
int UA = 0;
int UV = 0;
int temp = 0;
bool ready = false;
int offset = 0;
if (((operand >> 7) & 0x1) == 1) { //preverimo ali je indeksno naslavljanje
x_val = getX();
}
if (ni == 0) { // stari SIC (neposredno in enostavno naslavljanje)
if (((operand >> 7) & 0x1) == 1) { //preverimo ali je indeksno naslavljanje
x_val = getX();
}
UA = (((operand & 0x7F) << 8) | operand2) + x_val; //izracun uporabnega naslova: operand brez bita x + drugi del naslova + x_val
if (UA + 2 > MAX_ADDRESS) {
@ -187,156 +187,214 @@ bool Machine::execSICF3F4(int opcode, int ni, int operand) {
}
UV = (memory[UA] << 16) | (memory[UA + 1] << 8) | memory[UA + 2]; //izracunamo operand oz. uporabno vrednost
switch (opcode) {
case Opcode::ADD:
setA(getA() + UV);
return true;
case Opcode::AND:
setA(getA() & UV);
return true;
case Opcode::COMP:
temp = getA();
if (temp < UV) {
setSW(0x40);
} else if (temp == UV) {
setSW(0x0);
} else {
setSW(0x80);
}
return true;
break;
case Opcode::DIV:
if (UV == 0) {
cerr << "Error: Divison by zero." << endl;
return false;
}
setA(getA() / UV);
return true;
case Opcode::J:
setPC(UV);
return true;
case Opcode::JEQ:
if (getSW() == 0x00) {
setPC(UV);
}
return true;
case Opcode::JGT:
if (getSW() == 0x80) {
setPC(UV);
}
return true;
case Opcode::JLT:
if (getSW() == 0x40) {
setPC(UV);
}
return true;
case Opcode::JSUB:
setL(getPC());
setPC(UV);
return true;
case Opcode::LDA:
setA(UV);
return true;
case Opcode::LDB:
setB(UV);
return true;
case Opcode::LDCH:
setA((getA() & 0xFFFF00) | (UV & 0xFF));
return true;
case Opcode::LDL:
setL(UV);
return true;
case Opcode::LDS:
setS(UV);
return true;
case Opcode::LDT:
setT(UV);
return true;
case Opcode::LDX:
setX(UV);
return true;
case Opcode::MUL:
setA(getA() * UV);
return true;
case Opcode::OR:
setA(getA() | UV);
return true;
case Opcode::RD:
temp = UV & 0xFF;
if (devices[temp] != nullptr) {
setA(devices[temp]->read());
}
return true;
case Opcode::RSUB:
setPC(getL());
return true;
case Opcode::STA:
temp = getA();
memory[UV] = (temp >> 16) & 0xFF;
memory[UV + 1] = (temp >> 8) & 0xFF;
memory[UV + 2] = temp & 0xFF;
return true;
case Opcode::STCH:
temp = getA();
memory[UV] = temp & 0xFF;
return true;
case Opcode::STL:
temp = getL();
memory[UV] = (temp >> 16) & 0xFF;
memory[UV + 1] = (temp >> 8) & 0xFF;
memory[UV + 2] = temp & 0xFF;
return true;
case Opcode::STSW:
temp = getSW();
memory[UV] = (temp >> 16) & 0xFF;
memory[UV + 1] = (temp >> 8) & 0xFF;
memory[UV + 2] = temp & 0xFF;
return true;
case Opcode::STX:
temp = getX();
memory[UV] = (temp >> 16) & 0xFF;
memory[UV + 1] = (temp >> 8) & 0xFF;
memory[UV + 2] = temp & 0xFF;
return true;
case Opcode::SUB:
setA(getA() - UV);
return true;
case Opcode::TD:
temp = UV & 0xFF;
} else if (((operand >> 4) & 0x1) == 0) { // ce e bit ni prizgan e je F3, sicer F4
bool b = ((operand >> 6) & 0x1) == 1; //preverimo bit za bazno naslavljanje
bool p = ((operand >> 5) & 0x1) == 1;
offset = (((operand & 0x0F) << 8) | operand2);
if (offset & 0x800) { // če je bit 11 = 1 (negativno)
offset |= 0xFFFFF000; // nastavi vse višje bite na 1 (sign extend)
}
offset += x_val;
if (!b && p) { //PC - relativno
UA = getPC() + offset;
} else if (b && !p) {
UA = getB() + offset;
} else if (!b && !p) { //neposredno
UA = (((operand & 0x0F) << 8) | operand2);
} else { // b && p je nedovoljeno!
invalidAddressing();
}
ready = false;
if (devices[temp] != nullptr) {
ready = devices[temp]->test();
}
if (ready) {
setSW(0X40);
} else {
setSW(0x00);
}
if (UA + 2 > MAX_ADDRESS) {
invalidAddressing();
return false;
}
return true;
case Opcode::TIX:
temp = getX();
setX(temp + 1);
if (temp < UV) setSW(0x40);
else if (temp == UV) setSW(0x00);
else setSW(0x80);
return true;
case Opcode::WD:
temp = UV & 0xFF;
if (devices[temp] != nullptr) {
devices[temp]->write(getA() & 0xFF);
}
return true;
default:
notImplemented(opcode);
break;
if (ni == 2) { //posredno
int UV_temp = (memory[UA] << 16) | (memory[UA + 1] << 8) | memory[UA + 2];
UV = (memory[UV_temp] << 16) | (memory[UV_temp + 1] << 8) | memory[UV_temp + 2];
} else if (ni == 1) { //takojšnje
UV = UA;
} else if (ni == 3) { //enostavno
UV = (memory[UA] << 16) | (memory[UA + 1] << 8) | memory[UA + 2]; //izracunamo operand oz. uporabno vrednost
}
} else {
int operand3 = fetch();
bool b = ((operand >> 6) & 0x1) == 1; //preverimo bit za bazno naslavljanje
bool p = ((operand >> 5) & 0x1) == 1;
offset = (((operand & 0x0F) << 16) | (operand2 << 8) | operand3);
if (offset & 0x80000) { // če je bit 11 = 1 (negativno)
offset |= 0xFFF00000; // nastavi vse višje bite na 1 (sign extend)
}
offset += x_val;
if (!b && p) { //PC - relativno
UA = getPC() + offset;
} else if (b && !p) {
UA = getB() + offset;
} else if (!b && !p) { //neposredno
UA = (((operand & 0x0F) << 16) | (operand2 << 8) | operand3);
} else { // b && p je nedovoljeno!
invalidAddressing();
}
} else if (((operand >> 4) & 0x1) == 0) { // ce e bit ni prizgan e je F3, sicer F4
if (UA + 2 > MAX_ADDRESS) {
invalidAddressing();
return false;
}
} else {
if (ni == 2) { //posredno
int UV_temp = (memory[UA] << 16) | (memory[UA + 1] << 8) | memory[UA + 2];
UV = (memory[UV_temp] << 16) | (memory[UV_temp + 1] << 8) | memory[UV_temp + 2];
} else if (ni == 1) { //takojšnje
UV = UA;
} else if (ni == 3) { //enostavno
UV = (memory[UA] << 16) | (memory[UA + 1] << 8) | memory[UA + 2]; //izracunamo operand oz. uporabno vrednost
}
}
switch (opcode) {
case Opcode::ADD:
setA(getA() + UV);
return true;
case Opcode::AND:
setA(getA() & UV);
return true;
case Opcode::COMP:
temp = getA();
if (temp < UV) {
setSW(0x40);
} else if (temp == UV) {
setSW(0x0);
} else {
setSW(0x80);
}
return true;
break;
case Opcode::DIV:
if (UV == 0) {
cerr << "Error: Divison by zero." << endl;
return false;
}
setA(getA() / UV);
return true;
case Opcode::J:
setPC(UV);
return true;
case Opcode::JEQ:
if (getSW() == 0x00) {
setPC(UV);
}
return true;
case Opcode::JGT:
if (getSW() == 0x80) {
setPC(UV);
}
return true;
case Opcode::JLT:
if (getSW() == 0x40) {
setPC(UV);
}
return true;
case Opcode::JSUB:
setL(getPC());
setPC(UV);
return true;
case Opcode::LDA:
setA(UV);
return true;
case Opcode::LDB:
setB(UV);
return true;
case Opcode::LDCH:
setA((getA() & 0xFFFF00) | (UV & 0xFF));
return true;
case Opcode::LDL:
setL(UV);
return true;
case Opcode::LDS:
setS(UV);
return true;
case Opcode::LDT:
setT(UV);
return true;
case Opcode::LDX:
setX(UV);
return true;
case Opcode::MUL:
setA(getA() * UV);
return true;
case Opcode::OR:
setA(getA() | UV);
return true;
case Opcode::RD:
temp = UV & 0xFF;
if (devices[temp] != nullptr) {
setA(devices[temp]->read());
}
return true;
case Opcode::RSUB:
setPC(getL());
return true;
case Opcode::STA:
temp = getA();
memory[UV] = (temp >> 16) & 0xFF;
memory[UV + 1] = (temp >> 8) & 0xFF;
memory[UV + 2] = temp & 0xFF;
return true;
case Opcode::STCH:
temp = getA();
memory[UV] = temp & 0xFF;
return true;
case Opcode::STL:
temp = getL();
memory[UV] = (temp >> 16) & 0xFF;
memory[UV + 1] = (temp >> 8) & 0xFF;
memory[UV + 2] = temp & 0xFF;
return true;
case Opcode::STSW:
temp = getSW();
memory[UV] = (temp >> 16) & 0xFF;
memory[UV + 1] = (temp >> 8) & 0xFF;
memory[UV + 2] = temp & 0xFF;
return true;
case Opcode::STX:
temp = getX();
memory[UV] = (temp >> 16) & 0xFF;
memory[UV + 1] = (temp >> 8) & 0xFF;
memory[UV + 2] = temp & 0xFF;
return true;
case Opcode::SUB:
setA(getA() - UV);
return true;
case Opcode::TD:
temp = UV & 0xFF;
ready = false;
if (devices[temp] != nullptr) {
ready = devices[temp]->test();
}
if (ready) {
setSW(0X40);
} else {
setSW(0x00);
}
return true;
case Opcode::TIX:
temp = getX();
setX(temp + 1);
if (temp < UV) setSW(0x40);
else if (temp == UV) setSW(0x00);
else setSW(0x80);
return true;
case Opcode::WD:
temp = UV & 0xFF;
if (devices[temp] != nullptr) {
devices[temp]->write(getA() & 0xFF);
}
return true;
default:
notImplemented(opcode);
break;
}
return false;
}