Implemented extended registers AX-FX.

This commit is contained in:
2018-10-28 09:53:45 +00:00
parent 2b851f222f
commit e89b07d69f
4 changed files with 127 additions and 71 deletions

View File

@@ -39,15 +39,45 @@ void Console::setSerial(HardwareSerial *serial) {
this->serial = serial; this->serial = serial;
} }
void Console::printRegisters(bool header) { void Console::printRegisters(uint8_t padding) {
if (header) { if (padding < 3) {
serial->println(" 0 1 2 3 4 5 6 7 8 9 A B C D E F"); padding = 3;
} }
for(short i = 0; i < VM_REG_SIZE; i++) {
if (this->vm->R[i] < 0x10) { serial->print('R');
for(uint8_t x = 1; x < padding; x++) serial->print(' ');
serial->println(" 0 1 2 3 4 5 6 7 8 9 A B C D E F");
for(uint8_t x = 0; x < padding; x++) serial->print(' ');
for(uint8_t i = 0; i < 16; i++) {
uint8_t r = vm_get_r(vm, i);
if (r < 0x10) {
serial->print("0"); serial->print("0");
} }
serial->print(this->vm->R[i], HEX); serial->print(r, HEX);
serial->print(" ");
}
serial->print("\n");
serial->print("RX");
for(uint8_t x = 2; x < padding; x++) serial->print(' ');
serial->println(" AX BX CX DX EX FX");
serial->print( " ");
for(uint8_t x = 0; x < padding; x++) serial->print(' ');
for(uint8_t i = 0xA; i <= 0xF; i++) {
uint16_t rx = vm_get_rx(vm, i);
uint8_t rxh = (rx & 0xFF00) >> 8,
rxl = rx & 0xFF;
if (rxh < 0x10) {
serial->print("0");
}
serial->print(rxh, HEX);
if (rxl < 0x10) {
serial->print("0");
}
serial->print(rxl, HEX);
serial->print(" "); serial->print(" ");
} }
serial->print("\n"); serial->print("\n");
@@ -122,9 +152,9 @@ void Console::loop() {
vm_step(this->vm); vm_step(this->vm);
} else { } else {
serial->print("VM Halted. PC=0x"); serial->print("VM Halted. PC=0x");
serial->print(this->vm->PC); serial->print(this->vm->PC, HEX);
serial->println(". Registers:"); serial->println(". Registers:");
this->printRegisters(true); this->printRegisters(0);
this->state = CONSOLE_ACTIVATE; this->state = CONSOLE_ACTIVATE;
} }
break; break;
@@ -135,9 +165,9 @@ void Console::loop() {
serial->print("VM Halted. "); serial->print("VM Halted. ");
} }
serial->print("PC=0x"); serial->print("PC=0x");
serial->print(this->vm->PC); serial->print(this->vm->PC, HEX);
serial->println(". Registers:"); serial->println(". Registers:");
this->printRegisters(true); this->printRegisters(0);
} }
this->state = CONSOLE_ACTIVATE; this->state = CONSOLE_ACTIVATE;
break; break;
@@ -223,16 +253,24 @@ void Console::stateActive() {
}//Console::stateActive }//Console::stateActive
void Console::stateView() { void Console::stateView() {
int i;
//PC //PC
serial->print( "PC "); serial->print("PC ");
if (this->vm->PC < 0x1000) {
serial->print("0");
}
if (this->vm->PC < 0x100) {
serial->print("0");
}
if (this->vm->PC < 0x10) {
serial->print("0");
}
serial->print(this->vm->PC, HEX); serial->print(this->vm->PC, HEX);
serial->print("\n"); serial->print("\n");
//Registers //Registers
serial->print( "R "); this->printRegisters(5);
this->printRegisters(false); serial->print("\n");
//Memory //Memory
this->printMemory(0, 0xFF); this->printMemory(0, 0xFF);
@@ -243,7 +281,7 @@ void Console::stateView() {
void Console::stateExamine() { void Console::stateExamine() {
char d; char d;
int location, value; uint16_t location, value;
if(serial->available()) { if(serial->available()) {
while((d = (char)serial->read()) != -1) { while((d = (char)serial->read()) != -1) {
if (d == 27) { if (d == 27) {
@@ -279,7 +317,7 @@ void Console::stateExamine() {
serial->println("Invalid value"); serial->println("Invalid value");
} }
} else if (this->inputBuffer->equals("R")) { } else if (this->inputBuffer->equals("R")) {
this->printRegisters(true); this->printRegisters(0);
} else if (this->inputBuffer->startsWith("R") && this->inputBuffer->indexOf("=") != -1) { } else if (this->inputBuffer->startsWith("R") && this->inputBuffer->indexOf("=") != -1) {
location = this->hexToDec(this->inputBuffer->substring(1, this->inputBuffer->indexOf("="))); location = this->hexToDec(this->inputBuffer->substring(1, this->inputBuffer->indexOf("=")));
value = this->hexToDec(this->inputBuffer->substring(this->inputBuffer->indexOf("=")+1)); value = this->hexToDec(this->inputBuffer->substring(this->inputBuffer->indexOf("=")+1));
@@ -313,7 +351,7 @@ void Console::stateExamine() {
if (x.length() % 2 != 0) { if (x.length() % 2 != 0) {
serial->println("Invalid data. 2 characters per byte required"); serial->println("Invalid data. 2 characters per byte required");
} else { } else {
for(int i = 0; i < x.length(); i += 2) { for(unsigned int i = 0; i < x.length(); i += 2) {
value = this->hexToDec(x.substring(i, i+2)); value = this->hexToDec(x.substring(i, i+2));
if (value >= 0 && value <= 255) { if (value >= 0 && value <= 255) {
this->vm->writeAddr(location++, value); this->vm->writeAddr(location++, value);
@@ -328,7 +366,6 @@ void Console::stateExamine() {
} }
} else { } else {
serial->println("Unknown command."); serial->println("Unknown command.");
serial->print("E> ");
} }
if (this->state == CONSOLE_EXAMINE) { if (this->state == CONSOLE_EXAMINE) {
serial->print("E> "); serial->print("E> ");

View File

@@ -41,7 +41,7 @@ class Console {
HardwareSerial *serial; HardwareSerial *serial;
int hexToDec(String); int hexToDec(String);
void printRegisters(bool); void printRegisters(uint8_t);
void printMemory(uint16_t, uint16_t); void printMemory(uint16_t, uint16_t);
void stateActive(); void stateActive();

View File

@@ -48,6 +48,27 @@ inline uint8_t vm_get_r(VM *vm, uint8_t r) {
return 0; return 0;
} }
inline uint16_t vm_get_rx(VM *vm, uint8_t r) {
if (r < 0xA) {
return vm_get_r(vm, r);
}
switch(r) {
case 0xA:
return (vm->R[4]<<8) + vm->R[5];
case 0xB:
return (vm->R[6]<<8) + vm->R[7];
case 0xC:
return (vm->R[8]<<8) + vm->R[9];
case 0xD:
return (vm->R[10]<<8) + vm->R[11];
case 0xE:
return (vm->R[12]<<8) + vm->R[13];
case 0xF:
return (vm->R[14]<<8) + vm->R[15];
}
return 0;
}
inline void vm_put_r(VM *vm, uint8_t r, uint8_t v) { inline void vm_put_r(VM *vm, uint8_t r, uint8_t v) {
if (r < VM_REG_SIZE) { if (r < VM_REG_SIZE) {
vm->R[r] = v; vm->R[r] = v;
@@ -88,9 +109,8 @@ inline uint8_t vm_subtract(uint8_t x, uint8_t y, uint8_t *ptr_borrow) {
void vm_step(VM *vm) { void vm_step(VM *vm) {
VM_Instruction inst; VM_Instruction inst;
memset(&inst, 0, sizeof(VM_Instruction));
uint8_t PC = vm->PC; uint16_t PC = vm->PC;
if (PC % 2 != 0) { if (PC % 2 != 0) {
if (vm->error != NULL) { if (vm->error != NULL) {
vm->error(VM_ERR_MISALIGN); vm->error(VM_ERR_MISALIGN);
@@ -106,18 +126,15 @@ void vm_step(VM *vm) {
return; return;
} }
uint8_t x = 0; uint8_t rx = 0, ry = 0, rd = 0;
uint8_t y = 0; uint16_t rdx = 0, rxx = 0, temp16 = 0;
uint8_t d = 0;
uint16_t temp16 = 0;
switch (inst.op) { switch (inst.op) {
case OP_LDA: case OP_LDA:
vm_decode_T(&inst, raw); vm_decode_T(&inst, raw);
x = vm_get_r(vm, inst.rx); rxx = vm_get_rx(vm, inst.rx);
temp16 = x; rxx += inst.imm;
temp16 += inst.imm; if (rxx < VM_MEM_SIZE) {
if (temp16 < VM_MEM_SIZE) { rd = vm->readAddr(rxx, false);
d = vm->readAddr(temp16, false);
} else { } else {
if (vm->error != NULL) { if (vm->error != NULL) {
vm->error(VM_ERR_OUT_OF_BOUNDS); vm->error(VM_ERR_OUT_OF_BOUNDS);
@@ -127,11 +144,11 @@ void vm_step(VM *vm) {
break; break;
case OP_STA: case OP_STA:
vm_decode_T(&inst, raw); vm_decode_T(&inst, raw);
x = vm_get_r(vm, inst.rx); rx = vm_get_r(vm, inst.rx);
temp16 = vm_get_r(vm, inst.rd); rdx = vm_get_rx(vm, inst.rd);
temp16 += inst.imm; rdx += inst.imm;
if (temp16 < VM_MEM_SIZE) { if (rdx < VM_MEM_SIZE) {
vm->writeAddr(temp16, x); vm->writeAddr(rdx, rx);
} else { } else {
if (vm->error != NULL) { if (vm->error != NULL) {
vm->error(VM_ERR_OUT_OF_BOUNDS); vm->error(VM_ERR_OUT_OF_BOUNDS);
@@ -141,83 +158,83 @@ void vm_step(VM *vm) {
break; break;
case OP_LDI: case OP_LDI:
vm_decode_Q(&inst, raw); vm_decode_Q(&inst, raw);
d = inst.imm; rd = inst.imm;
break; break;
case OP_ADD: case OP_ADD:
vm_decode_S(&inst, raw); vm_decode_S(&inst, raw);
vm->carry = 0; vm->carry = 0;
x = vm_get_r(vm, inst.rx); rx = vm_get_r(vm, inst.rx);
y = vm_get_r(vm, inst.ry); ry = vm_get_r(vm, inst.ry);
d = x + y; rd = rx + ry;
break; break;
case OP_ADC: case OP_ADC:
vm_decode_S(&inst, raw); vm_decode_S(&inst, raw);
x = vm_get_r(vm, inst.rx); rx = vm_get_r(vm, inst.rx);
y = vm_get_r(vm, inst.ry); ry = vm_get_r(vm, inst.ry);
temp16 = x + y + vm->carry; temp16 = rx + ry + vm->carry;
vm->carry = (uint8_t) (temp16 >> 8); vm->carry = (uint8_t) (temp16 >> 8);
d = (uint8_t) temp16; rd = (uint8_t) temp16;
break; break;
case OP_SUB: case OP_SUB:
vm_decode_S(&inst, raw); vm_decode_S(&inst, raw);
vm->carry = 0; vm->carry = 0;
x = vm_get_r(vm, inst.rx); rx = vm_get_r(vm, inst.rx);
y = vm_get_r(vm, inst.ry); ry = vm_get_r(vm, inst.ry);
d = x - y; rd = rx - ry;
break; break;
case OP_SBC: case OP_SBC:
vm_decode_S(&inst, raw); vm_decode_S(&inst, raw);
x = vm_get_r(vm, inst.rx); rx = vm_get_r(vm, inst.rx);
y = vm_get_r(vm, inst.ry); ry = vm_get_r(vm, inst.ry);
d = vm_subtract(x, y, &vm->carry); rd = vm_subtract(rx, ry, &vm->carry);
break; break;
case OP_NOT: case OP_NOT:
vm_decode_T(&inst, raw); vm_decode_T(&inst, raw);
d = ~x; rd = ~rx;
break; break;
case OP_AND: case OP_AND:
vm_decode_S(&inst, raw); vm_decode_S(&inst, raw);
x = vm_get_r(vm, inst.rx); rx = vm_get_r(vm, inst.rx);
y = vm_get_r(vm, inst.ry); ry = vm_get_r(vm, inst.ry);
d = x & y; rd = rx & ry;
break; break;
case OP_SHL: case OP_SHL:
vm_decode_T(&inst, raw); vm_decode_T(&inst, raw);
x = vm_get_r(vm, inst.rx); rx = vm_get_r(vm, inst.rx);
d = x << vm_get_r(vm, inst.imm); rd = rx << vm_get_r(vm, inst.imm);
break; break;
case OP_SHR: case OP_SHR:
vm_decode_T(&inst, raw); vm_decode_T(&inst, raw);
x = vm_get_r(vm, inst.rx); rx = vm_get_r(vm, inst.rx);
d = x >> vm_get_r(vm, inst.imm); rd = rx >> vm_get_r(vm, inst.imm);
break; break;
case OP_SYS: case OP_SYS:
vm_decode_T(&inst, raw); vm_decode_T(&inst, raw);
x = vm_get_r(vm, inst.rx); rx = vm_get_r(vm, inst.rx);
if (vm->syscall != NULL) { if (vm->syscall != NULL) {
d = vm->syscall(vm, x, inst.imm); rd = vm->syscall(vm, rx, inst.imm);
} else { } else {
d = 0; rd = 0;
} }
break; break;
case OP_JMP: case OP_JMP:
vm_decode_Q(&inst, raw); vm_decode_Q(&inst, raw);
vm->PC = vm_get_r(vm, inst.rd); vm->PC = vm_get_rx(vm, inst.rd);
break; break;
case OP_JEQ: case OP_JEQ:
vm_decode_S(&inst, raw); vm_decode_S(&inst, raw);
x = vm_get_r(vm, inst.rx); rx = vm_get_r(vm, inst.rx);
y = vm_get_r(vm, inst.ry); ry = vm_get_r(vm, inst.ry);
if (x == y) { if (rx == ry) {
vm->PC = vm_get_r(vm, inst.rd); vm->PC = vm_get_rx(vm, inst.rd);
} }
break; break;
case OP_JLT: case OP_JLT:
vm_decode_S(&inst, raw); vm_decode_S(&inst, raw);
x = vm_get_r(vm, inst.rx); rx = vm_get_r(vm, inst.rx);
y = vm_get_r(vm, inst.ry); ry = vm_get_r(vm, inst.ry);
if (x < y) { if (rx < ry) {
vm->PC = vm_get_r(vm, inst.rd); vm->PC = vm_get_rx(vm, inst.rd);
} }
break; break;
case OP_HLT: case OP_HLT:
@@ -230,5 +247,5 @@ void vm_step(VM *vm) {
vm->halted = true; vm->halted = true;
break; break;
} }
vm_put_r(vm, inst.rd, d); vm_put_r(vm, inst.rd, rd);
} }

View File

@@ -59,7 +59,7 @@ typedef struct VM_Instruction_t VM_Instruction;
struct VM_t { struct VM_t {
uint8_t R[VM_REG_SIZE]; uint8_t R[VM_REG_SIZE];
uint8_t PC; uint16_t PC;
uint8_t carry; uint8_t carry;
bool halted; bool halted;
uint8_t (*readAddr)(uint16_t addr, bool instruction); uint8_t (*readAddr)(uint16_t addr, bool instruction);
@@ -79,6 +79,8 @@ void vm_clear(VM *vm);
uint8_t vm_get_r(VM *vm, uint8_t r); uint8_t vm_get_r(VM *vm, uint8_t r);
uint16_t vm_get_rx(VM *vm, uint8_t r);
void vm_put_r(VM *vm, uint8_t r, uint8_t v); void vm_put_r(VM *vm, uint8_t r, uint8_t v);
void vm_decode_Q(VM_Instruction *inst, uint16_t raw); void vm_decode_Q(VM_Instruction *inst, uint16_t raw);