diff options
Diffstat (limited to 'sux.c')
-rw-r--r-- | sux.c | 77 |
1 files changed, 53 insertions, 24 deletions
@@ -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) { + +} |