diff options
-rw-r--r-- | opcode.c | 14 | ||||
-rw-r--r-- | sux.c | 847 | ||||
-rw-r--r-- | test/test-the-tests.s | 5 |
3 files changed, 440 insertions, 426 deletions
@@ -230,24 +230,10 @@ void lsr(struct sux *cpu, uint64_t adr, uint8_t thread) { setps(cpu, thread); } -void inc(struct sux *cpu, uint64_t *reg, uint8_t thread) { - *reg += 1; - cpu->z[thread] = (*reg == 0); - cpu->n[thread] = (*reg >> 63); - setps(cpu, thread); -} - void inc_addr(struct sux *cpu, uint64_t adr, uint8_t thread) { addr[adr]++; } -void dec(struct sux *cpu, uint64_t *reg, uint8_t thread) { - *reg -= 1; - cpu->z[thread] = (*reg == 0); - cpu->n[thread] = (*reg >> 63); - setps(cpu, thread); -} - void dec_addr(struct sux *cpu, uint64_t adr, uint8_t thread) { addr[adr]--; } @@ -1,430 +1,458 @@ #include "opcode.h" #include <assert.h> +#include <string.h> #include <pthread.h> #define bench 0 #if bench #include <time.h> #endif -#define THREADS 0 -uint64_t inst; -uint8_t lines[THREADS+1]; -struct sux suxx; +#define THREADS 1 +uint64_t inst[THREADS]; +uint64_t inss; +uint8_t lines[THREADS]; +struct sux *cpu; #if bench double ipc; time_t str, en; #endif -int run(struct sux *cpu, uint8_t prefix, uint8_t opcode, uint8_t thread) { - uint64_t address; - uint8_t rs = (prefix & 0x30) >> 4; - uint8_t regsize = (1 << rs); - uint8_t tmp; - address = cpu->pc[thread]; - cpu->pc[thread]++; - clk++; - switch(opcode) { - case CPS: /* Clear Processor Status. */ - for (uint8_t i = 0; i < 8; i++) { - cpu->c[i] = 0; - cpu->z[i] = 0; - cpu->i[i] = 0; - cpu->s[i] = 0; - cpu->v[i] = 0; - cpu->n[i] = 0; - } - cpu->ps &= 0; - break; - case ADC: adc(cpu, immaddr(cpu, thread, regsize), thread, regsize); break; /* ADC Immediate. */ - case 0x03: adc(cpu, absaddr(cpu, thread), thread, regsize); break; /* ADC Absolute. */ - case 0x05: adc(cpu, zeromtx(cpu, thread), thread, regsize); break; /* ADC Zero Matrix. */ - case PHP: /* PusH Processor status to stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (int8_t i = 8*tmp; i > 0; i-=8) { - push(cpu, cpu->ps >> i); - } - push(cpu, cpu->ps & 0xFF); - break; - case PHA: /* PusH Accumulator to stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (int8_t i = 8*tmp; i > 0; i-=8) { - push(cpu, cpu->a[thread] >> i); - } - push(cpu, cpu->a[thread] & 0xFF); - break; - case PHY: /* PusH Y register to stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (int8_t i = 8*tmp; i > 0; i-=8) { - push(cpu, cpu->y[thread] >> i); - } - push(cpu, cpu->y[thread] & 0xFF); - break; - case PHX: /* PusH X register to stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (int8_t i = 8*tmp; i > 0; i-=8) { - push(cpu, cpu->x[thread] >> i); - } - push(cpu, cpu->x[thread] & 0xFF); - break; - case JMP: /* JMP Absolute. */ - address = absaddr(cpu, thread); - cpu->pc[thread] = address; - break; - case SBC: sbc(cpu, immaddr(cpu, thread, regsize), thread, regsize); break; /* SBC Immediate. */ - case 0x13: sbc(cpu, absaddr(cpu, thread), thread, regsize); break; /* SBC Absolute. */ - case 0x15: sbc(cpu, zeromtx(cpu, thread), thread, regsize); break; /* SBC Zero Matrix. */ - case PLP: /* PuLl Processor status from stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (uint8_t i = 0; i <= 8*tmp; i+=8) { - if (!i) - cpu->ps = (uint64_t)pull(cpu); - else - cpu->ps += (uint64_t)pull(cpu) << i; - } - break; - case PLA: /* PuLl Accumulator from stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (uint8_t i = 0; i <= 8*tmp; i+=8) { - if (!i) - cpu->a[thread] = (uint64_t)pull(cpu); - else - cpu->a[thread] += (uint64_t)pull(cpu) << i; - } - break; - case PLY: /* PuLl Y register from stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (uint8_t i = 0; i <= 8*tmp; i+=8) { - if (!i) - cpu->y[thread] = (uint64_t)pull(cpu); - else - cpu->y[thread] += (uint64_t)pull(cpu) << i; - } - break; - case PLX: /* PuLl X register from stack. */ - tmp = addr[cpu->pc[thread]++]; - if (tmp > 7) - tmp = 7; - for (uint8_t i = 0; i <= 8*tmp; i+=8) { - if (!i) - cpu->x[thread] = (uint64_t)pull(cpu); - else - cpu->x[thread] += (uint64_t)pull(cpu) << i; - } - break; - case JSR: /* Jump to SubRoutine. */ - address = (uint64_t)addr[cpu->pc[thread]] - | (uint64_t)addr[cpu->pc[thread]+1] << 8 - | (uint64_t)addr[cpu->pc[thread]+2] << 16 - | (uint64_t)addr[cpu->pc[thread]+3] << 24; - cpu->pc[thread]+=4; - push(cpu, (uint64_t)cpu->pc[thread] >> 24); - push(cpu, (uint64_t)cpu->pc[thread] >> 16); - push(cpu, (uint64_t)cpu->pc[thread] >> 8); - push(cpu, (uint64_t)cpu->pc[thread] & 0xFF); - cpu->pc[thread] = address; - break; - case AND: and_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* AND Immediate. */ - case ANY: and_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ANY Immediate. */ - case AAY: cpu->a[thread] = and(cpu, cpu->y[thread], thread); break; - case ANX: and_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ANX Immediate. */ - case AAX: cpu->a[thread] = and(cpu, cpu->x[thread], thread); break; - case STT: stt(cpu, immaddr(cpu, thread, 1)); break; /* STart Thread. */ - case 0x29: and_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* AND Absolute. */ - case 0x2B: and_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* AND Zero Matrix. */ - case BPO: bfc(cpu, cpu->n[thread], absaddr(cpu, thread), thread); break; /* Branch if POsitive. */ - case ORA: or_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ORA Immediate. */ - case ORY: or_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ORY Immediate. */ - case OAY: cpu->a[thread] = or(cpu, cpu->y[thread], thread); break; - case ORX: or_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ORX Immediate. */ - case OAX: cpu->a[thread] = or(cpu, cpu->x[thread], thread); break; - case SEI: /* SEt Interrupt. */ - cpu->i[thread] = 1; - setps(cpu, thread); - break; - case 0x39: or_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* ORA Absolute. */ - case 0x3B: or_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* ORA Zero Matrix. */ - case BNG: bfs(cpu, cpu->n[thread], absaddr(cpu, thread), thread); break; /* Branch if NeGative. */ - case XOR: xor_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* XOR Immediate. */ - case XRY: xor_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* XRY Immediate. */ - case XAY: cpu->a[thread] = xor(cpu, cpu->y[thread], thread); break; - case XRX: xor_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* XRX Immediate. */ - case XAX: cpu->a[thread] = xor(cpu, cpu->x[thread], thread); break; - case CLI: /* CLear Interrupt. */ - cpu->i[thread] = 0; - setps(cpu, thread); - break; - case 0x49: xor_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* XOR Absolute. */ - case 0x4B: xor_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* XOR Zero Matrix. */ - case BCS: bfs(cpu, cpu->c[thread], absaddr(cpu, thread), thread); break; /* Branch if Carry Set. */ - case LSL: lsl(cpu, immaddr(cpu, thread, 1), thread); break; /* LSL Immediate. */ - case 0x52: and_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* ANY Absolute. */ - case 0x53: lsl(cpu, absaddr(cpu, thread), thread); break; /* LSL Absolute. */ - case 0x54: and_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* ANX Absolute. */ - case 0x55: lsl(cpu, zeromtx(cpu, thread), thread); break; /* LSL Zero Matrix. */ - case SEC: /* SEt Carry flag.*/ - cpu->c[thread] = 1; - setps(cpu, thread); - break; - case 0x59: ld(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* LDA Absolute. */ - case 0x5A: ld(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* LDY Absolute. */ - case STA: st(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* STA Absolute. */ - case 0x5C: ld(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* LDX Absolute. */ - case STY: st(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* STY Absolute. */ - case STX: st(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* STX Absolute. */ - case BCC: bfc(cpu, cpu->c[thread], absaddr(cpu, thread), thread); break; /* Branch if Carry Clear. */ - case LSR: lsr(cpu, immaddr(cpu, thread, 1), thread); break; /* LSR Immediate. */ - case 0x62: or_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* ORY Absolute. */ - case 0x63: lsr(cpu, absaddr(cpu, thread), thread); break; /* LSR Absolute. */ - case 0x64: or_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* ORX Absolute. */ - case 0x65: lsr(cpu, zeromtx(cpu, thread), thread); break; /* LSR Zero Matrix. */ - case CLC: /* CLear Carry flag. */ - cpu->c[thread] = 0; - setps(cpu, thread); - break; - case LDA: ld(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* LDA Immediate. */ - case LDY: ld(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* LDY Immediate. */ - case LDX: ld(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* LDX Immediate. */ - case BEQ: bfs(cpu, cpu->z[thread], absaddr(cpu, thread), thread); break; /* Branch if EQual. */ - case ROL: rol(cpu, immaddr(cpu, thread, 1), thread); break; /* ROL Immediate. */ - case 0x72: xor_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* XRY Absolute. */ - case 0x73: rol(cpu, absaddr(cpu, thread), thread); break; /* ROL Absolute. */ - case 0x74: xor_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* XRX Absolute. */ - case 0x75: rol(cpu, zeromtx(cpu, thread), thread); break; /* ROL Zero Matrix. */ - case SSP: /* Set Stack Protection flag. */ - cpu->s[thread] = 1; - setps(cpu, thread); - break; - case 0x79: ld(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* LDA Zero Matrix. */ - case 0x7A: ld(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* LDY Zero Matrix. */ - case 0x7B: st(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* STA Zero Matrix. */ - case 0x7C: ld(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* LDX Zero Matrix. */ - case 0x7D: st(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* STY Zero Matrix. */ - case 0x7E: st(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* STX Zero Matrix. */ - case BNE: bfc(cpu, cpu->z[thread], absaddr(cpu, thread), thread); break; /* Branch if Not Equal. */ - case ROR: ror(cpu, immaddr(cpu, thread, 1), thread); break; /* ROR Immediate. */ - case 0x82: and_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* ANY Zero Matrix. */ - case 0x83: ror(cpu, absaddr(cpu, thread), thread); break; /* ROR Absolute. */ - case 0x84: and_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* ANX Zero Matrix. */ - case 0x85: ror(cpu, zeromtx(cpu, thread), thread); break; /* ROR Zero Matrix. */ - case CSP: /* Clear Stack Protection flag. */ - cpu->s[thread] = 0; - setps(cpu, thread); - break; - case 0x89: ld(cpu, &cpu->a[thread], zeromx(cpu, thread), thread, regsize); break; /* LDA Zero Matrix, Indexed with X. */ - case 0x8A: ld(cpu, &cpu->y[thread], zeromx(cpu, thread), thread, regsize); break; /* LDY Zero Matrix, Indexed with X. */ - case 0x8B: st(cpu, &cpu->a[thread], zeromx(cpu, thread), thread, regsize); break; /* STA Zero Matrix, Indexed with X. */ - case 0x8D: st(cpu, &cpu->y[thread], zeromx(cpu, thread), thread, regsize); break; /* STY Zero Matrix, Indexed with X. */ - case BVS: bfs(cpu, cpu->v[thread], absaddr(cpu, thread), thread); break; /* Branch if oVerflow Set. */ - case MUL: mul(cpu, immaddr(cpu, thread, regsize), thread, regsize); break; /* MUL Immediate. */ - case 0x92: or_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* ORY Zero Matrix. */ - case 0x93: mul(cpu, absaddr(cpu, thread), thread, regsize); break; /* MUL Absolute. */ - case 0x94: or_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* ORX Zero Matrix. */ - case 0x95: mul(cpu, zeromtx(cpu, thread), thread, regsize); break; /* MUL Zero Matrix. */ - case SEV: /* SEt oVerflow flag. */ - cpu->v[thread] = 1; - setps(cpu, thread); - break; - case 0x99: ld(cpu, &cpu->a[thread], zeromy(cpu, thread), thread, regsize); break; /* LDA Zero Matrix, Indexed with Y. */ - case 0x9B: ld(cpu, &cpu->x[thread], zeromy(cpu, thread), thread, regsize); break; /* STA Zero Matrix, Indexed with Y. */ - case 0x9C: st(cpu, &cpu->a[thread], zeromy(cpu, thread), thread, regsize); break; /* LDX Zero Matrix, Indexed with Y. */ - case 0x9E: st(cpu, &cpu->x[thread], zeromy(cpu, thread), thread, regsize); break; /* STX Zero Matrix, Indexed with Y. */ - case BVC: bfc(cpu, cpu->z[thread], absaddr(cpu, thread), thread); break; /* Branch if oVerflow Clear. */ - case DIV: divd(cpu, immaddr(cpu, thread, regsize), thread, regsize); break; /* DIV Immediate. */ - case 0xA2: xor_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* XRY Zero Matrix. */ - case 0xA3: divd(cpu, absaddr(cpu, thread), thread, regsize); break; /* DIV Absolute. */ - case 0xA4: xor_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* XRX Zero Matrix. */ - case 0xA5: divd(cpu, zeromtx(cpu, thread), thread, regsize); break; /* DIV Zero Matrix. */ - case CLV: /* CLear oVerflow flag. */ - cpu->v[thread] = 0; - setps(cpu, thread); - break; - case RTS: /* ReTurn from Subroutine. */ - cpu->pc[thread] = (uint64_t)pull(cpu); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 8); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 16); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 24) + 1; - break; - case CMP: cmp_addr(cpu, cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* CMP Immediate. */ - case CPY: cmp_addr(cpu, cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* CPY Immediate. */ - case CAY: cmp(cpu, cpu->a[thread], cpu->y[thread], thread); break; - case CPX: cmp_addr(cpu, cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* CPX Immediate. */ - case CAX: cmp(cpu, cpu->a[thread], cpu->x[thread], thread); break; - case ENT: ent(cpu, immaddr(cpu, thread, 1)); break; /* ENd Thread. */ - case RTI: /* ReTurn from Interupt routine. */ - cpu->ps = ((uint64_t)pull(cpu) << 8*thread); - cpu->pc[thread] = (uint64_t)pull(cpu); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 8); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 16); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 24); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 32); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 40); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 48); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 56); - break; - case INC: /* INC Accumulator. */ - inc(cpu, &cpu->a[thread], thread); - break; - case INY: inc(cpu, &cpu->y[thread], thread); break; - case IAY: inc(cpu, &cpu->a[thread], thread); inc(cpu, &cpu->y[thread], thread); break; - case INX: inc(cpu, &cpu->x[thread], thread); break; - case IAX: inc(cpu, &cpu->a[thread], thread); inc(cpu, &cpu->x[thread], thread); break; - case 0xD0: /* JMP Zero Matrix. */ - address = zeromtx(cpu, thread); - cpu->pc[thread] = address; - break; - case DEC: dec(cpu, &cpu->a[thread], thread); break; /* DEC Accumulator. */ - case DEY: dec(cpu, &cpu->y[thread], thread); break; - case DAY: dec(cpu, &cpu->a[thread], thread); dec(cpu, &cpu->y[thread], thread); break; - case DEX: dec(cpu, &cpu->x[thread], thread); break; - case DAX: dec(cpu, &cpu->a[thread], thread); dec(cpu, &cpu->x[thread], thread); break; - case JSL: /* Jump to Subroutine Long. */ - address = (uint64_t)addr[cpu->pc[thread]] - | (uint64_t)addr[cpu->pc[thread]+1] << 8 - | (uint64_t)addr[cpu->pc[thread]+2] << 16 - | (uint64_t)addr[cpu->pc[thread]+3] << 24 - | (uint64_t)addr[cpu->pc[thread]+4] << 32 - | (uint64_t)addr[cpu->pc[thread]+5] << 40 - | (uint64_t)addr[cpu->pc[thread]+6] << 48 - | (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; - push(cpu, (uint64_t)cpu->pc[thread] >> 56); - push(cpu, (uint64_t)cpu->pc[thread] >> 48); - push(cpu, (uint64_t)cpu->pc[thread] >> 40); - push(cpu, (uint64_t)cpu->pc[thread] >> 32); - push(cpu, (uint64_t)cpu->pc[thread] >> 24); - push(cpu, (uint64_t)cpu->pc[thread] >> 16); - push(cpu, (uint64_t)cpu->pc[thread] >> 8); - push(cpu, (uint64_t)cpu->pc[thread] & 0xFF); - cpu->pc[thread] = address; - break; - case 0xE1: inc_addr(cpu, absaddr(cpu, thread), thread); break; /* INC Absolute. */ - case 0xE2: cmp_addr(cpu, cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* CPY Absolute. */ - case 0xE3: inc_addr(cpu, zeromtx(cpu, thread), thread); break; /* INC Zero Matrix. */ - case 0xE4: cmp_addr(cpu, cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* CPX Absolute. */ - case 0xE5: cmp_addr(cpu, cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* CMP Absolute. */ - case NOP: break; /* No OPeration. */ - case RTL: /* ReTurn from subroutine Long. */ - cpu->pc[thread] = (uint64_t)pull(cpu); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 8); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 16); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 24); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 32); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 40); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 48); - cpu->pc[thread] += ((uint64_t)pull(cpu) << 56) + 1; - break; - case 0xF1: dec_addr(cpu, absaddr(cpu, thread), thread); break; /* DEC Absolute. */ - case 0xF2: cmp_addr(cpu, cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* CPY Zero Matrix. */ - case 0xF3: dec_addr(cpu, zeromtx(cpu, thread), thread); break; /* DEC Zero Matrix. */ - case 0xF4: cmp_addr(cpu, cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* CPX Zero Matrix. */ - case 0xF5: cmp_addr(cpu, cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* CMP Zero Matrix. */ - case BRK: /* BReaK. */ - push(cpu, (uint64_t)cpu->pc[thread]-1 >> 56); - push(cpu, (uint64_t)cpu->pc[thread]-1 >> 48); - push(cpu, (uint64_t)cpu->pc[thread]-1 >> 40); - push(cpu, (uint64_t)cpu->pc[thread]-1 >> 32); - push(cpu, (uint64_t)cpu->pc[thread]-1 >> 24); - push(cpu, (uint64_t)cpu->pc[thread]-1 >> 16); - push(cpu, (uint64_t)cpu->pc[thread]-1 >> 8); - push(cpu, (uint64_t)cpu->pc[thread]-1 & 0xFF); - push(cpu, (uint64_t)cpu->ps >> 8*thread); - cpu->i[thread] = 1; - setps(cpu, thread); - cpu->pc[thread] = (uint64_t)addr[0xFFE0] - | (uint64_t)addr[0xFFE1] << 8 - | (uint64_t)addr[0xFFE2] << 16 - | (uint64_t)addr[0xFFE3] << 24 - | (uint64_t)addr[0xFFE4] << 32 - | (uint64_t)addr[0xFFE5] << 40 - | (uint64_t)addr[0xFFE6] << 48 - | (uint64_t)addr[0xFFE7] << 56; - default: - if(opcode != BRK) { - printf("Cool, you inputed a non existent opcode, which means\n" - "that you have now wasted clock cycles.\n" - "Good job! *clap*\n"); - } - break; - } - return 1; -} - - -void *threads(void *args) { +void *run(void *args) { uint8_t thread = *((uint8_t *) args); + uint64_t address; uint8_t prefix = 0; uint8_t opcode = 0; - -#if bench uint8_t end = 0; while (!end) { -#endif - prefix = addr[suxx.pc[thread]]; + prefix = addr[cpu->pc[thread]]; - if ((prefix & 0x07) == 0x07) { - suxx.pc[thread]++; - } + if ((prefix & 0x07) == 0x07) + cpu->pc[thread]++; + else + prefix = 0; + opcode = addr[cpu->pc[thread]]; - opcode = addr[suxx.pc[thread]]; -#if !bench + #if !bench printf("\033[%uH\033[2K" "pc: 0x%08llx, a: 0x%016llx, x: 0x%016llx, y: 0x%016llx" ", sp: 0x%04lx, ps: 0x%016llx, opcode: 0x%02x, thread: %u, inst: %s\n" , lines[thread] - , suxx.pc[thread], suxx.a[thread], suxx.x[thread], suxx.y[thread] - , suxx.sp, suxx.ps, opcode, thread, opname[opcode]); + , cpu->pc[thread], cpu->a[thread], cpu->x[thread], cpu->y[thread] + , cpu->sp, cpu->ps, opcode, thread, opname[opcode]); fflush(stdout); lines[thread]++; if (lines[thread] > 6*(thread+1)) lines[thread] = (6*thread)+2; -#endif - if ((prefix & 0x07) == 0x07) - run(&suxx, prefix-7, opcode, thread); - else - run(&suxx, 0, opcode, thread); + #endif - inst++; -#if bench - if (inst >= 10000000) { + uint8_t rs = (prefix & 0x30) >> 4; + uint8_t regsize = (1 << rs); + uint8_t tmp; + address = cpu->pc[thread]; + cpu->pc[thread]++; + clk++; + switch(opcode) { + case CPS: /* Clear Processor Status. */ + for (uint8_t i = 0; i < 8; i++) { + cpu->c[i] = 0; + cpu->z[i] = 0; + cpu->i[i] = 0; + cpu->s[i] = 0; + cpu->v[i] = 0; + cpu->n[i] = 0; + } + cpu->ps &= 0; + break; + case ADC: adc(cpu, immaddr(cpu, thread, regsize), thread, regsize); break; /* ADC Immediate. */ + case 0x03: adc(cpu, absaddr(cpu, thread), thread, regsize); break; /* ADC Absolute. */ + case 0x05: adc(cpu, zeromtx(cpu, thread), thread, regsize); break; /* ADC Zero Matrix. */ + case PHP: /* PusH Processor status to stack. */ + tmp = addr[cpu->pc[thread]++]; + if (tmp > 7) + tmp = 7; + for (int8_t i = 8*tmp; i > 0; i-=8) { + push(cpu, cpu->ps >> i); + } + push(cpu, cpu->ps & 0xFF); + break; + case PHA: /* PusH Accumulator to stack. */ + tmp = addr[cpu->pc[thread]++]; + if (tmp > 7) + tmp = 7; + for (int8_t i = 8*tmp; i > 0; i-=8) { + push(cpu, cpu->a[thread] >> i); + } + push(cpu, cpu->a[thread] & 0xFF); + break; + case PHY: /* PusH Y register to stack. */ + tmp = addr[cpu->pc[thread]++]; + if (tmp > 7) + tmp = 7; + for (int8_t i = 8*tmp; i > 0; i-=8) { + push(cpu, cpu->y[thread] >> i); + } + push(cpu, cpu->y[thread] & 0xFF); + break; + case PHX: /* PusH X register to stack. */ + tmp = addr[cpu->pc[thread]++]; + if (tmp > 7) + tmp = 7; + for (int8_t i = 8*tmp; i > 0; i-=8) { + push(cpu, cpu->x[thread] >> i); + } + push(cpu, cpu->x[thread] & 0xFF); + break; + case JMP: /* JMP Absolute. */ + address = absaddr(cpu, thread); + cpu->pc[thread] = address; + break; + case SBC: sbc(cpu, immaddr(cpu, thread, regsize), thread, regsize); break; /* SBC Immediate. */ + case 0x13: sbc(cpu, absaddr(cpu, thread), thread, regsize); break; /* SBC Absolute. */ + case 0x15: sbc(cpu, zeromtx(cpu, thread), thread, regsize); break; /* SBC Zero Matrix. */ + case PLP: /* PuLl Processor status from stack. */ + tmp = addr[cpu->pc[thread]++]; + if (tmp > 7) + tmp = 7; + for (uint8_t i = 0; i <= 8*tmp; i+=8) { + if (!i) + cpu->ps = (uint64_t)pull(cpu); + else + cpu->ps += (uint64_t)pull(cpu) << i; + } + break; + case PLA: /* PuLl Accumulator from stack. */ + tmp = addr[cpu->pc[thread]++]; + if (tmp > 7) + tmp = 7; + for (uint8_t i = 0; i <= 8*tmp; i+=8) { + if (!i) + cpu->a[thread] = (uint64_t)pull(cpu); + else + cpu->a[thread] += (uint64_t)pull(cpu) << i; + } + break; + case PLY: /* PuLl Y register from stack. */ + tmp = addr[cpu->pc[thread]++]; + if (tmp > 7) + tmp = 7; + for (uint8_t i = 0; i <= 8*tmp; i+=8) { + if (!i) + cpu->y[thread] = (uint64_t)pull(cpu); + else + cpu->y[thread] += (uint64_t)pull(cpu) << i; + } + break; + case PLX: /* PuLl X register from stack. */ + tmp = addr[cpu->pc[thread]++]; + if (tmp > 7) + tmp = 7; + for (uint8_t i = 0; i <= 8*tmp; i+=8) { + if (!i) + cpu->x[thread] = (uint64_t)pull(cpu); + else + cpu->x[thread] += (uint64_t)pull(cpu) << i; + } + break; + case JSR: /* Jump to SubRoutine. */ + address = (uint64_t)addr[cpu->pc[thread]] + | (uint64_t)addr[cpu->pc[thread]+1] << 8 + | (uint64_t)addr[cpu->pc[thread]+2] << 16 + | (uint64_t)addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=4; + push(cpu, (uint64_t)cpu->pc[thread] >> 24); + push(cpu, (uint64_t)cpu->pc[thread] >> 16); + push(cpu, (uint64_t)cpu->pc[thread] >> 8); + push(cpu, (uint64_t)cpu->pc[thread] & 0xFF); + cpu->pc[thread] = address; + break; + case AND: and_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* AND Immediate. */ + case ANY: and_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ANY Immediate. */ + case AAY: cpu->a[thread] = and(cpu, cpu->y[thread], thread); break; + case ANX: and_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ANX Immediate. */ + case AAX: cpu->a[thread] = and(cpu, cpu->x[thread], thread); break; + case STT: stt(cpu, immaddr(cpu, thread, 1)); break; /* STart Thread. */ + case 0x29: and_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* AND Absolute. */ + case 0x2B: and_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* AND Zero Matrix. */ + case BPO: bfc(cpu, cpu->n[thread], absaddr(cpu, thread), thread); break; /* Branch if POsitive. */ + case ORA: or_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ORA Immediate. */ + case ORY: or_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ORY Immediate. */ + case OAY: cpu->a[thread] = or(cpu, cpu->y[thread], thread); break; + case ORX: or_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ORX Immediate. */ + case OAX: cpu->a[thread] = or(cpu, cpu->x[thread], thread); break; + case SEI: /* SEt Interrupt. */ + cpu->i[thread] = 1; + setps(cpu, thread); + break; + case 0x39: or_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* ORA Absolute. */ + case 0x3B: or_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* ORA Zero Matrix. */ + case BNG: bfs(cpu, cpu->n[thread], absaddr(cpu, thread), thread); break; /* Branch if NeGative. */ + case XOR: xor_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* XOR Immediate. */ + case XRY: xor_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* XRY Immediate. */ + case XAY: cpu->a[thread] = xor(cpu, cpu->y[thread], thread); break; + case XRX: xor_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* XRX Immediate. */ + case XAX: cpu->a[thread] = xor(cpu, cpu->x[thread], thread); break; + case CLI: /* CLear Interrupt. */ + cpu->i[thread] = 0; + setps(cpu, thread); + break; + case 0x49: xor_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* XOR Absolute. */ + case 0x4B: xor_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* XOR Zero Matrix. */ + case BCS: bfs(cpu, cpu->c[thread], absaddr(cpu, thread), thread); break; /* Branch if Carry Set. */ + case LSL: lsl(cpu, immaddr(cpu, thread, 1), thread); break; /* LSL Immediate. */ + case 0x52: and_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* ANY Absolute. */ + case 0x53: lsl(cpu, absaddr(cpu, thread), thread); break; /* LSL Absolute. */ + case 0x54: and_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* ANX Absolute. */ + case 0x55: lsl(cpu, zeromtx(cpu, thread), thread); break; /* LSL Zero Matrix. */ + case SEC: /* SEt Carry flag.*/ + cpu->c[thread] = 1; + setps(cpu, thread); + break; + case 0x59: ld(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* LDA Absolute. */ + case 0x5A: ld(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* LDY Absolute. */ + case STA: st(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* STA Absolute. */ + case 0x5C: ld(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* LDX Absolute. */ + case STY: st(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* STY Absolute. */ + case STX: st(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* STX Absolute. */ + case BCC: bfc(cpu, cpu->c[thread], absaddr(cpu, thread), thread); break; /* Branch if Carry Clear. */ + case LSR: lsr(cpu, immaddr(cpu, thread, 1), thread); break; /* LSR Immediate. */ + case 0x62: or_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* ORY Absolute. */ + case 0x63: lsr(cpu, absaddr(cpu, thread), thread); break; /* LSR Absolute. */ + case 0x64: or_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* ORX Absolute. */ + case 0x65: lsr(cpu, zeromtx(cpu, thread), thread); break; /* LSR Zero Matrix. */ + case CLC: /* CLear Carry flag. */ + cpu->c[thread] = 0; + setps(cpu, thread); + break; + case LDA: ld(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* LDA Immediate. */ + case LDY: ld(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* LDY Immediate. */ + case LDX: ld(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* LDX Immediate. */ + case BEQ: bfs(cpu, cpu->z[thread], absaddr(cpu, thread), thread); break; /* Branch if EQual. */ + case ROL: rol(cpu, immaddr(cpu, thread, 1), thread); break; /* ROL Immediate. */ + case 0x72: xor_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* XRY Absolute. */ + case 0x73: rol(cpu, absaddr(cpu, thread), thread); break; /* ROL Absolute. */ + case 0x74: xor_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* XRX Absolute. */ + case 0x75: rol(cpu, zeromtx(cpu, thread), thread); break; /* ROL Zero Matrix. */ + case SSP: /* Set Stack Protection flag. */ + cpu->s[thread] = 1; + setps(cpu, thread); + break; + case 0x79: ld(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* LDA Zero Matrix. */ + case 0x7A: ld(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* LDY Zero Matrix. */ + case 0x7B: st(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* STA Zero Matrix. */ + case 0x7C: ld(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* LDX Zero Matrix. */ + case 0x7D: st(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* STY Zero Matrix. */ + case 0x7E: st(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* STX Zero Matrix. */ + case BNE: bfc(cpu, cpu->z[thread], absaddr(cpu, thread), thread); break; /* Branch if Not Equal. */ + case ROR: ror(cpu, immaddr(cpu, thread, 1), thread); break; /* ROR Immediate. */ + case 0x82: and_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* ANY Zero Matrix. */ + case 0x83: ror(cpu, absaddr(cpu, thread), thread); break; /* ROR Absolute. */ + case 0x84: and_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* ANX Zero Matrix. */ + case 0x85: ror(cpu, zeromtx(cpu, thread), thread); break; /* ROR Zero Matrix. */ + case CSP: /* Clear Stack Protection flag. */ + cpu->s[thread] = 0; + setps(cpu, thread); + break; + case 0x89: ld(cpu, &cpu->a[thread], zeromx(cpu, thread), thread, regsize); break; /* LDA Zero Matrix, Indexed with X. */ + case 0x8A: ld(cpu, &cpu->y[thread], zeromx(cpu, thread), thread, regsize); break; /* LDY Zero Matrix, Indexed with X. */ + case 0x8B: st(cpu, &cpu->a[thread], zeromx(cpu, thread), thread, regsize); break; /* STA Zero Matrix, Indexed with X. */ + case 0x8D: st(cpu, &cpu->y[thread], zeromx(cpu, thread), thread, regsize); break; /* STY Zero Matrix, Indexed with X. */ + case BVS: bfs(cpu, cpu->v[thread], absaddr(cpu, thread), thread); break; /* Branch if oVerflow Set. */ + case MUL: mul(cpu, immaddr(cpu, thread, regsize), thread, regsize); break; /* MUL Immediate. */ + case 0x92: or_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* ORY Zero Matrix. */ + case 0x93: mul(cpu, absaddr(cpu, thread), thread, regsize); break; /* MUL Absolute. */ + case 0x94: or_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* ORX Zero Matrix. */ + case 0x95: mul(cpu, zeromtx(cpu, thread), thread, regsize); break; /* MUL Zero Matrix. */ + case SEV: /* SEt oVerflow flag. */ + cpu->v[thread] = 1; + setps(cpu, thread); + break; + case 0x99: ld(cpu, &cpu->a[thread], zeromy(cpu, thread), thread, regsize); break; /* LDA Zero Matrix, Indexed with Y. */ + case 0x9B: ld(cpu, &cpu->x[thread], zeromy(cpu, thread), thread, regsize); break; /* STA Zero Matrix, Indexed with Y. */ + case 0x9C: st(cpu, &cpu->a[thread], zeromy(cpu, thread), thread, regsize); break; /* LDX Zero Matrix, Indexed with Y. */ + case 0x9E: st(cpu, &cpu->x[thread], zeromy(cpu, thread), thread, regsize); break; /* STX Zero Matrix, Indexed with Y. */ + case BVC: bfc(cpu, cpu->z[thread], absaddr(cpu, thread), thread); break; /* Branch if oVerflow Clear. */ + case DIV: divd(cpu, immaddr(cpu, thread, regsize), thread, regsize); break; /* DIV Immediate. */ + case 0xA2: xor_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* XRY Zero Matrix. */ + case 0xA3: divd(cpu, absaddr(cpu, thread), thread, regsize); break; /* DIV Absolute. */ + case 0xA4: xor_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* XRX Zero Matrix. */ + case 0xA5: divd(cpu, zeromtx(cpu, thread), thread, regsize); break; /* DIV Zero Matrix. */ + case CLV: /* CLear oVerflow flag. */ + cpu->v[thread] = 0; + setps(cpu, thread); + break; + case RTS: /* ReTurn from Subroutine. */ + cpu->pc[thread] = (uint64_t)pull(cpu); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 8); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 16); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 24) + 1; + break; + case CMP: cmp_addr(cpu, cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* CMP Immediate. */ + case CPY: cmp_addr(cpu, cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* CPY Immediate. */ + case CAY: cmp(cpu, cpu->a[thread], cpu->y[thread], thread); break; + case CPX: cmp_addr(cpu, cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* CPX Immediate. */ + case CAX: cmp(cpu, cpu->a[thread], cpu->x[thread], thread); break; + case ENT: ent(cpu, immaddr(cpu, thread, 1)); break; /* ENd Thread. */ + case RTI: /* ReTurn from Interupt routine. */ + cpu->ps = ((uint64_t)pull(cpu) << 8*thread); + cpu->pc[thread] = (uint64_t)pull(cpu); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 8); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 16); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 24); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 32); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 40); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 48); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 56); + break; + case INC: /* INC Accumulator. */ + case INY: + case IAY: + case INX: + case IAX: + if (opcode == INC || opcode == IAY || opcode == IAX) { + cpu->a[thread]+=1; + cpu->z[thread] = (cpu->a[thread] == 0); + cpu->n[thread] = (cpu->a[thread] >> 63); + } + if (opcode == INY || opcode == IAY) { + cpu->y[thread]+=1; + cpu->z[thread] = (cpu->y[thread] == 0); + cpu->n[thread] = (cpu->y[thread] >> 63); + } + if (opcode == INX || opcode == IAX) { + cpu->x[thread]+=1; + cpu->z[thread] = (cpu->x[thread] == 0); + cpu->n[thread] = (cpu->x[thread] >> 63); + } + (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); + (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); + break; + case 0xD0: /* JMP Zero Matrix. */ + address = zeromtx(cpu, thread); + cpu->pc[thread] = address; + break; + + case DEC: /* DEC Accumulator. */ + case DEY: + case DAY: + case DEX: + case DAX: + if (opcode == DEC || opcode == DAY || opcode == DAX) { + cpu->a[thread]-=1; + cpu->z[thread] = (cpu->a[thread] == 0); + cpu->n[thread] = (cpu->a[thread] >> 63); + } + if (opcode == DEY || opcode == DAY) { + cpu->y[thread]-=1; + cpu->z[thread] = (cpu->y[thread] == 0); + cpu->n[thread] = (cpu->y[thread] >> 63); + } + if (opcode == DEX || opcode == DAX) { + cpu->x[thread]-=1; + cpu->z[thread] = (cpu->x[thread] == 0); + cpu->n[thread] = (cpu->x[thread] >> 63); + } + (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); + (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); + break; + case JSL: /* Jump to Subroutine Long. */ + address = (uint64_t)addr[cpu->pc[thread]] + | (uint64_t)addr[cpu->pc[thread]+1] << 8 + | (uint64_t)addr[cpu->pc[thread]+2] << 16 + | (uint64_t)addr[cpu->pc[thread]+3] << 24 + | (uint64_t)addr[cpu->pc[thread]+4] << 32 + | (uint64_t)addr[cpu->pc[thread]+5] << 40 + | (uint64_t)addr[cpu->pc[thread]+6] << 48 + | (uint64_t)addr[cpu->pc[thread]+7] << 56; + cpu->pc[thread]+=8; + push(cpu, (uint64_t)cpu->pc[thread] >> 56); + push(cpu, (uint64_t)cpu->pc[thread] >> 48); + push(cpu, (uint64_t)cpu->pc[thread] >> 40); + push(cpu, (uint64_t)cpu->pc[thread] >> 32); + push(cpu, (uint64_t)cpu->pc[thread] >> 24); + push(cpu, (uint64_t)cpu->pc[thread] >> 16); + push(cpu, (uint64_t)cpu->pc[thread] >> 8); + push(cpu, (uint64_t)cpu->pc[thread] & 0xFF); + cpu->pc[thread] = address; + break; + case 0xE1: inc_addr(cpu, absaddr(cpu, thread), thread); break; /* INC Absolute. */ + case 0xE2: cmp_addr(cpu, cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* CPY Absolute. */ + case 0xE3: inc_addr(cpu, zeromtx(cpu, thread), thread); break; /* INC Zero Matrix. */ + case 0xE4: cmp_addr(cpu, cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* CPX Absolute. */ + case 0xE5: cmp_addr(cpu, cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* CMP Absolute. */ + case NOP: break; /* No OPeration. */ + case RTL: /* ReTurn from subroutine Long. */ + cpu->pc[thread] = (uint64_t)pull(cpu); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 8); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 16); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 24); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 32); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 40); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 48); + cpu->pc[thread] += ((uint64_t)pull(cpu) << 56) + 1; + break; + case 0xF1: dec_addr(cpu, absaddr(cpu, thread), thread); break; /* DEC Absolute. */ + case 0xF2: cmp_addr(cpu, cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* CPY Zero Matrix. */ + case 0xF3: dec_addr(cpu, zeromtx(cpu, thread), thread); break; /* DEC Zero Matrix. */ + case 0xF4: cmp_addr(cpu, cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* CPX Zero Matrix. */ + case 0xF5: cmp_addr(cpu, cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* CMP Zero Matrix. */ + case BRK: /* BReaK. */ + push(cpu, (uint64_t)cpu->pc[thread]-1 >> 56); + push(cpu, (uint64_t)cpu->pc[thread]-1 >> 48); + push(cpu, (uint64_t)cpu->pc[thread]-1 >> 40); + push(cpu, (uint64_t)cpu->pc[thread]-1 >> 32); + push(cpu, (uint64_t)cpu->pc[thread]-1 >> 24); + push(cpu, (uint64_t)cpu->pc[thread]-1 >> 16); + push(cpu, (uint64_t)cpu->pc[thread]-1 >> 8); + push(cpu, (uint64_t)cpu->pc[thread]-1 & 0xFF); + push(cpu, (uint64_t)cpu->ps >> 8*thread); + cpu->i[thread] = 1; + setps(cpu, thread); + cpu->pc[thread] = (uint64_t)addr[0xFFE0] + | (uint64_t)addr[0xFFE1] << 8 + | (uint64_t)addr[0xFFE2] << 16 + | (uint64_t)addr[0xFFE3] << 24 + | (uint64_t)addr[0xFFE4] << 32 + | (uint64_t)addr[0xFFE5] << 40 + | (uint64_t)addr[0xFFE6] << 48 + | (uint64_t)addr[0xFFE7] << 56; + default: + if(opcode != BRK) { + printf("Cool, you inputed a non existent opcode, which means\n" + "that you have now wasted clock cycles.\n" + "Good job! *clap*\n"); + } + break; + } + inst[thread]++; + for (uint8_t i = 0; i < THREADS; i++) { + if (!i) + inss = inst[i]; + else + inss += inst[i]; + } + if (inss >= 100000000/THREADS) { end = 1; } } -#endif + /*return 1;*/ } - - int main(int argc, char **argv) { - suxx.a[0] = 0; - suxx.x[0] = 0; - suxx.y[0] = 0; - suxx.sp = 0xFFFF; + cpu = malloc(sizeof(struct sux)); + cpu->sp = 0xFFFF; ibcount = 0; - addr = malloc(8*0x04000000); + addr = malloc(0x04000000); + inss = 0; int v = 0; if (asmmon() == 2) return 0; - for (int i = 0; i < THREADS+1; i++) { - suxx.a[i] = 0; - suxx.x[i] = 0; - suxx.y[i] = 0; - suxx.pc[i] = (uint64_t)addr[0xFFC0] + for (int i = 0; i < THREADS; i++) { + cpu->a[i] = 0; + cpu->x[i] = 0; + cpu->y[i] = 0; + cpu->pc[i] = (uint64_t)addr[0xFFC0] | (uint64_t)addr[0xFFC1] << 8 | (uint64_t)addr[0xFFC2] << 16 | (uint64_t)addr[0xFFC3] << 24 @@ -433,46 +461,41 @@ int main(int argc, char **argv) { | (uint64_t)addr[0xFFC6] << 48 | (uint64_t)addr[0xFFC7] << 56; } - for (int i = 0; i < THREADS+1; i++) + for (int i = 0; i < THREADS; i++) { lines[i] = (6*i)+2; - inst = 0; - pthread_t therads[THREADS+1]; + inst[i] = 0; + } + pthread_t therads[THREADS]; int result; - uint8_t throds[THREADS+1]; + uint8_t throds[THREADS]; printf("\033[2J"); #if bench str=clock(); -#else - uint8_t end = 0; - while (!end) { #endif - for (int i = 0; i < THREADS+1; i++) { - throds[i] = i; - result = pthread_create(&therads[i], NULL, threads, &throds[i]); - assert(!result); - } - - for (int i = 0; i < THREADS+1; i++) { - result = pthread_join(therads[i], NULL); - assert(!result); - } -#if !bench - printf("\033[HInstructions executed: %llu, Clock cycles: %llu\n", inst, clk); - fflush(stdout); -#endif -#if !bench + for (int i = 0; i < THREADS; i++) { + throds[i] = i; + result = pthread_create(&therads[i], NULL, run, &throds[i]); + assert(!result); } + for (int i = 0; i < THREADS; i++) { + result = pthread_join(therads[i], NULL); + assert(!result); + } +#if !bench + printf("\033[HInstructions executed: %llu, Clock cycles: %llu\n", inss, clk); + fflush(stdout); #endif #if bench en=clock(); - double tm = (en-str)/1+THREADS; + double tm = (en-str)/THREADS; double clkspd = ((tm/CLOCKS_PER_SEC)*1000000)/clk; double mhz = 1000000.0/clkspd/1000000; - double ips = (double)inst/(double)tm; - ipc=(double)inst/(double)clk; + double ips = (double)inss/(double)tm; + ipc=(double)inss/(double)clk; printf("\033[2J"); - printf("Instructions executed: %llu, Instructions per Second in MIPS: %f, Clock cycles: %llu, Clock Speed in MHz: %f, tm: %f\n", inst, ips, clk, mhz, tm/CLOCKS_PER_SEC); + printf("Instructions executed: %llu, Instructions per Second in MIPS: %f, Clock cycles: %llu, Clock Speed in MHz: %f, tm: %f\n", inss, ips, clk, mhz, tm/CLOCKS_PER_SEC); #endif + free(cpu); free(addr); return 0; } diff --git a/test/test-the-tests.s b/test/test-the-tests.s new file mode 100644 index 0000000..47f7576 --- /dev/null +++ b/test/test-the-tests.s @@ -0,0 +1,5 @@ +cps +inc +jmp $1 +done + |