diff options
-rw-r--r-- | opcode.c | 3 | ||||
-rw-r--r-- | opcode.h | 19 | ||||
-rw-r--r-- | sux.c | 163 |
3 files changed, 116 insertions, 69 deletions
@@ -1,4 +1,5 @@ #include "opcode.h" + void setps(struct sux *cpu, uint8_t thread) { (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); @@ -57,7 +58,7 @@ void mul(struct sux *cpu, uint64_t adr, uint8_t thread) { cpu->z[thread] = (sum == 0); cpu->n[thread] = (sum >> 63); cpu->v[thread] = !((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000); - cpu->c[thread] = (!((cpu->a[thread]^sum) && (cpu->a[thread]^value)) || (cpu->a[thread] >= ((uint64_t)1 << 32) && value >= ((uint64_t)1 << 32))); + cpu->c[thread] = (!((cpu->a[thread]^sum) && (cpu->a[thread]^value)) && (cpu->a[thread] >= ((uint64_t)1 << 32) && value >= ((uint64_t)1 << 32))); cpu->a[thread] = sum; setps(cpu, thread); } @@ -40,15 +40,15 @@ #define BCS 0x50 /* Branch if Carry Set. */ #define LSL 0x51 /* Logical Shift Left. */ #define SEC 0x58 /* SEt Carry flag. */ +#define STA 0x5B /* STore Accumulator. */ +#define STY 0x5D /* STore Y register. */ +#define STX 0x5E /* STore X register. */ #define BCC 0x60 /* Branch if Carry Clear. */ #define LSR 0x61 /* Logical Shift Right. */ #define CLC 0x68 /* CLear Carry flag. */ #define LDA 0x69 /* LoaD Accumulator. */ #define LDY 0x6A /* LoaD Y register. */ -#define STA 0x6B /* STore Accumulator. */ #define LDX 0x6C /* LoaD X register. */ -#define STY 0x6D /* STore Y register. */ -#define STX 0x6E /* STore X register. */ #define BEQ 0x70 /* Branch if EQual. */ #define ROL 0x71 /* ROtate Left. */ #define SSP 0x78 /* Set Stack Protection flag. */ @@ -158,10 +158,10 @@ static const char *opname[0x100] = { OPNAME(SEC), [0x59] = "LDA a", [0x5A] = "LDY a", - [0x5B] = "STA a", + [STA] = "STA a", [0x5C] = "LDX a", - [0x5D] = "STY a", - [0x5E] = "STX a", + [STY] = "STY a", + [STX] = "STX a", OPNAME(BCC), [LSR] = "LSR #", [0x62] = "ORY a", @@ -171,10 +171,7 @@ static const char *opname[0x100] = { OPNAME(CLC), [LDA]= "LDA #", [LDY]= "LDY #", - [STA]= "STA #", [LDX]= "LDX #", - [STY]= "STY #", - [STX]= "STX #", OPNAME(BEQ), [ROL] = "ROL #", [0x72] = "XRY a", @@ -225,12 +222,12 @@ static const char *opname[0x100] = { OPNAME(CAX), OPNAME(ENT), OPNAME(RTI), - [INC] = "INC #", + [INC] = "INC A", OPNAME(INY), OPNAME(IAY), OPNAME(INX), OPNAME(IAX), - [DEC] = "DEC #", + [DEC] = "DEC A", OPNAME(DEY), OPNAME(DAY), OPNAME(DEX), @@ -5,9 +5,17 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) { uint8_t tmp; address = cpu->pc[thread]; printf("pc: 0x%08llx, a: 0x%016llx, x: 0x%016llx, y: 0x%016llx" - ", sp: 0x%04lx, carry: %u, opcode: 0x%02x, inst: %s\n" + ", sp: 0x%04lx, ps: 0x%016llx, opcode: 0x%02x, inst: %s,\taddr $4000-7: 0x%016llx\n" , cpu->pc[thread], cpu->a[thread], cpu->x[thread], cpu->y[thread] - , cpu->sp, cpu->c[thread], opcode, opname[opcode]); + , 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->pc[thread]++; switch(opcode) { case CPS: /* Clear Processor Status. */ @@ -148,7 +156,6 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) { case SEI: /* SEt Interrupt. */ cpu->i[thread] = 1; setps(cpu, thread); - cpu->pc[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. */ @@ -161,7 +168,6 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) { case CLI: /* CLear Interrupt. */ cpu->i[thread] = 0; setps(cpu, thread); - cpu->pc[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. */ @@ -174,14 +180,13 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) { case SEC: /* SEt Carry flag.*/ cpu->c[thread] = 1; setps(cpu, thread); - cpu->pc[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 0x5B: st(cpu, &cpu->a[thread], absaddr(cpu, thread), thread); break; /* STA 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 0x5D: st(cpu, &cpu->y[thread], absaddr(cpu, thread), thread); break; /* STY Absolute. */ - case 0x5E: st(cpu, &cpu->x[thread], absaddr(cpu, thread), thread); break; /* STX 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 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. */ @@ -191,14 +196,10 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) { case CLC: /* CLear Carry flag. */ cpu->c[thread] = 0; setps(cpu, thread); - cpu->pc[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 STA: st(cpu, &cpu->a[thread], immaddr(cpu, thread, 8), thread); break; /* STA Immediate. */ case LDX: ld(cpu, &cpu->x[thread], immaddr(cpu, thread, 8), thread); break; /* LDX Immediate. */ - case STY: st(cpu, &cpu->y[thread], immaddr(cpu, thread, 8), thread); break; /* STY Immediate. */ - case STX: st(cpu, &cpu->x[thread], immaddr(cpu, thread, 8), thread); break; /* STX 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. */ @@ -208,7 +209,6 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) { case SSP: /* Set Stack Protection flag. */ cpu->s[thread] = 1; setps(cpu, thread); - cpu->pc[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. */ @@ -225,7 +225,6 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) { case CSP: /* Clear Stack Protection flag. */ cpu->s[thread] = 0; setps(cpu, thread); - cpu->pc[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. */ @@ -240,7 +239,6 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) { case SEV: /* SEt oVerflow flag. */ cpu->v[thread] = 1; setps(cpu, thread); - cpu->pc[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. */ @@ -255,7 +253,6 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) { case CLV: /* CLear oVerflow flag. */ cpu->v[thread] = 0; setps(cpu, thread); - cpu->pc[thread]++; break; case RTS: /* ReTurn from Subroutine. */ cpu->pc[thread] = (uint64_t)pull(cpu); @@ -273,7 +270,17 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) { case CPX: cmp_addr(cpu, cpu->x[thread], immaddr(cpu, thread, 8), thread); 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: break; /* ReTurn from Interupt routine. */ + 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) + 1; + break; case INC: /* INC Accumulator. */ inc(cpu, &cpu->a[thread], thread); break; @@ -291,17 +298,38 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) { 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 NOP: cpu->pc[thread]++; break; /* No OPeration. */ + case NOP: break; /* No OPeration. */ 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 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 BRK: break; /* BReaK. */ + 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[0xFFF0] << 32 + | (uint64_t)addr[0xFFF1] << 40 + | (uint64_t)addr[0xFFF2] << 48 + | (uint64_t)addr[0xFFF3] << 56; default: - printf("Cool, you inputed a non existent opcode, which means\n" - "that you have now wasted clock cycles.\n" - "Good job! *clap*\n"); + 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; @@ -316,46 +344,58 @@ int main(int argc, char **argv) { addr = malloc(8*0x04000000); int v = 0; - /*addr[0x8000] = 0x00; /* CPS */ - /*addr[0x8001] = 0xE1; /* LDA #$01 */ - /*addr[0x8002] = 0x01; - addr[0x8003] = 0x51; /* SLA #$04 */ - /*addr[0x8004] = 0x04; - addr[0x8005] = 0x50; /* BCS $800B */ - /*addr[0x8006] = 0x0B; - addr[0x8007] = 0x80; - addr[0x8008] = 0x10; /* JMP $8003 */ - /*addr[0x8009] = 0x03; - addr[0x800A] = 0x80; - addr[0x800B] = 0xE1; /* LDA #$01 */ - /*addr[0x800C] = 0x01; - addr[0x800D] = 0x51; /* SLA #$38 */ - /*addr[0x800E] = 0x38; - addr[0x800F] = 0x61; /* SRA #$04 */ - /*addr[0x8010] = 0x04; - addr[0x8011] = 0x50; /* BCS $8017 */ - /*addr[0x8012] = 0x17; - addr[0x8013] = 0x80; - addr[0x8014] = 0x10; /* JMP $800F */ - /*addr[0x8015] = 0x0F; - addr[0x8016] = 0x80; - addr[0x8017] = 0x10; /* JMP $8001 */ - /*addr[0x8018] = 0x01; - addr[0x8019] = 0x80; - addr[0xFFFC] = 0x00; - addr[0xFFFD] = 0x80;*/ - addr[0x8000] = 0x00; /* CPS */ - addr[0x8001] = 0xC5; /* IAX */ - addr[0x8002] = 0x10; /* JMP $8001 */ - addr[0x8003] = 0x01; - addr[0x8004] = 0x80; + 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] = 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 */ addr[0xFFC0] = 0x00; addr[0xFFC1] = 0x80; @@ -366,6 +406,15 @@ int main(int argc, char **argv) { addr[0xFFD2] = 0x00; addr[0xFFD3] = 0x00; + addr[0xFFE0] = 0x00; + addr[0xFFE1] = 0x80; + addr[0xFFE2] = 0x02; + addr[0xFFE3] = 0x00; + addr[0xFFF0] = 0x00; + addr[0xFFF1] = 0x00; + addr[0xFFF2] = 0x00; + addr[0xFFF3] = 0x00; + cpu.pc[0] = (uint64_t)addr[0xFFC0] | (uint64_t)addr[0xFFC1] << 8 | (uint64_t)addr[0xFFC2] << 16 @@ -385,7 +434,7 @@ int main(int argc, char **argv) { lines++; run(&cpu, opcode, 0); - if (lines > 50) + if (lines > 24) lines = 2; printf("\033[HInstructions executed: %llu\n", inst++); } |