summaryrefslogtreecommitdiff
path: root/sux.c
diff options
context:
space:
mode:
Diffstat (limited to 'sux.c')
-rw-r--r--sux.c77
1 files changed, 53 insertions, 24 deletions
diff --git a/sux.c b/sux.c
index 1efbc77..de32a14 100644
--- a/sux.c
+++ b/sux.c
@@ -7,37 +7,54 @@ uint8_t crt; /* Current Running Threads. */
uint64_t pc[8]; /* Program counter. */
uint64_t ps; /* Processor status. */
+uint64_t rol(uint64_t a, uint64_t value) {
+ const uint64_t mask = 8 * sizeof(a) - 1;
+ value &= mask;
+ return (a << value) | (a >> (-value & mask));
+}
+
+uint64_t ror(uint64_t a, uint64_t value) {
+ const uint64_t mask = 8 * sizeof(a) - 1;
+ value &= mask;
+ return (a >> value) | (a << (-value & mask));
+}
+
int alu(uint8_t opcode, uint64_t value) {
uint64_t sum;
- uint8_t carry = 0, vf = 0;
+ uint8_t c = 0; /* Carry flag. */
+ uint8_t v = 0; /* Overflow flag. */
+ uint8_t z = 0; /* Zero flag. */
+ uint8_t n = 0; /* Negative flag. */
switch(opcode) {
/* Add with carry. */
case ADC:
- sum = a+value+carry;
- vf = (~(a^value) & (a^sum & 0x80));
- carry = (sum < value) ? 1 : 0;
- a |= sum;
+ c = ps & 1;
+ sum = a+value+c;
+ v = !((a^value) & 0x8000000000000000) && ((a^sum) & 0x8000000000000000);
+ c = (sum < value);
+ a = sum;
break;
/* Subtract with carry. */
case SBC:
- sum = a-value-!carry;
- vf = (a^value) & (a^sum) & 0x80;
- carry = (sum > value) ? 1 : 0;
- a |= sum;
+ c = !(ps & 1);
+ sum = a-value-c;
+ v = ((a^value) & 0x8000000000000000) && ((a^sum) & 0x8000000000000000);
+ c = (sum > value);
+ a = sum;
break;
/* Multiply with accumulator. */
case MUL:
- sum = a*value+carry;
- vf = (~(a^value) & (a^sum & 0x80));
- carry = (sum < value) ? 1 : 0;
- a |= sum;
+ 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;
break;
/* Divide with accumulator. */
case DIV:
- sum = a/value-!carry;
- vf = (a^value) & (a^sum) & 0x80;
- carry = (sum > value) ? 1 : 0;
- a |= sum;
+ sum = a/value;
+ v = ((a^value) & 0x8000000000000000) && ((a^sum) & 0x8000000000000000);
+ a = sum;
break;
/* Bitwise AND. */
case AND:
@@ -89,23 +106,31 @@ int alu(uint8_t opcode, uint64_t value) {
break;
/* Shift accumulator left. */
case SLA:
- a <<= value;
+ sum = (value < 64) ? a << value : 0;
+ c = (sum < a << value && value >= 64);
+ a = sum;
break;
/* Shift accumulator right. */
case SRA:
- a >>= value;
+ sum = (value < 64) ? a << value : 0;
+ c = (sum < a >> value && value >= 64);
+ a = sum;
break;
/* Rotate accumulator left. */
case ROL:
- (a << value) | (a >> (64-value));
+ a = rol(a, value);
break;
/* Rotate accumulator right. */
case ROR:
- (a >> value) | (a << (64-value));
+ a = ror(a, value);
break;
}
- ps |= vf;
- ps |= carry;
+ 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);
return 1;
}
@@ -142,8 +167,12 @@ int branch(uint8_t opcode, uint64_t value, uint8_t thread) {
break;
/* Return from subroutine. */
case RTS:
- pulladdr();
+ pc[thread] = pulladdr();
break;
}
}
}
+
+int memory(uint8_t opcode, uint64_t value) {
+
+}