#include "opcode.h" #define bench 0 #if bench #include #endif 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]; #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]); fflush(stdout); #endif 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; } int main(int argc, char **argv) { struct sux cpu; cpu.a[0] = 0; cpu.x[0] = 0; cpu.y[0] = 0; cpu.sp = 0xFFFF; addr = malloc(8*0x04000000); int v = 0; if (asmmon() == 2) return 0; #if 0 /* Reset Vector. */ addr[0xFFC0] = 0x00; addr[0xFFC1] = 0x80; addr[0xFFC2] = 0x00; addr[0xFFC3] = 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[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[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++; #endif run(&cpu, prefix, opcode, 0); #if !bench if (lines > 24) lines = 2; #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; }