diff --git a/arduino/Console.cpp b/arduino/Console.cpp index 2477629..dea0b24 100644 --- a/arduino/Console.cpp +++ b/arduino/Console.cpp @@ -39,15 +39,45 @@ void Console::setSerial(HardwareSerial *serial) { this->serial = serial; } -void Console::printRegisters(bool header) { - if (header) { - serial->println(" 0 1 2 3 4 5 6 7 8 9 A B C D E F"); +void Console::printRegisters(uint8_t padding) { + if (padding < 3) { + 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(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("\n"); @@ -122,9 +152,9 @@ void Console::loop() { vm_step(this->vm); } else { serial->print("VM Halted. PC=0x"); - serial->print(this->vm->PC); + serial->print(this->vm->PC, HEX); serial->println(". Registers:"); - this->printRegisters(true); + this->printRegisters(0); this->state = CONSOLE_ACTIVATE; } break; @@ -135,9 +165,9 @@ void Console::loop() { serial->print("VM Halted. "); } serial->print("PC=0x"); - serial->print(this->vm->PC); + serial->print(this->vm->PC, HEX); serial->println(". Registers:"); - this->printRegisters(true); + this->printRegisters(0); } this->state = CONSOLE_ACTIVATE; break; @@ -223,16 +253,24 @@ void Console::stateActive() { }//Console::stateActive void Console::stateView() { - int i; //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("\n"); //Registers - serial->print( "R "); - this->printRegisters(false); + this->printRegisters(5); + serial->print("\n"); //Memory this->printMemory(0, 0xFF); @@ -243,7 +281,7 @@ void Console::stateView() { void Console::stateExamine() { char d; - int location, value; + uint16_t location, value; if(serial->available()) { while((d = (char)serial->read()) != -1) { if (d == 27) { @@ -279,7 +317,7 @@ void Console::stateExamine() { serial->println("Invalid value"); } } else if (this->inputBuffer->equals("R")) { - this->printRegisters(true); + this->printRegisters(0); } else if (this->inputBuffer->startsWith("R") && this->inputBuffer->indexOf("=") != -1) { location = this->hexToDec(this->inputBuffer->substring(1, this->inputBuffer->indexOf("="))); value = this->hexToDec(this->inputBuffer->substring(this->inputBuffer->indexOf("=")+1)); @@ -313,7 +351,7 @@ void Console::stateExamine() { if (x.length() % 2 != 0) { serial->println("Invalid data. 2 characters per byte required"); } 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)); if (value >= 0 && value <= 255) { this->vm->writeAddr(location++, value); @@ -328,7 +366,6 @@ void Console::stateExamine() { } } else { serial->println("Unknown command."); - serial->print("E> "); } if (this->state == CONSOLE_EXAMINE) { serial->print("E> "); diff --git a/arduino/Console.h b/arduino/Console.h index c88adaa..3e35573 100644 --- a/arduino/Console.h +++ b/arduino/Console.h @@ -41,7 +41,7 @@ class Console { HardwareSerial *serial; int hexToDec(String); - void printRegisters(bool); + void printRegisters(uint8_t); void printMemory(uint16_t, uint16_t); void stateActive(); diff --git a/arduino/VM.c b/arduino/VM.c index 1d05b82..7ce32d6 100644 --- a/arduino/VM.c +++ b/arduino/VM.c @@ -48,6 +48,27 @@ inline uint8_t vm_get_r(VM *vm, uint8_t r) { 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) { if (r < VM_REG_SIZE) { 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) { VM_Instruction inst; - memset(&inst, 0, sizeof(VM_Instruction)); - uint8_t PC = vm->PC; + uint16_t PC = vm->PC; if (PC % 2 != 0) { if (vm->error != NULL) { vm->error(VM_ERR_MISALIGN); @@ -106,18 +126,15 @@ void vm_step(VM *vm) { return; } - uint8_t x = 0; - uint8_t y = 0; - uint8_t d = 0; - uint16_t temp16 = 0; + uint8_t rx = 0, ry = 0, rd = 0; + uint16_t rdx = 0, rxx = 0, temp16 = 0; switch (inst.op) { case OP_LDA: vm_decode_T(&inst, raw); - x = vm_get_r(vm, inst.rx); - temp16 = x; - temp16 += inst.imm; - if (temp16 < VM_MEM_SIZE) { - d = vm->readAddr(temp16, false); + rxx = vm_get_rx(vm, inst.rx); + rxx += inst.imm; + if (rxx < VM_MEM_SIZE) { + rd = vm->readAddr(rxx, false); } else { if (vm->error != NULL) { vm->error(VM_ERR_OUT_OF_BOUNDS); @@ -127,11 +144,11 @@ void vm_step(VM *vm) { break; case OP_STA: vm_decode_T(&inst, raw); - x = vm_get_r(vm, inst.rx); - temp16 = vm_get_r(vm, inst.rd); - temp16 += inst.imm; - if (temp16 < VM_MEM_SIZE) { - vm->writeAddr(temp16, x); + rx = vm_get_r(vm, inst.rx); + rdx = vm_get_rx(vm, inst.rd); + rdx += inst.imm; + if (rdx < VM_MEM_SIZE) { + vm->writeAddr(rdx, rx); } else { if (vm->error != NULL) { vm->error(VM_ERR_OUT_OF_BOUNDS); @@ -141,83 +158,83 @@ void vm_step(VM *vm) { break; case OP_LDI: vm_decode_Q(&inst, raw); - d = inst.imm; + rd = inst.imm; break; case OP_ADD: vm_decode_S(&inst, raw); vm->carry = 0; - x = vm_get_r(vm, inst.rx); - y = vm_get_r(vm, inst.ry); - d = x + y; + rx = vm_get_r(vm, inst.rx); + ry = vm_get_r(vm, inst.ry); + rd = rx + ry; break; case OP_ADC: vm_decode_S(&inst, raw); - x = vm_get_r(vm, inst.rx); - y = vm_get_r(vm, inst.ry); - temp16 = x + y + vm->carry; + rx = vm_get_r(vm, inst.rx); + ry = vm_get_r(vm, inst.ry); + temp16 = rx + ry + vm->carry; vm->carry = (uint8_t) (temp16 >> 8); - d = (uint8_t) temp16; + rd = (uint8_t) temp16; break; case OP_SUB: vm_decode_S(&inst, raw); vm->carry = 0; - x = vm_get_r(vm, inst.rx); - y = vm_get_r(vm, inst.ry); - d = x - y; + rx = vm_get_r(vm, inst.rx); + ry = vm_get_r(vm, inst.ry); + rd = rx - ry; break; case OP_SBC: vm_decode_S(&inst, raw); - x = vm_get_r(vm, inst.rx); - y = vm_get_r(vm, inst.ry); - d = vm_subtract(x, y, &vm->carry); + rx = vm_get_r(vm, inst.rx); + ry = vm_get_r(vm, inst.ry); + rd = vm_subtract(rx, ry, &vm->carry); break; case OP_NOT: vm_decode_T(&inst, raw); - d = ~x; + rd = ~rx; break; case OP_AND: vm_decode_S(&inst, raw); - x = vm_get_r(vm, inst.rx); - y = vm_get_r(vm, inst.ry); - d = x & y; + rx = vm_get_r(vm, inst.rx); + ry = vm_get_r(vm, inst.ry); + rd = rx & ry; break; case OP_SHL: vm_decode_T(&inst, raw); - x = vm_get_r(vm, inst.rx); - d = x << vm_get_r(vm, inst.imm); + rx = vm_get_r(vm, inst.rx); + rd = rx << vm_get_r(vm, inst.imm); break; case OP_SHR: vm_decode_T(&inst, raw); - x = vm_get_r(vm, inst.rx); - d = x >> vm_get_r(vm, inst.imm); + rx = vm_get_r(vm, inst.rx); + rd = rx >> vm_get_r(vm, inst.imm); break; case OP_SYS: vm_decode_T(&inst, raw); - x = vm_get_r(vm, inst.rx); + rx = vm_get_r(vm, inst.rx); if (vm->syscall != NULL) { - d = vm->syscall(vm, x, inst.imm); + rd = vm->syscall(vm, rx, inst.imm); } else { - d = 0; + rd = 0; } break; case OP_JMP: vm_decode_Q(&inst, raw); - vm->PC = vm_get_r(vm, inst.rd); + vm->PC = vm_get_rx(vm, inst.rd); break; case OP_JEQ: vm_decode_S(&inst, raw); - x = vm_get_r(vm, inst.rx); - y = vm_get_r(vm, inst.ry); - if (x == y) { - vm->PC = vm_get_r(vm, inst.rd); + rx = vm_get_r(vm, inst.rx); + ry = vm_get_r(vm, inst.ry); + if (rx == ry) { + vm->PC = vm_get_rx(vm, inst.rd); } break; case OP_JLT: vm_decode_S(&inst, raw); - x = vm_get_r(vm, inst.rx); - y = vm_get_r(vm, inst.ry); - if (x < y) { - vm->PC = vm_get_r(vm, inst.rd); + rx = vm_get_r(vm, inst.rx); + ry = vm_get_r(vm, inst.ry); + if (rx < ry) { + vm->PC = vm_get_rx(vm, inst.rd); } break; case OP_HLT: @@ -230,5 +247,5 @@ void vm_step(VM *vm) { vm->halted = true; break; } - vm_put_r(vm, inst.rd, d); + vm_put_r(vm, inst.rd, rd); } diff --git a/arduino/VM.h b/arduino/VM.h index 98d8590..fa10b22 100644 --- a/arduino/VM.h +++ b/arduino/VM.h @@ -59,7 +59,7 @@ typedef struct VM_Instruction_t VM_Instruction; struct VM_t { uint8_t R[VM_REG_SIZE]; - uint8_t PC; + uint16_t PC; uint8_t carry; bool halted; 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); +uint16_t vm_get_rx(VM *vm, uint8_t r); + void vm_put_r(VM *vm, uint8_t r, uint8_t v); void vm_decode_Q(VM_Instruction *inst, uint16_t raw);