summaryrefslogtreecommitdiff
path: root/sux.c
diff options
context:
space:
mode:
Diffstat (limited to 'sux.c')
-rw-r--r--sux.c362
1 files changed, 188 insertions, 174 deletions
diff --git a/sux.c b/sux.c
index 0af4c06..f42c0da 100644
--- a/sux.c
+++ b/sux.c
@@ -1,22 +1,23 @@
#include "opcode.h"
+#define bench 0
+#if bench
+#include <time.h>
+#endif
-int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
+int run(struct sux *cpu, uint8_t prefix, uint8_t opcode, uint8_t thread) {
uint64_t address;
+ uint8_t regsize = (1 << (prefix & 3));
uint8_t tmp;
address = cpu->pc[thread];
- printf("pc: 0x%08llx, a: 0x%016llx, x: 0x%016llx, y: 0x%016llx"
- ", sp: 0x%04lx, ps: 0x%016llx, opcode: 0x%02x, inst: %s,\taddr $4000-7: 0x%016llx\n"
+#if !bench
+ printf("pc: 0x%llx, a: 0x%016llx, x: 0x%016llx, y: 0x%016llx"
+ ", sp: 0x%04lx, ps: 0x%016llx, opcode: 0x%02x, inst: %s\n"
, cpu->pc[thread], cpu->a[thread], cpu->x[thread], cpu->y[thread]
- , cpu->sp, cpu->ps, opcode, opname[opcode]
- , (uint64_t)addr[0x4000]
- | (uint64_t)addr[0x4001] << 8
- | (uint64_t)addr[0x4002] << 16
- | (uint64_t)addr[0x4003] << 24
- | (uint64_t)addr[0x4004] << 32
- | (uint64_t)addr[0x4005] << 40
- | (uint64_t)addr[0x4006] << 48
- | (uint64_t)addr[0x4007] << 56);
+ , cpu->sp, cpu->ps, opcode, opname[opcode]);
+ fflush(stdout);
+#endif
cpu->pc[thread]++;
+ clk++;
switch(opcode) {
case CPS: /* Clear Processor Status. */
for (uint8_t i = 0; i < 8; i++) {
@@ -29,9 +30,9 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
}
cpu->ps &= 0;
break;
- case ADC: adc(cpu, immaddr(cpu, thread, 8), thread); break; /* ADC Immediate. */
- case 0x03: adc(cpu, absaddr(cpu, thread), thread); break; /* ADC Absolute. */
- case 0x05: adc(cpu, zeromtx(cpu, thread), thread); break; /* ADC Zero Matrix. */
+ 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)
@@ -68,13 +69,13 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
}
push(cpu, cpu->x[thread] & 0xFF);
break;
- case JMP: /* JuMP to memory location. */
+ case JMP: /* JMP Absolute. */
address = absaddr(cpu, thread);
cpu->pc[thread] = address;
break;
- case SBC: sbc(cpu, immaddr(cpu, thread, 8), thread); break; /* SBC Immediate. */
- case 0x13: sbc(cpu, absaddr(cpu, thread), thread); break; /* SBC Absolute. */
- case 0x15: sbc(cpu, zeromtx(cpu, thread), thread); break; /* SBC Zero Matrix. */
+ 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)
@@ -123,133 +124,125 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
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);
+ | (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, 8), thread); break; /* AND Immediate. */
- case ANY: and_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, 8), thread); break; /* ANY Immediate. */
+ 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, 8), thread); break; /* ANX Immediate. */
+ 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); break; /* AND Absolute. */
- case 0x2B: and_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread); break; /* AND Zero Matrix. */
+ 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, 8), thread); break; /* ORA Immediate. */
- case ORY: or_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, 8), thread); break; /* ORY Immediate. */
+ 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, 8), thread); break; /* ORX Immediate. */
+ 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); break; /* ORA Absolute. */
- case 0x3B: or_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread); break; /* ORA Zero Matrix. */
+ 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, 8), thread); break; /* XOR Immediate. */
- case XRY: xor_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, 8), thread); break; /* XRY Immediate. */
+ 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, 9), thread); break; /* XRX Immediate. */
+ 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); break; /* XOR Absolute. */
- case 0x4B: xor_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread); break; /* XOR Zero Matrix. */
+ 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); break; /* ANY Absolute. */
+ 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); break; /* ANX 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); break; /* LDA Absolute. */
- case 0x5A: ld(cpu, &cpu->y[thread], absaddr(cpu, thread), thread); break; /* LDY Absolute. */
- case STA: st(cpu, &cpu->a[thread], absaddr(cpu, thread), thread); break; /* STA Absolute. */
- case 0x5C: ld(cpu, &cpu->x[thread], absaddr(cpu, thread), thread); break; /* LDX Absolute. */
- case STY: st(cpu, &cpu->y[thread], absaddr(cpu, thread), thread); break; /* STY Absolute. */
- case STX: st(cpu, &cpu->x[thread], absaddr(cpu, thread), thread); break; /* STX Absolute. */
+ 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); break; /* ORY Absolute. */
+ 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); break; /* ORX 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, 8), thread); break; /* LDA Immediate. */
- case LDY: ld(cpu, &cpu->y[thread], immaddr(cpu, thread, 8), thread); break; /* LDY Immediate. */
- case LDX: ld(cpu, &cpu->x[thread], immaddr(cpu, thread, 8), thread); break; /* LDX Immediate. */
+ 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); break; /* XRY Absolute. */
+ 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); break; /* XRX 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); break; /* LDA Zero Matrix. */
- case 0x7A: ld(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread); break; /* LDY Zero Matrix. */
- case 0x7B: st(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread); break; /* STA Zero Matrix. */
- case 0x7C: ld(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread); break; /* LDX Zero Matrix. */
- case 0x7D: st(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread); break; /* STY Zero Matrix. */
- case 0x7E: st(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread); break; /* STX Zero Matrix. */
+ 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); break; /* ANY Zero Matrix. */
+ 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); break; /* ANX Zero Matrix. */
+ 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); break; /* LDA Zero Matrix, Indexed with X. */
- case 0x8A: ld(cpu, &cpu->y[thread], zeromx(cpu, thread), thread); break; /* LDY Zero Matrix, Indexed with X. */
- case 0x8B: st(cpu, &cpu->a[thread], zeromx(cpu, thread), thread); break; /* STA Zero Matrix, Indexed with X. */
- case 0x8D: st(cpu, &cpu->y[thread], zeromx(cpu, thread), thread); break; /* STY Zero Matrix, Indexed with X. */
+ 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, 8), thread); break; /* MUL Immediate. */
- case 0x92: or_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread); break; /* ORY Zero Matrix. */
- case 0x93: mul(cpu, absaddr(cpu, thread), thread); break; /* MUL Absolute. */
- case 0x94: or_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread); break; /* ORX Zero Matrix. */
- case 0x95: mul(cpu, zeromtx(cpu, thread), thread); break; /* MUL Zero Matrix. */
+ 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); break; /* LDA Zero Matrix, Indexed with Y. */
- case 0x9B: ld(cpu, &cpu->x[thread], zeromy(cpu, thread), thread); break; /* STA Zero Matrix, Indexed with Y. */
- case 0x9C: st(cpu, &cpu->a[thread], zeromy(cpu, thread), thread); break; /* LDX Zero Matrix, Indexed with Y. */
- case 0x9E: st(cpu, &cpu->x[thread], zeromy(cpu, thread), thread); break; /* STX Zero Matrix, Indexed with Y. */
+ 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, 8), thread); break; /* DIV Immediate. */
- case 0xA2: xor_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread); break; /* XRY Zero Matrix. */
- case 0xA3: divd(cpu, absaddr(cpu, thread), thread); break; /* DIV Absolute. */
- case 0xA4: xor_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread); break; /* XRX Zero Matrix. */
- case 0xA5: divd(cpu, zeromtx(cpu, thread), thread); break; /* DIV Zero Matrix. */
+ 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);
@@ -258,16 +251,12 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t 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) + 1;
+ cpu->pc[thread] += ((uint64_t)pull(cpu) << 24) + 1;
break;
- case CMP: cmp_addr(cpu, cpu->a[thread], immaddr(cpu, thread, 8), thread); break; /* CMP Immediate */
- case CPY: cmp_addr(cpu, cpu->y[thread], immaddr(cpu, thread, 8), thread); break; /* CPY Immediate */
+ 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, 8), thread); break; /* CPX Immediate */
+ 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. */
@@ -279,7 +268,7 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
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;
+ cpu->pc[thread] += ((uint64_t)pull(cpu) << 56);
break;
case INC: /* INC Accumulator. */
inc(cpu, &cpu->a[thread], thread);
@@ -288,22 +277,56 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
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); break; /* CPY 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); break; /* CPX Absolute. */
- case 0xE5: cmp_addr(cpu, cpu->a[thread], absaddr(cpu, thread), thread); break; /* CMP Absolute. */
+ 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); break; /* CPY Zero Matrix. */
+ 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); break; /* CPX Zero Matrix. */
- case 0xF5: cmp_addr(cpu, cpu->a[thread], zeromtx(cpu, thread), thread); break; /* CMP 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);
@@ -320,10 +343,10 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
| (uint64_t)addr[0xFFE1] << 8
| (uint64_t)addr[0xFFE2] << 16
| (uint64_t)addr[0xFFE3] << 24
- | (uint64_t)addr[0xFFF0] << 32
- | (uint64_t)addr[0xFFF1] << 40
- | (uint64_t)addr[0xFFF2] << 48
- | (uint64_t)addr[0xFFF3] << 56;
+ | (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"
@@ -336,6 +359,8 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
}
int main(int argc, char **argv) {
+
+
struct sux cpu;
cpu.a[0] = 0;
cpu.x[0] = 0;
@@ -343,101 +368,90 @@ int main(int argc, char **argv) {
cpu.sp = 0xFFFF;
addr = malloc(8*0x04000000);
int v = 0;
+ if (asmmon() == 2)
+ return 0;
- addr[0x8000] = 0x00; /* CPS */
- addr[0x8001] = 0x69; /* LDA #$01 */
- addr[0x8002] = 0x02;
- addr[0x8003] = 0x00;
- addr[0x8004] = 0x00;
- addr[0x8005] = 0x00;
- addr[0x8006] = 0x00;
- addr[0x8007] = 0x00;
- addr[0x8008] = 0x00;
- addr[0x8009] = 0x00;
- addr[0x800A] = 0x7B; /* STA $4000 */
- addr[0x800B] = 0x00;
- addr[0x800C] = 0x40;
- addr[0x800D] = 0x00;
- addr[0x800E] = 0x00;
- addr[0x800F] = 0x7C; /* LDX $4000 */
- addr[0x8010] = 0x00;
- addr[0x8011] = 0x40;
- addr[0x8012] = 0x00;
- addr[0x8013] = 0x00;
- addr[0x8014] = 0x05; /* ADC $4000 */
- addr[0x8015] = 0x00;
- addr[0x8016] = 0x40;
- addr[0x8017] = 0x00;
- addr[0x8018] = 0x00;
- addr[0x8019] = 0xF8; /* BRK */
- addr[0x801A] = 0x10; /* JMP $800A */
- addr[0x801B] = 0x0A;
- addr[0x801C] = 0x80;
- addr[0x801D] = 0x00;
- addr[0x801E] = 0x00;
- addr[0x801F] = 0x00;
- addr[0x8020] = 0x00;
- addr[0x8021] = 0x00;
- addr[0x8022] = 0x00;
-
- addr[0x28000] = 0xE8; /* NOP */
- addr[0x28001] = 0x6A; /* LDY #$800A10E8 */
- addr[0x28002] = 0xE8;
- addr[0x28003] = 0x10;
- addr[0x28004] = 0x0A;
- addr[0x28005] = 0x80;
- addr[0x28006] = 0x00;
- addr[0x28007] = 0x00;
- addr[0x28008] = 0x00;
- addr[0x28009] = 0x00;
- addr[0x2800A] = 0x7D; /* STY $8019 */
- addr[0x2800B] = 0x19;
- addr[0x2800C] = 0x80;
- addr[0x2800D] = 0x00;
- addr[0x2800E] = 0x00;
- addr[0x2800F] = 0xC0; /* RTI */
-
+#if 0
+ /* Reset Vector. */
addr[0xFFC0] = 0x00;
addr[0xFFC1] = 0x80;
addr[0xFFC2] = 0x00;
addr[0xFFC3] = 0x00;
- addr[0xFFD0] = 0x00;
- addr[0xFFD1] = 0x00;
- addr[0xFFD2] = 0x00;
- addr[0xFFD3] = 0x00;
-
+ addr[0xFFC4] = 0x00;
+ addr[0xFFC5] = 0x00;
+ addr[0xFFC6] = 0x00;
+ addr[0xFFC7] = 0x00;
+#endif
+#if 0
+ /* BRK Vector. */
addr[0xFFE0] = 0x00;
addr[0xFFE1] = 0x80;
addr[0xFFE2] = 0x02;
addr[0xFFE3] = 0x00;
- addr[0xFFF0] = 0x00;
- addr[0xFFF1] = 0x00;
- addr[0xFFF2] = 0x00;
- addr[0xFFF3] = 0x00;
-
+ addr[0xFFE4] = 0x00;
+ addr[0xFFE5] = 0x00;
+ addr[0xFFE6] = 0x00;
+ addr[0xFFE7] = 0x00;
+#endif
cpu.pc[0] = (uint64_t)addr[0xFFC0]
| (uint64_t)addr[0xFFC1] << 8
| (uint64_t)addr[0xFFC2] << 16
| (uint64_t)addr[0xFFC3] << 24
- | (uint64_t)addr[0xFFD0] << 32
- | (uint64_t)addr[0xFFD1] << 40
- | (uint64_t)addr[0xFFD2] << 48
- | (uint64_t)addr[0xFFD3] << 56;
+ | (uint64_t)addr[0xFFC4] << 32
+ | (uint64_t)addr[0xFFC5] << 40
+ | (uint64_t)addr[0xFFC6] << 48
+ | (uint64_t)addr[0xFFC7] << 56;
uint64_t inst = 0;
uint8_t lines = 2;
+ uint8_t prefix = 0;
uint8_t opcode = 0;
uint8_t end = 0;
+#if bench
+ double ipc;
+ clock_t st, en;
+ double t0;
+#endif
printf("\033[2J");
+#if bench
+ st = clock();
+#endif
while (!end) {
+ prefix = addr[cpu.pc[0]++];
opcode = addr[cpu.pc[0]];
+#if !bench
printf("\033[%uH\033[2K", lines);
lines++;
- run(&cpu, opcode, 0);
-
+#endif
+ run(&cpu, prefix, opcode, 0);
+#if !bench
if (lines > 24)
lines = 2;
- printf("\033[HInstructions executed: %llu\n", inst++);
+#endif
+#if bench
+ t0 = ((double)clock() - (double)st)/(double)CLOCKS_PER_SEC;
+#endif
+ inst++;
+
+#if !bench
+ printf("\033[HInstructions executed: %llu, Clock cycles: %llu\n", inst, clk);
+ fflush(stdout);
+#endif
+#if bench
+ if (t0 >= 1.00) {
+ end = 1;
+ }
+#endif
}
+#if bench
+ en = (double)clock();
+ double tm = (double)(en - st);
+ double clkspd = (t0*1000000)/clk;
+ double mhz = 1000000.0/clkspd/1000000;
+ double ips = (double)inst/(double)tm;
+ ipc=(double)inst/(double)clk;
+ printf("\033[2J");
+ printf("Instructions executed: %llu, Instructions per Second in MIPS: %f, Clock cycles: %llu, Clock Speed in MHz: %f\n", inst, ips, clk, mhz);
+#endif
free(addr);
return 0;
}