summaryrefslogtreecommitdiff
path: root/sux.c
diff options
context:
space:
mode:
Diffstat (limited to 'sux.c')
-rw-r--r--sux.c84
1 files changed, 79 insertions, 5 deletions
diff --git a/sux.c b/sux.c
index 4e64277..43699d3 100644
--- a/sux.c
+++ b/sux.c
@@ -1,4 +1,3 @@
-#include <limits.h>
#include "opcode.h"
#include <stdint.h>
uint64_t a; /* Accumulator. */
@@ -19,13 +18,88 @@ uint64_t alu(uint8_t opcode, uint64_t value) {
break;
/* Subtract with carry. */
case SBC:
- sum = a-value-!carry
+ sum = a-value-!carry;
vf = (a^value) & (a^sum) & 0x80;
carry = (sum > value) ? 1 : 0;
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;
+ break;
+ /* Divide with accumulator. */
+ case DIV:
+ sum = a/value-!carry;
+ vf = (a^value) & (a^sum) & 0x80;
+ carry = (sum > value) ? 1 : 0;
+ a |= sum;
+ break;
+ /* Bitwise AND. */
+ case AND:
+ case AAY:
+ case AAX:
+ a &= value;
+ if (opcode == AAY)
+ y &= value;
+ if (opcode == AAX)
+ x &= value;
+ break;
+ case ANY:
+ y &= value;
+ break;
+ case ANX:
+ x &= value;
+ break;
+ /* Bitwise OR. */
+ case ORA:
+ case OAY:
+ case OAX:
+ a |= value;
+ if (opcode == OAY)
+ y |= value;
+ if (opcode == OAX)
+ x |= value;
+ break;
+ case ORY:
+ y |= value;
+ break;
+ case ORX:
+ x |= value;
+ break;
+ /* Bitwise Exclusive OR. */
+ case XOR:
+ case XAY:
+ case XAX:
+ a ^= value;
+ if (opcode == XAY)
+ y ^= value;
+ if (opcode == XAX)
+ x ^= value;
+ break;
+ case XRY:
+ y ^= value;
+ break;
+ case XRX:
+ x ^= value;
+ break;
+ /* Shift accumulator left. */
+ case SLA:
+ a <<= value;
+ break;
+ /* Shift accumulator right. */
+ case SRA:
+ a >>= value;
+ break;
+ /* Rotate accumulator left. */
+ case ROL:
+ (a << value) | (a >> (64-value));
+ break;
+ /* Rotate accumulator right. */
+ case ROR:
+ (a >> value) | (a << (64-value));
+ break;
}
}