#include "opcode.h" #include uint64_t a; /* Accumulator. */ uint64_t y; /* Y index. */ uint64_t x; /* X index. */ 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 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: 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: 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: 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; v = ((a^value) & 0x8000000000000000) && ((a^sum) & 0x8000000000000000); 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: sum = (value < 64) ? a << value : 0; c = (sum < a << value && value >= 64); a = sum; break; /* Shift accumulator right. */ case SRA: sum = (value < 64) ? a << value : 0; c = (sum < a >> value && value >= 64); a = sum; break; /* Rotate accumulator left. */ case ROL: a = rol(a, value); break; /* Rotate accumulator right. */ case ROR: a = ror(a, value); 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); return 1; } int threads(uint8_t opcode, uint64_t value) { uint8_t t = value & 0xFF; /* This tells the CPU, which threads to start, or end. */ switch(opcode) { /* Start Thread. */ case STT: crt |= t; for (uint8_t i = 0; i < 8; i++) if ((t >> i) & 1) pc[i] = value >> 8; break; /* End Thread. */ case ENT: crt &= ~t; for (uint8_t i = 0; i < 8; i++) if ((t >> i) & 1) pc[i] = 0; break; } } 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; } } } int memory(uint8_t opcode, uint64_t value) { }