summaryrefslogtreecommitdiff
path: root/sux.c
diff options
context:
space:
mode:
Diffstat (limited to 'sux.c')
-rw-r--r--sux.c284
1 files changed, 217 insertions, 67 deletions
diff --git a/sux.c b/sux.c
index de32a14..0c84a9a 100644
--- a/sux.c
+++ b/sux.c
@@ -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;
}