diff options
author | mrb0nk500 <b0nk@b0nk.xyz> | 2019-11-26 00:33:20 -0500 |
---|---|---|
committer | mrb0nk500 <b0nk@b0nk.xyz> | 2019-11-26 00:33:20 -0500 |
commit | c1e735ec8b0481c1ebc631cd495a10f72e47ba32 (patch) | |
tree | e43331c872a35790e070ad2daded086a5ef6f8c7 | |
parent | 988c81ae76ab0da47db8938c14865d6e5b3a8024 (diff) |
Revamped the entire emulator.
I finally implemented the other addressing modes, and
added a Makefile.
Not sure when I will start work on rev2 of Sux, but it
will be sometime soon.
-rw-r--r-- | Makefile | 24 | ||||
-rw-r--r-- | opcode.c | 358 | ||||
-rw-r--r-- | opcode.h | 217 | ||||
-rw-r--r-- | sux.c | 1058 |
4 files changed, 862 insertions, 795 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e83e8b2 --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +PREFIX := /usr/local +BIN_DIR := $(PREFIX)/bin + +ifdef PCC +PCC_CFLAGS=-D__float128="long double" +else +PCC_CFLAGS= +endif + +CFLAGS = $(PCC_CFLAGS) $(CFLAGS_EXTRA) +OBJS = opcode.o sux.o +OBJ_NAME = cisc-0.2 +all : $(OBJS) + $(CC) $(OBJS) $(CFLAGS) -o $(OBJ_NAME) +sux.o : + $(CC) sux.c -c $(CFLAGS) -o sux.o +opcode.o : + $(CC) opcode.c -c $(CFLAGS) -o opcode.o +clean : + rm -f $(OBJ_NAME) $(OBJS) +install : + install -D -m755 $(OBJ_NAME) $(BIN_DIR)/$(OBJ_NAME) +uninstall : + rm -f $(BIN_DIR)/$(OBJ_NAME) diff --git a/opcode.c b/opcode.c new file mode 100644 index 0000000..ea3f726 --- /dev/null +++ b/opcode.c @@ -0,0 +1,358 @@ +#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)); + (cpu->i[thread]) ? (cpu->ps |= (I << 8*thread)) : (cpu->ps &= ~(I << 8*thread)); + (cpu->s[thread]) ? (cpu->ps |= (S << 8*thread)) : (cpu->ps &= ~(S << 8*thread)); + (cpu->v[thread]) ? (cpu->ps |= (V << 8*thread)) : (cpu->ps &= ~(V << 8*thread)); + (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); +} + +void adc(struct sux *cpu, uint64_t adr, uint8_t thread) { + uint64_t value = (uint64_t)addr[adr] + | (uint64_t)addr[adr+1] << 8 + | (uint64_t)addr[adr+2] << 16 + | (uint64_t)addr[adr+3] << 24 + | (uint64_t)addr[adr+4] << 32 + | (uint64_t)addr[adr+5] << 40 + | (uint64_t)addr[adr+6] << 48 + | (uint64_t)addr[adr+7] << 56; + uint64_t sum = cpu->a[thread]+value+cpu->c[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] = (sum < value); + cpu->a[thread] = sum; + setps(cpu, thread); +} + +void sbc(struct sux *cpu, uint64_t adr, uint8_t thread) { + uint64_t value = (uint64_t)addr[adr] + | (uint64_t)addr[adr+1] << 8 + | (uint64_t)addr[adr+2] << 16 + | (uint64_t)addr[adr+3] << 24 + | (uint64_t)addr[adr+4] << 32 + | (uint64_t)addr[adr+5] << 40 + | (uint64_t)addr[adr+6] << 48 + | (uint64_t)addr[adr+7] << 56; + uint64_t sum = cpu->a[thread]-value-!cpu->c[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] = (sum > value); + cpu->a[thread] = sum; + setps(cpu, thread); +} + +void mul(struct sux *cpu, uint64_t adr, uint8_t thread) { + uint64_t value = (uint64_t)addr[adr] + | (uint64_t)addr[adr+1] << 8 + | (uint64_t)addr[adr+2] << 16 + | (uint64_t)addr[adr+3] << 24 + | (uint64_t)addr[adr+4] << 32 + | (uint64_t)addr[adr+5] << 40 + | (uint64_t)addr[adr+6] << 48 + | (uint64_t)addr[adr+7] << 56; + uint64_t sum = cpu->a[thread]*value+cpu->c[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->a[thread] = sum; + setps(cpu, thread); +} + +void divd(struct sux *cpu, uint64_t adr, uint8_t thread) { + uint64_t value = (uint64_t)addr[adr] + | (uint64_t)addr[adr+1] << 8 + | (uint64_t)addr[adr+2] << 16 + | (uint64_t)addr[adr+3] << 24 + | (uint64_t)addr[adr+4] << 32 + | (uint64_t)addr[adr+5] << 40 + | (uint64_t)addr[adr+6] << 48 + | (uint64_t)addr[adr+7] << 56; + uint64_t sum = cpu->a[thread]/value; + cpu->z[thread] = (sum == 0); + cpu->v[thread] = !((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000); + cpu->a[thread] = sum; + setps(cpu, thread); +} + +uint64_t and(struct sux *cpu, uint64_t value, uint8_t thread) { + uint64_t sum; + sum &= value; + cpu->z[thread] = (sum == 0); + cpu->n[thread] = (sum >> 63); + setps(cpu, thread); + return sum; +} + +void and_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread) { + uint64_t value = (uint64_t)addr[adr] + | (uint64_t)addr[adr+1] << 8 + | (uint64_t)addr[adr+2] << 16 + | (uint64_t)addr[adr+3] << 24 + | (uint64_t)addr[adr+4] << 32 + | (uint64_t)addr[adr+5] << 40 + | (uint64_t)addr[adr+6] << 48 + | (uint64_t)addr[adr+7] << 56; + *reg &= value; + cpu->z[thread] = (*reg == 0); + cpu->n[thread] = (*reg >> 63); + setps(cpu, thread); +} + +uint64_t or(struct sux *cpu, uint64_t value, uint8_t thread) { + uint64_t sum; + sum |= value; + cpu->z[thread] = (sum == 0); + cpu->n[thread] = (sum >> 63); + setps(cpu, thread); + return sum; +} + +void or_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread) { + uint64_t value = (uint64_t)addr[adr] + | (uint64_t)addr[adr+1] << 8 + | (uint64_t)addr[adr+2] << 16 + | (uint64_t)addr[adr+3] << 24 + | (uint64_t)addr[adr+4] << 32 + | (uint64_t)addr[adr+5] << 40 + | (uint64_t)addr[adr+6] << 48 + | (uint64_t)addr[adr+7] << 56; + *reg |= value; + cpu->z[thread] = (*reg == 0); + cpu->n[thread] = (*reg >> 63); + setps(cpu, thread); +} + +uint64_t xor(struct sux *cpu, uint64_t value, uint8_t thread) { + uint64_t sum; + sum ^= value; + cpu->z[thread] = (sum == 0); + cpu->n[thread] = (sum >> 63); + setps(cpu, thread); + return sum; +} + +void xor_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread) { + uint64_t value = (uint64_t)addr[adr] + | (uint64_t)addr[adr+1] << 8 + | (uint64_t)addr[adr+2] << 16 + | (uint64_t)addr[adr+3] << 24 + | (uint64_t)addr[adr+4] << 32 + | (uint64_t)addr[adr+5] << 40 + | (uint64_t)addr[adr+6] << 48 + | (uint64_t)addr[adr+7] << 56; + *reg ^= value; + cpu->z[thread] = (*reg == 0); + cpu->n[thread] = (*reg >> 63); + setps(cpu, thread); +} + +void rol(struct sux *cpu, uint64_t adr, uint8_t thread) { + uint64_t value = addr[adr]; + uint64_t sum = cpu->a[thread] << value; + sum |= cpu->c[thread]; + cpu->z[thread] = (sum == 0); + cpu->n[thread] = (sum >> 63); + cpu->c[thread] = cpu->a[thread] >> (uint64_t)64-value; + cpu->a[thread] = sum; + setps(cpu, thread); +} + +void ror(struct sux *cpu, uint64_t adr, uint8_t thread) { + uint64_t value = addr[adr]; + uint64_t sum = cpu->a[thread] >> value; + sum |= (uint64_t)cpu->c[thread] << (uint64_t)64-value; + cpu->c[thread] = cpu->a[thread] & 1; + cpu->a[thread] = sum; + setps(cpu, thread); +} + +void lsl(struct sux *cpu, uint64_t adr, uint8_t thread) { + uint64_t value = addr[adr]; + uint64_t sum = (value < 64) ? cpu->a[thread] << value : 0; + cpu->c[thread] = cpu->a[thread] >> 64-value; + cpu->a[thread] = sum; + setps(cpu, thread); +} + +void lsr(struct sux *cpu, uint64_t adr, uint8_t thread) { + uint64_t value = addr[adr]; + uint64_t sum = (value < 64) ? cpu->a[thread] >> value : 0; + cpu->c[thread] = cpu->a[thread] & 1; + cpu->a[thread] = sum; + 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]--; +} + +void stt(struct sux* const cpu, uint8_t value) { + uint16_t tv = 0xFF50; /* Thread Vector. */ + uint8_t t = addr[value]; + cpu->crt |= t; + for (uint8_t i = 0; i < 7; i++) + if ((t >> i) & 1) { + uint64_t adr = (uint64_t)addr[tv+(8*i)] + | (uint64_t)addr[tv+1+(8*i)] << 8 + | (uint64_t)addr[tv+2+(8*i)] << 16 + | (uint64_t)addr[tv+3+(8*i)] << 24 + | (uint64_t)addr[tv+4+(8*i)] << 32 + | (uint64_t)addr[tv+5+(8*i)] << 40 + | (uint64_t)addr[tv+6+(8*i)] << 48 + | (uint64_t)addr[tv+7+(8*i)] << 56; + cpu->pc[i+1] = adr; + } +} + +void ent(struct sux *cpu, uint8_t value) { + uint8_t t = addr[value]; + cpu->crt &= ~t; + for (uint8_t i = 0; i < 7; i++) + if ((t >> i) & 1) + cpu->pc[i+1] = cpu->pc[0]+(i+1); +} + +void ld(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread) { + *reg = (uint64_t)addr[adr] + | (uint64_t)addr[adr+1] << 8 + | (uint64_t)addr[adr+2] << 16 + | (uint64_t)addr[adr+3] << 24 + | (uint64_t)addr[adr+4] << 32 + | (uint64_t)addr[adr+5] << 40 + | (uint64_t)addr[adr+6] << 48 + | (uint64_t)addr[adr+7] << 56; + cpu->z[thread] = (*reg == 0); + cpu->n[thread] = (*reg >> 63); + setps(cpu, thread); +} + +void st(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread) { + addr[adr] = *reg & 0xFF; + addr[adr+1] = *reg >> 8; + addr[adr+2] = *reg >> 16; + addr[adr+3] = *reg >> 24; + addr[adr+4] = *reg >> 32; + addr[adr+5] = *reg >> 40; + addr[adr+6] = *reg >> 48; + addr[adr+7] = *reg >> 56; +} + +void push(struct sux *cpu, uint8_t value) { + addr[STK_STADDR+cpu->sp] = value; + cpu->sp--; + addr[0xFF90] = cpu->sp & 0xFF; + addr[0xFF91] = cpu->sp >> 8; +} + +uint8_t pull(struct sux *cpu) { + cpu->sp++; + addr[0xFF90] = cpu->sp & 0xFF; + addr[0xFF91] = cpu->sp >> 8; + return addr[STK_STADDR+cpu->sp]; +} + +void cmp_addr(struct sux *cpu, uint64_t reg, uint64_t adr, uint8_t thread) { + uint64_t value = (uint64_t)addr[adr] + | (uint64_t)addr[adr+1] << 8 + | (uint64_t)addr[adr+2] << 16 + | (uint64_t)addr[adr+3] << 24 + | (uint64_t)addr[adr+4] << 32 + | (uint64_t)addr[adr+5] << 40 + | (uint64_t)addr[adr+6] << 48 + | (uint64_t)addr[adr+7] << 56; + uint64_t sum = reg-value; + cpu->n[thread] = (sum & 0x8000000000000000) ? 1 : 0; + cpu->z[thread] = (sum == 0) ? 1 : 0; + cpu->c[thread] = (sum > value) ? 1 : 0; + setps(cpu, thread); +} + +void cmp(struct sux *cpu, uint64_t reg1, uint64_t reg2, uint8_t thread) { + uint64_t sum = reg1-reg2; + cpu->n[thread] = (sum & 0x8000000000000000) ? 1 : 0; + cpu->z[thread] = (sum == 0) ? 1 : 0; + cpu->c[thread] = (sum > reg2) ? 1 : 0; + setps(cpu, thread); +} + +/* Branch if Flag Set. */ +void bfs(struct sux *cpu, uint8_t flag, uint64_t adr, uint8_t thread) { + if (flag) + cpu->pc[thread] = adr; +} + +/* Branch if Flag Clear. */ +void bfc(struct sux *cpu, uint8_t flag, uint64_t adr, uint8_t thread) { + if (!flag) + cpu->pc[thread] = adr; +} + +uint64_t immaddr(struct sux *cpu, uint8_t thread, uint8_t size) { + uint64_t adr = cpu->pc[thread]; + cpu->pc[thread]+=size; + return adr; +} + +uint64_t absaddr(struct sux *cpu, uint8_t thread) { + uint64_t adr = (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; + return adr; +} + +uint32_t zeromtx(struct sux *cpu, uint8_t thread) { + uint32_t adr = (uint32_t)addr[cpu->pc[thread]] + | (uint32_t)addr[cpu->pc[thread]+1] << 8 + | (uint32_t)addr[cpu->pc[thread]+2] << 16 + | (uint32_t)addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=4; + return adr; +} + +uint32_t zeromx(struct sux *cpu, uint8_t thread) { + uint32_t adr = (uint32_t)addr[cpu->pc[thread]] + | (uint32_t)addr[cpu->pc[thread]+1] << 8 + | (uint32_t)addr[cpu->pc[thread]+2] << 16 + | (uint32_t)addr[cpu->pc[thread]+3] << 24; + adr += cpu->x[thread]; + cpu->pc[thread]+=4; + return adr; +} + +uint32_t zeromy(struct sux *cpu, uint8_t thread) { + uint32_t adr = (uint32_t)addr[cpu->pc[thread]] + | (uint32_t)addr[cpu->pc[thread]+1] << 8 + | (uint32_t)addr[cpu->pc[thread]+2] << 16 + | (uint32_t)addr[cpu->pc[thread]+3] << 24; + adr += cpu->y[thread]; + cpu->pc[thread]+=4; + return adr; +} @@ -1,20 +1,21 @@ +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + #define OPNAME(opcode) [opcode] = #opcode /* Get name of Opcode, for dissambly. */ #define CPS 0x00 /* Clear Processor Status. */ #define ADC 0x01 /* ADd with Carry. */ #define PHP 0x08 /* PusH Processor status to stack. */ #define PHA 0x09 /* PusH Accumulator to stack. */ #define PHY 0x0A /* PusH Y register to stack. */ -#define PAY 0x0B /* Push Accumulator, and Y register to stack. */ #define PHX 0x0C /* PusH X register to stack. */ -#define PAX 0x0D /* Push Accumulator, and X register to stack. */ #define JMP 0x10 /* JuMP to memory location. */ #define SBC 0x11 /* SuBtract with Carry. */ #define PLP 0x18 /* PuLl Processor status from stack. */ #define PLA 0x19 /* PuLl Accumulator from stack. */ #define PLY 0x1A /* PuLl Y register from stack. */ -#define PYA 0x1B /* Pull Y register, and Accumulator from stack. */ #define PLX 0x1C /* PuLl X register from stack. */ -#define PXA 0x1D /* Pull X register, and Accumulator from stack. */ #define JSR 0x20 /* Jump to SubRoutine. */ #define AND 0x21 /* bitwise AND with accumulator. */ #define ANY 0x22 /* bitwise ANd with Y register.*/ @@ -37,11 +38,17 @@ #define XAX 0x45 /* bitwise Xor with Accumulator, and X register. */ #define CLI 0x48 /* CLear Interupt flag. */ #define BCS 0x50 /* Branch if Carry Set. */ -#define SLA 0x51 /* Shift Left with Accumulator. */ +#define LSL 0x51 /* Logical Shift Left. */ #define SEC 0x58 /* SEt Carry flag. */ #define BCC 0x60 /* Branch if Carry Clear. */ -#define SRA 0x61 /* Shift Right with Accumulator. */ +#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. */ @@ -72,107 +79,207 @@ #define DAY 0xD3 /* Decrement Accumulator, and Y register. */ #define DEX 0xD4 /* DEcrement X register. */ #define DAX 0xD5 /* Decrement Accumulator, and X register. */ -#define LDA 0xE1 /* LoaD Accumulator. */ -#define LDY 0xE2 /* LoaD Y register. */ -#define LAY 0xE3 /* Load Accumulator, and Y register. */ -#define LDX 0xE4 /* LoaD X register. */ -#define LAX 0xE5 /* Load Accumulator, and X register. */ #define NOP 0xE8 /* No OPeration. */ -#define STA 0xF1 /* STore Accumulator. */ -#define STY 0xF2 /* STore Y register. */ -#define SAY 0xF3 /* Store Accumulator, and Y register. */ -#define STX 0xF4 /* STore X register. */ -#define SAX 0xF5 /* Store Accumulator, and X register. */ #define BRK 0xF8 /* BReaK. */ -#define STP 0xFF /* SToP. */ -enum {ALU, THREAD, BRANCH, FLAG, MEMORY, MISC}; +#define C ((uint64_t)1 << 0) +#define Z ((uint64_t)1 << 1) +#define I ((uint64_t)1 << 2) +#define S ((uint64_t)1 << 3) +#define V ((uint64_t)1 << 6) +#define N ((uint64_t)1 << 7) + +#define STK_STADDR 0x010000 /* Starting address of the stack. */ + +struct sux; + +uint8_t *addr; /* Address Space. */ + +struct sux { + uint64_t ps; /* The processor status register. */ + uint64_t a[8], y[8], x[8]; /* Registers A, X, and Y. */ + uint64_t pc[8]; /* Program counter. */ + uint16_t sp; /* Stack pointer. */ + uint8_t crt; /* Current running threads. */ + uint8_t c[8], z[8], i[8], s[8], v[8], n[8]; /* Processor Status Flags. */ + +}; static const char *opname[0x100] = { OPNAME(CPS), - OPNAME(ADC), + [ADC] = "ADC #", + [0x03] = "ADC a", + [0x05] = "ADC zm", OPNAME(PHP), OPNAME(PHA), OPNAME(PHY), - OPNAME(PAY), OPNAME(PHX), - OPNAME(PAX), OPNAME(JMP), - OPNAME(SBC), + [SBC] = "SBC #", + [0x13] = "SBC a", + [0x15] = "SBC zm", OPNAME(PLP), OPNAME(PLA), OPNAME(PLY), - OPNAME(PYA), OPNAME(PLX), - OPNAME(PXA), OPNAME(JSR), - OPNAME(AND), - OPNAME(ANY), + [AND] = "AND #", + [ANY] = "ANY #", OPNAME(AAY), - OPNAME(ANX), + [ANX] = "ANX #", OPNAME(AAX), OPNAME(STT), + [0x29] = "AND a", + [0x2B] = "AND zm", OPNAME(BPO), - OPNAME(ORA), - OPNAME(ORY), + [ORA] = "ORA #", + [ORY] = "ORY #", OPNAME(OAY), - OPNAME(ORX), + [ORX] = "ORX #", OPNAME(OAX), OPNAME(SEI), + [0x39] = "ORA a", + [0x3B] = "ORA zm", OPNAME(BNG), - OPNAME(XOR), - OPNAME(XRY), + [XOR] = "XOR #", + [XRY] = "XRY #", OPNAME(XAY), - OPNAME(XRX), + [XRX] = "XRX #", OPNAME(XAX), OPNAME(CLI), + [0x49] = "XOR a", + [0x4B] = "XOR zm", OPNAME(BCS), - OPNAME(SLA), + [LSL] = "LSL #", + [0x52] = "ANY a", + [0x53] = "LSL a", + [0x54] = "ANX a", + [0x55] = "LSL zm", OPNAME(SEC), + [0x59] = "LDA a", + [0x5A] = "LDY a", + [0x5B] = "STA a", + [0x5C] = "LDX a", + [0x5D] = "STY a", + [0x5E] = "STX a", OPNAME(BCC), - OPNAME(SRA), + [LSR] = "LSR #", + [0x62] = "ORY a", + [0x63] = "LSR a", + [0x64] = "ORX a", + [0x65] = "LSR zm", OPNAME(CLC), + [LDA]= "LDA #", + [LDY]= "LDY #", + [STA]= "STA #", + [LDX]= "LDX #", + [STY]= "STY #", + [STX]= "STX #", OPNAME(BEQ), - OPNAME(ROL), + [ROL] = "ROL #", + [0x72] = "XRY a", + [0x73] = "ROL a", + [0x74] = "XRX a", + [0x75] = "ROL zm", OPNAME(SSP), + [0x79] = "LDA zm", + [0x7A] = "LDY zm", + [0x7B] = "STA zm", + [0x7C] = "LDX zm", + [0x7D] = "STY zm", + [0x7E] = "STX zm", OPNAME(BNE), - OPNAME(ROR), + [ROR] = "ROR #", + [0x82] = "ANY zm", + [0x83] = "ROR a", + [0x84] = "ANX zm", + [0x85] = "ROR zm", OPNAME(CSP), + [0x89] = "LDA zm, x", + [0x8A] = "LDY zm, x", + [0x8B] = "STA zm, x", + [0x8D] = "STY zm, x", OPNAME(BVS), - OPNAME(MUL), + [MUL] = "MUL #", + [0x92] = "ORY zm", + [0x93] = "MUL a", + [0x94] = "ORX zm", + [0x95] = "MUL zm", OPNAME(SEV), + [0x99] = "LDA zm, y", + [0x9B] = "LDX zm, y", + [0x9C] = "STA zm, y", + [0x9E] = "STX zm, y", OPNAME(BVC), - OPNAME(DIV), + [DIV] = "DIV #", + [0xA2] = "XRY zm", + [0xA3] = "DIV a", + [0xA4] = "XRX zm", + [0xA5] = "DIV zm", OPNAME(CLV), OPNAME(RTS), - OPNAME(CMP), - OPNAME(CPY), + [CMP] = "CMP #", + [CPY] = "CPY #", OPNAME(CAY), - OPNAME(CPX), + [CPX] = "CPX #", OPNAME(CAX), OPNAME(ENT), OPNAME(RTI), - OPNAME(INC), + [INC] = "INC #", OPNAME(INY), OPNAME(IAY), OPNAME(INX), OPNAME(IAX), - OPNAME(DEC), + [DEC] = "DEC #", OPNAME(DEY), OPNAME(DAY), OPNAME(DEX), OPNAME(DAX), - OPNAME(LDA), - OPNAME(LDY), - OPNAME(LAY), - OPNAME(LDX), - OPNAME(LAX), + [0xE1] = "INC a", + [0xE2] = "CPY a", + [0xE3] = "INC zm", + [0xE4] = "CPX a", + [0xE5] = "CMP a", OPNAME(NOP), - OPNAME(STA), - OPNAME(STY), - OPNAME(SAY), - OPNAME(STX), - OPNAME(SAX), + [0xF1] = "DEC a", + [0xF2] = "CPY zm", + [0xF3] = "DEC zm", + [0xF4] = "CPX zm", + [0xF4] = "CMP zm", OPNAME(BRK), - OPNAME(STP), }; + +extern void adc(struct sux *cpu, uint64_t adr, uint8_t thread); +extern void sbc(struct sux *cpu, uint64_t adr, uint8_t thread); +extern void mul(struct sux *cpu, uint64_t adr, uint8_t thread); +extern void divd(struct sux *cpu, uint64_t adr, uint8_t thread); +extern uint64_t and(struct sux *cpu, uint64_t value, uint8_t thread); +extern void and_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread); +extern uint64_t or(struct sux *cpu, uint64_t value, uint8_t thread); +extern void or_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread); +extern uint64_t xor(struct sux *cpu, uint64_t value, uint8_t thread); +extern void xor_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread); +extern void rol(struct sux *cpu, uint64_t adr, uint8_t thread); +extern void ror(struct sux *cpu, uint64_t adr, uint8_t thread); +extern void lsl(struct sux *cpu, uint64_t adr, uint8_t thread); +extern void lsr(struct sux *cpu, uint64_t adr, uint8_t thread); +extern void inc(struct sux *cpu, uint64_t *reg, uint8_t thread); +extern void inc_addr(struct sux *cpu, uint64_t adr, uint8_t thread); +extern void dec(struct sux *cpu, uint64_t *reg, uint8_t thread); +extern void dec_addr(struct sux *cpu, uint64_t adr, uint8_t thread); +extern void stt(struct sux *cpu, uint8_t value); +extern void ent(struct sux *cpu, uint8_t value); +extern void ld(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread); +extern void st(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread); +extern void push(struct sux *cpu, uint8_t value); +extern uint8_t pull(struct sux *cpu); +extern void cmp_addr(struct sux *cpu, uint64_t reg, uint64_t adr, uint8_t thread); +extern void cmp(struct sux *cpu, uint64_t reg1, uint64_t reg2, uint8_t thread); +extern void bfs(struct sux *cpu, uint8_t flag, uint64_t adr, uint8_t thread); +extern void bfc(struct sux *cpu, uint8_t flag, uint64_t adr, uint8_t thread); +extern void setps(struct sux *cpu, uint8_t thread); +extern uint64_t immaddr(struct sux *cpu, uint8_t thread, uint8_t size); +extern uint64_t absaddr(struct sux *cpu, uint8_t thread); +extern uint32_t zeromtx(struct sux *cpu, uint8_t thread); +extern uint32_t zeromx(struct sux *cpu, uint8_t thread); +extern uint32_t zeromy(struct sux *cpu, uint8_t thread); @@ -1,681 +1,318 @@ #include "opcode.h" -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#define C (1 << 0) -#define Z (1 << 1) -#define I (1 << 2) -#define S (1 << 3) -#define V (1 << 6) -#define N (1 << 7) -#define STK_STADDR 0x010000 /* Starting address of the stack. */ -uint8_t *addr; /* Address Space. */ -uint8_t update_pc = 1; /* Update the program counter. */ -uint16_t sp = 0xFFFF; /* Stack pointer. */ -uint64_t a[8]; /* Accumulator. */ -uint64_t y[8]; /* Y index. */ -uint64_t x[8]; /* X index. */ -uint8_t crt; /* Current Running Threads. */ -uint64_t pc[8]; /* Program counter. */ -uint64_t ps; /* Processor status. */ - -int optype(uint8_t opcode) { - switch (opcode) { - /* ALU instructions. */ - case ADC: - case SBC: - case MUL: - case DIV: - case AND: - case AAY: - case AAX: - case ANY: - case ANX: - case ORA: - case OAY: - case OAX: - case ORY: - case ORX: - case XOR: - case XAY: - case XAX: - case XRY: - case XRX: - case SLA: - case SRA: - case ROL: - case ROR: - case INC: - case IAY: - case IAX: - case INY: - case INX: - case DEC: - case DAY: - case DAX: - case DEY: - case DEX: - return ALU; - /* Thread instructions. */ - case STT: - case ENT: - return THREAD; - /* Branching instructions. */ - case JMP: - case JSR: - case RTS: - case BPO: - case BNG: - case BEQ: - case BNE: - case BCS: - case BCC: - case BVS: - case BVC: - case CMP: - case CAY: - case CAX: - case CPY: - case CPX: - return BRANCH; - /* Processor status instructions. */ - case CPS: - case SEI: - case CLI: - case SEC: - case CLC: - case SSP: - case CSP: - case SEV: - case CLV: - return FLAG; - /* Memory based instructions. */ - case LDA: /* LDA, imm */ - case LDY: /* LDY, imm */ - case LAY: /* LAY, imm */ - case LDX: /* LDX, imm */ - case LAX: /* LAX, imm */ - case 0x59: /* LDA, abs */ - case 0x52: /* LDY, abs */ - case 0x53: /* LAY, abs */ - case 0x54: /* LDX, abs */ - case 0x55: /* LAX, abs */ - case STA: - case SAY: - case SAX: - case STY: - case STX: - case PHP: - case PHA: - case PAY: - case PAX: - case PHY: - case PHX: - case PLP: - case PLA: - case PYA: - case PXA: - case PLY: - case PLX: - return MEMORY; - /* Misc intructions. */ - case NOP: - case BRK: - return MISC; - default: - return -1; - } -} - -uint64_t rol(uint64_t a, uint64_t value) { - const uint64_t mask = 8 * sizeof(a) - 1; - value &= mask; - return (a << value) | (a >> (-value & mask)); -} - -uint64_t ror(uint64_t a, uint64_t value) { - const uint64_t mask = 8 * sizeof(a) - 1; - value &= mask; - return (a >> value) | (a << (-value & mask)); -} - -/*int push(uint64_t value, uint8_t size) { - for (uint8_t i = 0; i < size; i++) { - addr[STK_STADDR+sp] = value >> 8*i; - sp--; - } - return 1; -}*/ - -/*uint64_t pull(uint8_t size) { - uint64_t value; - for (uint8_t i = 0; i < size; i++) { - sp++; - if (i == 0) - value = (addr[STK_STADDR+sp]); - else - value |= (addr[STK_STADDR+sp] << (8*i)); - } - return value; -}*/ - - - -void push(uint8_t value) { - addr[STK_STADDR+sp] = value; - sp--; -} - -uint8_t pull() { - sp++; - return addr[STK_STADDR+sp]; -} - -int alu(uint8_t opcode, uint64_t value, uint8_t thread) { - uint64_t sum; - uint8_t c = 0; /* Carry flag. */ - uint8_t v = 0; /* Overflow flag. */ - uint8_t z = 0; /* Zero flag. */ - uint8_t n = 0; /* Negative flag. */ +int run(struct sux *cpu, uint8_t opcode, uint8_t thread) { + uint64_t address; + 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" + , cpu->pc[thread], cpu->a[thread], cpu->x[thread], cpu->y[thread] + , cpu->sp, cpu->c[thread], opcode, opname[opcode]); + cpu->pc[thread]++; switch(opcode) { - /* Add with carry. */ - case ADC: - c = (ps & (1 << thread)) >> thread; - sum = a[thread]+value+c; - v = !((a[thread]^value) & 0x8000000000000000) && ((a[thread]^sum) & 0x8000000000000000); - c = (sum < value); - a[thread] = sum; - break; - /* Subtract with carry. */ - case SBC: - c = !(ps & (1 << thread)); - sum = a[thread]-value-c; - v = ((a[thread]^value) & 0x8000000000000000) && ((a[thread]^sum) & 0x8000000000000000); - c = (sum > value); - a[thread] = sum; - break; - /* Multiply with accumulator. */ - case MUL: - c = (ps & (1 << thread)) >> thread; - sum = a[thread]*value+c; - v = !((a[thread]^value) & 0x8000000000000000) && ((a[thread]^sum) & 0x8000000000000000); - c = (!((a[thread]^sum) && (a[thread]^value)) || (a[thread] >= ((uint64_t)1 << 32) && value >= ((uint64_t)1 << 32))); - a[thread] = sum; - break; - /* Divide with accumulator. */ - case DIV: - sum = a[thread]/value; - v = ((a[thread]^value) & 0x8000000000000000) && ((a[thread]^sum) & 0x8000000000000000); - a[thread] = sum; - break; - /* Bitwise AND. */ - case AND: - case AAY: - case AAX: - a[thread] &= value; - if (opcode == AAY) - y[thread] &= value; - if (opcode == AAX) - x[thread] &= value; - break; - case ANY: - y[thread] &= value; - break; - case ANX: - x[thread] &= value; - break; - /* Bitwise OR. */ - case ORA: - case OAY: - case OAX: - a[thread] |= value; - if (opcode == OAY) - y[thread] |= value; - if (opcode == OAX) - x[thread] |= value; - break; - case ORY: - y[thread] |= value; - break; - case ORX: - x[thread] |= value; - break; - /* Bitwise Exclusive OR. */ - case XOR: - case XAY: - case XAX: - a[thread] ^= value; - if (opcode == XAY) - y[thread] ^= value; - if (opcode == XAX) - x[thread] ^= value; - break; - case XRY: - y[thread] ^= value; - break; - case XRX: - x[thread] ^= value; - break; - /* Shift accumulator left. */ - case SLA: - sum = (value < 64) ? a[thread] << value : 0; - c = a[thread] >> 64-value; - a[thread] = sum; - break; - /* Shift accumulator right. */ - case SRA: - sum = (value < 64) ? a[thread] >> value : 0; - c = a[thread] & 1; - a[thread] = sum; - break; - /* Rotate accumulator left. */ - case ROL: - c = (ps & (1 << thread)) >> thread; - sum = a[thread] << value; - sum |= c; - c = a[thread] >> (uint64_t)64-value; - a[thread] = sum; - break; - /* Rotate accumulator right. */ - case ROR: - c = (ps & (1 << thread)) >> thread; - sum = a[thread] >> value; - sum |= (uint64_t)c << (uint64_t)64-value; - c = a[thread] & 1; - a[thread] = sum; - break; - /* Increment accumulator. */ - case INC: - case IAY: - case IAX: - a[thread]++; - if (opcode == IAY) - y[thread]++; - if (opcode == IAX) - x[thread]++; - break; - /* Increment y register. */ - case INY: - y[thread]++; - break; - /* Increment x register. */ - case INX: - x[thread]++; - break; - /* Decrement accumulator. */ - case DEC: - case DAY: - case DAX: - a[thread]--; - if (opcode == DAY) - y[thread]--; - if (opcode == DAX) - x[thread]--; - break; - /* Decrement y register. */ - case DEY: - y[thread]--; - break; - /* Decrement y register. */ - case DEX: - x[thread]--; - break; - default: - /*printf("Cool, you inputed a non existent opcode, which means\n" - "that you have now wasted clock cycles.\n" - "Good job! *clap*\n");*/ - break; - } - z = (a[thread] == 0); - n = (a[thread] >> 63); - ps = (n) ? (ps | (uint64_t)N << 8*thread) : (ps & ~((uint64_t)N << 8*thread)); - ps = (v) ? (ps | (uint64_t)V << 8*thread) : (ps & ~((uint64_t)V << 8*thread)); - ps = (z) ? (ps | (uint64_t)Z << 8*thread) : (ps & ~((uint64_t)Z << 8*thread)); - ps = (c) ? (ps | (uint64_t)C << 8*thread) : (ps & ~((uint64_t)C << 8*thread)); - return 1; -} - -int threads(uint8_t opcode, uint64_t value) { - uint8_t t = value & 0xFF; /* This tells the CPU, which threads to start, or end. */ - switch(opcode) { - /* Start Thread. */ - case STT: - crt |= t; - for (uint8_t i = 0; i < 7; i++) - if ((t >> i) & 1) - pc[i] = value >> 8; - break; - /* End Thread. */ - case ENT: - crt &= ~t; - for (uint8_t i = 0; i < 7; i++) - if ((t >> i) & 1) - pc[i] = 0; - break; - } - return 1; -} - -int branch(uint8_t opcode, uint64_t value, uint8_t thread) { - uint64_t dif; - switch (opcode) { - /* Jump. */ - case JMP: - pc[thread] = value; - break; - /* Jump to subroutine. */ - case JSR: - /*push(pc[thread], 8);*/ - pc[thread] = value; - break; - /* Return from subroutine. */ - case RTS: - /*pc[thread] = pull(8);*/ - break; - /* Branch if positive. */ - case BPO: - if (!(ps & ((uint64_t)N << 8*thread))) - pc[thread] = value; - else - pc[thread]+=0; - break; - /* Branch if negative. */ - case BNG: - if (ps & ((uint64_t)N << 8*thread)) - pc[thread] = value; - else - pc[thread]+=0; - break; - /* Branch if equal. */ - case BEQ: - if (ps & ((uint64_t)Z << 8*thread)) - pc[thread] = value; - else - pc[thread]+=0; - break; - /* Branch if not equal. */ - case BNE: - if (!(ps & ((uint64_t)Z << 8*thread))) - pc[thread] = value; - else - pc[thread]+=0; - break; - /* Branch if carry set. */ - case BCS: - if (ps & ((uint64_t)C << 8*thread)) - pc[thread] = value; - else - pc[thread]+=0; - break; - /* Branch if carry clear. */ - case BCC: - if (!(ps & ((uint64_t)C << 8*thread))) - pc[thread] = value; - else - pc[thread]+=0; - break; - /* Branch if overflow set. */ - case BVS: - if (ps & ((uint64_t)V << 8*thread)) - pc[thread] = value; - else - pc[thread]+=0; - break; - /* Branch if overflow clear. */ - case BVC: - if (!(ps & ((uint64_t)V << 8*thread))) - pc[thread] = value; - else - pc[thread]+=0; - break; - /* Compare accumulator. */ - case CMP: - case CAY: - case CAX: - if (opcode == CAY || opcode == CAX) { - dif = (opcode == CAY) ? a[thread]-y[thread] : a[thread]-x[thread]; - value = a[thread]; - } else { - dif = value-a[thread]; + 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; } - ps = (dif & 0x8000000000000000) ? (ps | (uint64_t)N << 8*thread) : (ps & ~((uint64_t)N << 8*thread)); - ps = (dif == 0) ? (ps | (uint64_t)Z << 8*thread) : (ps & ~((uint64_t)Z << 8*thread)); - ps = (dif > value) ? (ps | (uint64_t)C << 8*thread) : (ps & ~((uint64_t)C << 8*thread)); - break; - /* Compare y register. */ - case CPY: - dif = value-y[thread]; - ps = (dif & 0x8000000000000000) ? (ps | (uint64_t)N << 8*thread) : (ps & ~((uint64_t)N << 8*thread)); - ps = (dif == 0) ? (ps | (uint64_t)Z << 8*thread) : (ps & ~((uint64_t)Z << 8*thread)); - ps = (dif > value) ? (ps | (uint64_t)C << 8*thread) : (ps & ~((uint64_t)C << 8*thread)); - break; - /* Compare x register. */ - case CPX: - dif = value-x[thread]; - ps = (dif & 0x8000000000000000) ? (ps | (uint64_t)N << 8*thread) : (ps & ~((uint64_t)N << 8*thread)); - ps = (dif == 0) ? (ps | (uint64_t)Z << 8*thread) : (ps & ~((uint64_t)Z << 8*thread)); - ps = (dif > value) ? (ps | (uint64_t)C << 8*thread) : (ps & ~((uint64_t)C << 8*thread)); - break; - } - return 1; -} - -int setflags(uint8_t opcode, uint8_t thread) { - switch (opcode) { - /* Clear processor status. */ - case CPS: - ps &= 0; - break; - /* Set interupt flag. */ - case SEI: - ps |= ((uint64_t)I << 8*thread); - break; - /* Clear interupt flag. */ - case CLI: - ps &= ~((uint64_t)I << 8*thread); - break; - /* Set carry flag. */ - case SEC: - ps |= ((uint64_t)C << 8*thread); - break; - /* Clear carry flag. */ - case CLC: - ps &= ~((uint64_t)C << 8*thread); - break; - /* Set stack protection flag. */ - case SSP: - ps |= ((uint64_t)S << 8*thread); - break; - /* Clear stack protection flag. */ - case CSP: - ps &= ~((uint64_t)S << 8*thread); - break; - /* Set overflow flag. */ - case SEV: - ps |= ((uint64_t)V << 8*thread); - break; - /* Clear overflow flag. */ - case CLV: - ps &= ~((uint64_t)V << 8*thread); - break; - } - return 1; -} - -int memory(uint8_t opcode, uint64_t value, uint8_t thread) { - switch (opcode) { - /* Load value. */ - case LDA: /* LDA, imm */ - case LDY: /* LDY, imm */ - case LAY: /* LAY, imm */ - case LDX: /* LDX, imm */ - case LAX: /* LAX, imm */ - case 0x95: /* LDA, abs */ - case 0x25: /* LDY, abs */ - case 0x35: /* LAY, abs */ - case 0x45: /* LDX, abs */ - case 0x55: /* LAX, abs */ - if (opcode == LDA || opcode == LAY || opcode == LAX) - a[thread] = value; - else if (opcode == 0x95 || opcode == 0x35 || opcode == 0x55) - a[thread] = addr[value]; - if (opcode == LAY || opcode == LDY) - y[thread] = value; - else if (opcode == 0x35) - y[thread] = addr[value]; - if (opcode == LAX) - x[thread] = value; - else if (opcode == 0x55) - x[thread] = addr[value]; - break; - /* Store value. */ - case STA: - case SAY: - case SAX: - addr[value] = a[thread]; - if (opcode == SAY) - addr[value] = y[thread]; - if (opcode == SAX) - addr[value] = x[thread]; - break; - case STY: - addr[value] = y[thread]; - break; - case STX: - addr[value] = x[thread]; - break; - /* Push processor status. */ - case PHP: - /*push(ps, value);*/ - break; - /* Push accumulator. */ - case PHA: - case PAY: - case PAX: - if (value > 7) - value = 7; - for (int8_t i = 8*value; i > 0; i-=8) { - push(a[thread] >> i); + 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 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(a[thread] & 0xFF); - if (opcode == PAY) { - if (value > 7) - value = 7; - for (int8_t i = 8*value; i > 0; i-=8) { - push(y[thread] >> i); - } - push(y[thread] & 0xFF); + 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); } - if (opcode == PAX) { - if (value > 7) - value = 7; - for (int8_t i = 8*value; i > 0; i-=8) { - push(x[thread] >> i); - } - push(x[thread] & 0xFF); + 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); } - break; - case PHY: - if (value > 7) - value = 7; - for (int8_t i = 8*value; i > 0; i-=8) { - push(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(y[thread] & 0xFF); - /*for (uint8_t i = value-1; i > 0; i--) - push(y[thread] >> 8*i);*/ - break; - case PHX: - if (value > 7) - value = 7; - for (int8_t i = 8*value; i > 0; i-=8) { - push(x[thread] >> i); + push(cpu, cpu->x[thread] & 0xFF); + break; + case JMP: /* JuMP to memory location. */ + 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 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; } - push(x[thread] & 0xFF); - /*for (uint8_t i = value-1; i > 0; i--) - push(x[thread] >> 8*i);*/ - break; - /* Pull processor status. */ - case PLP: - /*ps = pull(value);*/ break; - /* Pull accumulator. */ - case PLA: - case PYA: - case PXA: - if (value > 7) - value = 7; - for (uint8_t i = 0; i <= 8*value; i+=8) { + 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) - a[thread] = (uint64_t)pull(); + cpu->a[thread] = (uint64_t)pull(cpu); else - a[thread] += (uint64_t)pull() << i; - } - if (opcode == PAY) { - if (value > 7) - value = 7; - for (uint8_t i = 0; i <= 8*value; i+=8) { - if (!i) - y[thread] = (uint64_t)pull(); - else - y[thread] += (uint64_t)pull() << i; - } - } - if (opcode == PAX) { - if (value > 7) - value = 7; - for (uint8_t i = 0; i <= 8*value; i+=8) { - if (!i) - x[thread] = (uint64_t)pull(); - else - x[thread] += (uint64_t)pull() << i; - } + cpu->a[thread] += (uint64_t)pull(cpu) << i; } break; - /* Pull y register. */ - case PLY: - if (value > 7) - value = 7; - for (uint8_t i = 0; i <= 8*value; i+=8) { + 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) - y[thread] = (uint64_t)pull(); + cpu->y[thread] = (uint64_t)pull(cpu); else - y[thread] += (uint64_t)pull() << i; + cpu->y[thread] += (uint64_t)pull(cpu) << i; } break; - /* Pull x register. */ - case PLX: - if (value > 7) - value = 7; - for (uint8_t i = 0; i <= 8*value; i+=8) { + 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) - x[thread] = (uint64_t)pull(); + cpu->x[thread] = (uint64_t)pull(cpu); else - x[thread] += (uint64_t)pull() << i; + cpu->x[thread] += (uint64_t)pull(cpu) << i; } break; - } - return 1; -} - -int misc(uint8_t opcode, uint8_t thread) { - switch (opcode) { - /* No operation. */ - case NOP: - break; - /* TODO: Implement interupts. */ - case BRK: + 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 + | (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 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 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 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 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 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 OAX: cpu->a[thread] = or(cpu, cpu->x[thread], thread); break; + 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. */ + 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 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 XAX: cpu->a[thread] = xor(cpu, cpu->x[thread], thread); break; + 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. */ + 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 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 0x55: lsl(cpu, zeromtx(cpu, thread), thread); break; /* LSL Zero Matrix. */ + 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 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 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 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 0x65: lsr(cpu, zeromtx(cpu, thread), thread); break; /* LSR Zero Matrix. */ + 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. */ + 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 0x75: rol(cpu, zeromtx(cpu, thread), thread); break; /* ROL Zero Matrix. */ + 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. */ + 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 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 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 0x85: ror(cpu, zeromtx(cpu, thread), thread); break; /* ROR Zero Matrix. */ + 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. */ + 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 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 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. */ + 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 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 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); + 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 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 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 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 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 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 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 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 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. */ + default: + 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) { - a[0] = 0; - x[0] = 0; - y[0] = 0; + 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; @@ -706,111 +343,52 @@ int main(int argc, char **argv) { /*addr[0x8018] = 0x01; addr[0x8019] = 0x80; addr[0xFFFC] = 0x00; - addr[0xFFFD] = 0x80; - - /*addr[0x8000] = 0x00; CPS */ - /*addr[0x8001] = 0xE1; /* LDA #$01 */ - /*addr[0x8002] = 0xFF; - addr[0x8003] = 0x51; /* SLA #$3C */ - /*addr[0x8004] = 0x38; - addr[0x8005] = 0x01; /* ADC #$02 */ - /*addr[0x8006] = 0x02; - addr[0x8007] = 0x81; /* ROR #$04 */ - /*addr[0x8008] = 0x04; - addr[0x8009] = 0x10; /* JMP $8007 */ - /*addr[0x800A] = 0x07; - addr[0x800B] = 0x80; - addr[0x800C] = 0x10; /* JMP $8001 */ - /*addr[0x800D] = 0x01; - addr[0x800E] = 0x80; - /*addr[0x8008] = 0x70; BEQ $800E */ - /*addr[0x8009] = 0x0E; - addr[0x800A] = 0x80; - addr[0x800B] = 0x10; JMP $8001 - addr[0x800C] = 0x01; - addr[0x800D] = 0x80; - addr[0x800E] = 0xC1; INC - addr[0x800F] = 0xE8; - addr[0x8010] = 0x04; - addr[0x8011] = 0x50; - addr[0x8012] = 0x17; - addr[0x8013] = 0x80; - addr[0x8014] = 0x10; - addr[0x8015] = 0x0F; - addr[0x8016] = 0x80; - addr[0x8017] = 0x10; - addr[0x8018] = 0x01; - addr[0x8019] = 0x80;*/ - + addr[0xFFFD] = 0x80;*/ addr[0x8000] = 0x00; /* CPS */ - addr[0x8001] = 0xC1; /* INC */ - addr[0x8002] = 0x09; /* PHA #$08 */ - addr[0x8003] = 0x08; - addr[0x8004] = 0x1C; /* PLX #$08 */ - addr[0x8005] = 0x08; - addr[0x8006] = 0x10; /* JMP $8001 */ - addr[0x8007] = 0x01; - addr[0x8008] = 0x80; + addr[0x8001] = 0xC5; /* IAX */ + addr[0x8002] = 0x10; /* JMP $8001 */ + addr[0x8003] = 0x01; + addr[0x8004] = 0x80; + addr[0x8005] = 0x00; + addr[0x8006] = 0x00; + addr[0x8007] = 0x00; + addr[0x8008] = 0x00; addr[0x8009] = 0x00; addr[0x800A] = 0x00; - addr[0x800B] = 0x00; - addr[0xFFFC] = 0x00; - addr[0xFFFD] = 0x80; + addr[0xFFC0] = 0x00; + addr[0xFFC1] = 0x80; + addr[0xFFC2] = 0x00; + addr[0xFFC3] = 0x00; + addr[0xFFD0] = 0x00; + addr[0xFFD1] = 0x00; + addr[0xFFD2] = 0x00; + addr[0xFFD3] = 0x00; - pc[0] = addr[0xFFFC] | (addr[0xFFFD] << 8); - uint64_t value = 0; + 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 inst = 0; uint8_t lines = 2; - uint8_t end = 0; uint8_t opcode = 0; - uint8_t size; + uint8_t end = 0; printf("\033[2J"); while (!end) { - /*printf("pc: 0x%04llx, a: 0x%016llx, carry: %u, inst: %s, value: 0x%04llx, $%04llx: %02x\n", pc[0], a[0], ps & 1, opname[opcode], value, value, addr[value]);*/ - opcode = addr[pc[0]]; - if (opcode == STA || opcode == JMP || opcode == BCS) - size = 2; - else if (opcode == CPS || opcode == NOP || opcode == INC || opcode == IAX || opcode == CAX) - size = 0; - else if (opcode == STP) - end = 1, size = 0; - else - size = 1; - pc[0]++; - if (size) { - int i = 0; - while (i < size) { - if (!i) - value = (addr[pc[0]]); - else - value |= (addr[pc[0]] << (8*i)); - /*printf("pc: 0x%04llx, a: 0x%016llx, carry: %u, inst: %s, value: 0x%04llx, $%04llx: %02x\n", pc[0], a[0], ps & 1, opname[opcode], value, value, addr[value]);*/ - pc[0]++; - i++; - } - } - if (optype(opcode) == ALU) - alu(opcode, value, 0); - if (optype(opcode) == THREAD) - threads(opcode, value); - if (optype(opcode) == BRANCH) - branch(opcode, value, 0); - if (optype(opcode) == MEMORY) - memory(opcode, value, 0); - if (optype(opcode) == FLAG) - setflags(opcode, 0); - if (optype(opcode) == MISC) - misc(opcode, 0); + opcode = addr[cpu.pc[0]]; + printf("\033[%uH\033[2K", lines); + lines++; + run(&cpu, opcode, 0); if (lines > 50) lines = 2; - printf("\033[%uHpc: 0x%04llx, a: 0x%016llx, x: 0x%016llx, y: 0x%016llx, sp: 0x%04lx, carry: %u, inst: %s, value: 0x%04llx, $%04llx: %02x\n", lines, pc[0], a[0], x[0], y[0], sp, ps & 1, opname[opcode], value, value, addr[value]); - lines++; - printf("\033[1HInstructions executed: %llu\n", inst++); + printf("\033[HInstructions executed: %llu\n", inst++); } free(addr); return 0; - } |