diff options
Diffstat (limited to 'sux.c')
-rw-r--r-- | sux.c | 284 |
1 files changed, 217 insertions, 67 deletions
@@ -1,8 +1,11 @@ #include "opcode.h" #include <stdint.h> -uint64_t a; /* Accumulator. */ -uint64_t y; /* Y index. */ -uint64_t x; /* X index. */ +#define STK_STADDR 0x010000 /* Starting address of the stack. */ +uint8_t *addr; /* Address Space. */ +uint16_t sp; /* Stack pointer. */ +uint64_t a[8]; /* Accumulator. */ +uint64_t y[8]; /* Y index. */ +uint64_t x[8]; /* X index. */ uint8_t crt; /* Current Running Threads. */ uint64_t pc[8]; /* Program counter. */ uint64_t ps; /* Processor status. */ @@ -19,7 +22,24 @@ uint64_t ror(uint64_t a, uint64_t value) { return (a >> value) | (a << (-value & mask)); } -int alu(uint8_t opcode, uint64_t value) { +int push(uint64_t value, uint8_t size) { + for (uint8_t i = 0; i < size; i++) { + addr[STK_STADDR+sp] = value >> 8*i; + sp--; + } + return 1; +} + +uint64_t pull(uint8_t size) { + uint64_t value; + for (uint8_t i = 0; i < size; i++) { + value = addr[STK_STADDR+sp] << 8*i; + sp++; + } + return value; +} + +int alu(uint8_t opcode, uint64_t value, uint8_t thread) { uint64_t sum; uint8_t c = 0; /* Carry flag. */ uint8_t v = 0; /* Overflow flag. */ @@ -28,109 +48,155 @@ int alu(uint8_t opcode, uint64_t value) { switch(opcode) { /* Add with carry. */ case ADC: - c = ps & 1; - sum = a+value+c; - v = !((a^value) & 0x8000000000000000) && ((a^sum) & 0x8000000000000000); + c = (ps & (1 << thread)) >> thread; + sum = a[thread]+value+c; + v = !((a[thread]^value) & 0x8000000000000000) && ((a[thread]^sum) & 0x8000000000000000); c = (sum < value); - a = sum; + a[thread] = sum; break; /* Subtract with carry. */ case SBC: - c = !(ps & 1); - sum = a-value-c; - v = ((a^value) & 0x8000000000000000) && ((a^sum) & 0x8000000000000000); + c = !(ps & (1 << thread)); + sum = a[thread]-value-c; + v = ((a[thread]^value) & 0x8000000000000000) && ((a[thread]^sum) & 0x8000000000000000); c = (sum > value); - a = sum; + a[thread] = sum; break; /* Multiply with accumulator. */ case MUL: - c = ps & 1; - sum = a*value+c; - v = !((a^value) & 0x8000000000000000) && ((a^sum) & 0x8000000000000000); - c = (!((a^sum) && (a^value)) || (a >= ((uint64_t)1 << 32) && value >= ((uint64_t)1 << 32))); - a = sum; + c = (ps & (1 << thread)) >> thread; + sum = a[thread]*value+c; + v = !((a[thread]^value) & 0x8000000000000000) && ((a[thread]^sum) & 0x8000000000000000); + c = (!((a[thread]^sum) && (a[thread]^value)) || (a[thread] >= ((uint64_t)1 << 32) && value >= ((uint64_t)1 << 32))); + a[thread] = sum; break; /* Divide with accumulator. */ case DIV: - sum = a/value; - v = ((a^value) & 0x8000000000000000) && ((a^sum) & 0x8000000000000000); - a = sum; + sum = a[thread]/value; + v = ((a[thread]^value) & 0x8000000000000000) && ((a[thread]^sum) & 0x8000000000000000); + a[thread] = sum; break; /* Bitwise AND. */ case AND: case AAY: case AAX: - a &= value; + a[thread] &= value; if (opcode == AAY) - y &= value; + y[thread] &= value; if (opcode == AAX) - x &= value; + x[thread] &= value; break; case ANY: - y &= value; + y[thread] &= value; break; case ANX: - x &= value; + x[thread] &= value; break; /* Bitwise OR. */ case ORA: case OAY: case OAX: - a |= value; + a[thread] |= value; if (opcode == OAY) - y |= value; + y[thread] |= value; if (opcode == OAX) - x |= value; + x[thread] |= value; break; case ORY: - y |= value; + y[thread] |= value; break; case ORX: - x |= value; + x[thread] |= value; break; /* Bitwise Exclusive OR. */ case XOR: case XAY: case XAX: - a ^= value; + a[thread] ^= value; if (opcode == XAY) - y ^= value; + y[thread] ^= value; if (opcode == XAX) - x ^= value; + x[thread] ^= value; break; case XRY: - y ^= value; + y[thread] ^= value; break; case XRX: - x ^= value; + x[thread] ^= value; break; /* Shift accumulator left. */ case SLA: - sum = (value < 64) ? a << value : 0; - c = (sum < a << value && value >= 64); - a = sum; + c = (ps & (1 << thread)) >> thread; + if (value > 1) + c = ((a << value-1) & 0x8000000000000000) >> 63; + sum = (value < 64) ? a[thread] << value : 0; + a[thread] = sum; break; /* Shift accumulator right. */ case SRA: + c = (ps & (1 << thread)) >> thread; + if (value > 1) + c = (a >> value-1) & 1; sum = (value < 64) ? a << value : 0; - c = (sum < a >> value && value >= 64); - a = sum; + c = sum & 1; + a[thread] = sum; break; /* Rotate accumulator left. */ case ROL: - a = rol(a, value); + a[thread] = rol(a[thread], value); break; /* Rotate accumulator right. */ case ROR: - a = ror(a, value); + a[thread] = ror(a[thread], value); + break; + /* Increment accumulator. */ + case INC: + case IAY: + case IAX: + a[thread]++; + if (opcode == IAY) + y[thread]++; + if[opcode == IAX] + x[thread]++; + break; + /* Increment y register. */ + case INY: + y[thread]++; + break; + /* Increment x register. */ + case INX: + x[thread]++; + break; + /* Decrement accumulator. */ + case DEC: + case DAY: + case DAX: + a[thread]--; + if (opcode == DAY) + y[thread]--; + if[opcode == DAX] + x[thread]--; + break; + /* Decrement y register. */ + case DEY: + y[thread]--; + break; + /* Decrement y register. */ + case DEX: + x[thread]--; + break; + default: + printf("Cool, you inputed a non existent opcode, which means\n" + "that you have now wasted clock cycles.\n" + "Good job! *clap*\n"); break; } - z = (a == 0); - n = (a >> 63); - ps = (n) ? (ps | 1 << 7) : (ps & 1 << 7); - ps = (v) ? (ps | 1 << 6) : (ps & 1 << 6); - ps = (z) ? (ps | 1 << 1) : (ps & 1 << 1); - ps = (c) ? (ps | 1 << 0) : (ps & 1 << 0); + z = (a[thread] == 0); + n = (a[thread] >> 63); + ps = (n) ? (ps | 1 << 7+thread) : (ps & ~(1 << 7+thread)); + ps = (v) ? (ps | 1 << 6+thread) : (ps & ~(1 << 6+thread)); + ps = (z) ? (ps | 1 << 1+thread) : (ps & ~(1 << 1+thread)); + ps = (c) ? (ps | 1 << thread) : (ps & ~(1 << thread)); return 1; } @@ -140,39 +206,123 @@ int threads(uint8_t opcode, uint64_t value) { /* Start Thread. */ case STT: crt |= t; - for (uint8_t i = 0; i < 8; i++) + for (uint8_t i = 0; i < 7; i++) if ((t >> i) & 1) pc[i] = value >> 8; break; /* End Thread. */ case ENT: crt &= ~t; - for (uint8_t i = 0; i < 8; i++) + for (uint8_t i = 0; i < 7; i++) if ((t >> i) & 1) pc[i] = 0; break; } + return 1; } int branch(uint8_t opcode, uint64_t value, uint8_t thread) { - switch (opcode) { - /* Jump. */ - case JMP: - pc[thread] = value; - break; - /* Jump to subroutine. */ - case JSR: - pc[thread] = value; - pushaddr(value); - break; - /* Return from subroutine. */ - case RTS: - pc[thread] = pulladdr(); - break; - } + switch (opcode) { + /* Jump. */ + case JMP: + pc[thread] = value; + break; + /* Jump to subroutine. */ + case JSR: + push(pc[thread], 8); + pc[thread] = value; + break; + /* Return from subroutine. */ + case RTS: + pc[thread] = pull(8); + break; } + return 1; } -int memory(uint8_t opcode, uint64_t value) { - +int memory(uint8_t opcode, uint64_t value, uint8_t thread) { + switch (opcode) { + /* Load value. */ + case LDA: /* LDA, imm */ + case LDY: /* LDY, imm */ + case LAY: /* LAY, imm */ + case LDX: /* LDX, imm */ + case LAX: /* LAX, imm */ + case 0x95: /* LDA, abs */ + case 0x25: /* LDY, abs */ + case 0x35: /* LAY, abs */ + case 0x45: /* LDX, abs */ + case 0x55: /* LAX, abs */ + if (opcode == LDA || opcode == LAY || opcode == LAX) + a[thread] = value; + else if (opcode == 0x95 || opcode == 0x35 || opcode == 0x55) + a[thread] = addr[value]; + if (opcode == LAY || opcode == LDY) + y[thread] = value; + else if (opcode == 0x35) + y[thread] = addr[value]; + if (opcode == LAX) + x[thread] = value; + else if (opcode == 0x55) + x[thread] = addr[value]; + /* Store value. */ + case STA: + case SAY: + case SAX: + addr[value] = a[thread]; + if (opcode == SAY) + addr[value] = y[thread]; + if (opcode == SAX) + addr[value] = x[thread]; + break; + case STY: + addr[value] = y[thread]; + break; + case STX: + addr[value] = x[thread]; + break; + /* Push processor status. */ + case PHP: + push(ps, value); + break; + /* Push accumulator. */ + case PHA: + case PAY: + case PAX: + push(a, value); + if (opcode == PAY) + push(y, value); + if (opcode == PAX) + push(x, value); + break; + case PHY: + push(y, value); + break; + case PHX: + push(x, value); + break; + /* Pull processor status. */ + case PLP: + ps = pull(value); + break; + /* Pull accumulator. */ + case PLA: + case PYA: + case PXA: + a = pull(value); + if (opcode == PAY) + y = pull(value); + if (opcode == PAX) + x = pull(value); + break; + /* Pull y register. */ + case PLY: + y = pull(value); + break; + /* Pull x register. */ + case PLX: + x = pull(value); + break; + } + return 1; } |