#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. */ int alu(uint8_t opcode, uint64_t value) { uint64_t sum; uint8_t carry = 0, vf = 0; switch(opcode) { /* Add with carry. */ case ADC: sum = a+value+carry; vf = (~(a^value) & (a^sum & 0x80)); carry = (sum < value) ? 1 : 0; 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; 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; } ps |= vf; ps |= carry; 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: pulladdr(); break; } } }