summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2019-11-26 00:33:20 -0500
committermrb0nk500 <b0nk@b0nk.xyz>2019-11-26 00:33:20 -0500
commitc1e735ec8b0481c1ebc631cd495a10f72e47ba32 (patch)
treee43331c872a35790e070ad2daded086a5ef6f8c7
parent988c81ae76ab0da47db8938c14865d6e5b3a8024 (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--Makefile24
-rw-r--r--opcode.c358
-rw-r--r--opcode.h217
-rw-r--r--sux.c1058
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;
+}
diff --git a/opcode.h b/opcode.h
index f634be3..cf93a16 100644
--- a/opcode.h
+++ b/opcode.h
@@ -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);
diff --git a/sux.c b/sux.c
index c202d6c..c1a7003 100644
--- a/sux.c
+++ b/sux.c
@@ -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;
-
}