summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2019-12-03 11:03:11 -0500
committermrb0nk500 <b0nk@b0nk.xyz>2019-12-03 11:03:11 -0500
commit5962c60342b9ed6562d7fb0f71a50ca9700b3735 (patch)
treed784fa88b47bce5359cdcd497ef6bd45cb6e3461
parent245940209d5b8458f5d998783f7992573e2951bf (diff)
Start optimizing the emulator.
-rw-r--r--opcode.c14
-rw-r--r--sux.c847
-rw-r--r--test/test-the-tests.s5
3 files changed, 440 insertions, 426 deletions
diff --git a/opcode.c b/opcode.c
index e4bd510..036a4fb 100644
--- a/opcode.c
+++ b/opcode.c
@@ -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]--;
}
diff --git a/sux.c b/sux.c
index a38b52a..b791022 100644
--- a/sux.c
+++ b/sux.c
@@ -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
+