summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2019-11-30 19:57:46 -0500
committermrb0nk500 <b0nk@b0nk.xyz>2019-11-30 19:57:46 -0500
commitca89989d057a19b647514656d96d00ff23be9640 (patch)
tree1259b343d60680a4354a1a54b90d0d7418af770b
parent10ec62e8025eb43d1a096fb0962049670c3c148c (diff)
Start work on rev2 of Sux.
Added a prefix byte to tell the CPU certain information such as, how many bytes to load into the registers, or what ISA extension we want to use. I also added an assembly language monitor, so that I don't have to write stuff in machine code.
-rw-r--r--Makefile4
-rw-r--r--asmmon.c359
-rw-r--r--opcode.c241
-rw-r--r--opcode.h37
-rw-r--r--sux.c362
-rw-r--r--test/test.s13
6 files changed, 742 insertions, 274 deletions
diff --git a/Makefile b/Makefile
index e83e8b2..df46e69 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ PCC_CFLAGS=
endif
CFLAGS = $(PCC_CFLAGS) $(CFLAGS_EXTRA)
-OBJS = opcode.o sux.o
+OBJS = asmmon.o opcode.o sux.o
OBJ_NAME = cisc-0.2
all : $(OBJS)
$(CC) $(OBJS) $(CFLAGS) -o $(OBJ_NAME)
@@ -16,6 +16,8 @@ sux.o :
$(CC) sux.c -c $(CFLAGS) -o sux.o
opcode.o :
$(CC) opcode.c -c $(CFLAGS) -o opcode.o
+asmmon.o :
+ $(CC) asmmon.c -c $(CFLAGS) -o asmmon.o
clean :
rm -f $(OBJ_NAME) $(OBJS)
install :
diff --git a/asmmon.c b/asmmon.c
new file mode 100644
index 0000000..fd7c636
--- /dev/null
+++ b/asmmon.c
@@ -0,0 +1,359 @@
+#include "opcode.h"
+#include <string.h>
+
+#define SETOP(num, _mne, _IMM, _ZM, _ZMX, _ZMY, _ABS, _IMPL) \
+{opcodes[num].mnemonic[3] = '\0'; strncpy(opcodes[num].mnemonic, _mne, 3); \
+opcodes[num].imm = _IMM; \
+opcodes[num].zm = _ZM; opcodes[num].zmx = _ZMX; opcodes[num].zmy = _ZMY; \
+opcodes[num].abs = _ABS; opcodes[num].impl = _IMPL;}
+
+int asmmon() {
+ opent opcodes[79];
+ /* mne IMM ZM ZMX ZMY ABS IMPL*/
+ SETOP(0, "CPS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(1, "ADC", 0x01, 0x05, 0x00, 0x00, 0x03, 0x00);
+ SETOP(2, "PHP", 0x08, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(3, "PHA", 0x09, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(4, "PHY", 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(5, "PHX", 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(6, "JMP", 0x00, 0xD0, 0x00, 0x00, 0x10, 0x00);
+ SETOP(7, "SBC", 0x11, 0x15, 0x00, 0x00, 0x13, 0x00);
+ SETOP(8, "PLP", 0x18, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(9, "PLA", 0x19, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(10, "PLY", 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(11, "PLX", 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(12, "JSR", 0x00, 0x20, 0x00, 0x00, 0x00, 0x00);
+ SETOP(13, "AND", 0x21, 0x2B, 0x00, 0x00, 0x29, 0x00);
+ SETOP(14, "ANY", 0x22, 0x82, 0x00, 0x00, 0x52, 0x00);
+ SETOP(15, "AAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x23);
+ SETOP(16, "ANX", 0x24, 0x84, 0x00, 0x00, 0x54, 0x00);
+ SETOP(17, "AAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x25);
+ SETOP(18, "STT", 0x28, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(19, "BPO", 0x00, 0x00, 0x00, 0x00, 0x30, 0x00);
+ SETOP(20, "ORA", 0x31, 0x3B, 0x00, 0x00, 0x39, 0x00);
+ SETOP(21, "ORY", 0x32, 0x00, 0x00, 0x00, 0x62, 0x00);
+ SETOP(22, "OAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x33);
+ SETOP(23, "ORX", 0x34, 0x94, 0x00, 0x00, 0x64, 0x00);
+ SETOP(24, "OAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x35);
+ SETOP(25, "SEI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x38);
+ SETOP(26, "BNG", 0x00, 0x00, 0x00, 0x00, 0x40, 0x00);
+ SETOP(27, "XOR", 0x41, 0x4B, 0x00, 0x00, 0x49, 0x00);
+ SETOP(28, "XRY", 0x42, 0xA2, 0x00, 0x00, 0x72, 0x00);
+ SETOP(29, "XAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x43);
+ SETOP(30, "XRX", 0x44, 0xA4, 0x00, 0x00, 0x74, 0x00);
+ SETOP(31, "XAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x45);
+ SETOP(32, "CLI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x48);
+ SETOP(33, "BCS", 0x00, 0x00, 0x00, 0x00, 0x50, 0x00);
+ SETOP(34, "LSL", 0x51, 0x55, 0x00, 0x00, 0x53, 0x00);
+ SETOP(35, "SEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x58);
+ SETOP(36, "STA", 0x00, 0x7B, 0x8B, 0x9B, 0x5B, 0x00);
+ SETOP(37, "STY", 0x00, 0x7D, 0x8D, 0x00, 0x5D, 0x00);
+ SETOP(38, "STX", 0x00, 0x7E, 0x00, 0x9E, 0x5E, 0x00);
+ SETOP(39, "BCC", 0x00, 0x00, 0x00, 0x00, 0x60, 0x00);
+ SETOP(40, "LSR", 0x61, 0x65, 0x00, 0x00, 0x63, 0x00);
+ SETOP(41, "CLC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x68);
+ SETOP(42, "LDA", 0x69, 0x79, 0x89, 0x99, 0x59, 0x00);
+ SETOP(43, "LDY", 0x6A, 0x7A, 0x8A, 0x00, 0x5A, 0x00);
+ SETOP(44, "LDX", 0x6C, 0x7C, 0x00, 0x9C, 0x5C, 0x00);
+ SETOP(45, "BEQ", 0x00, 0x00, 0x00, 0x00, 0x70, 0x00);
+ SETOP(46, "ROL", 0x71, 0x75, 0x00, 0x00, 0x73, 0x00);
+ SETOP(47, "SSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x78);
+ SETOP(48, "BNE", 0x00, 0x00, 0x00, 0x00, 0x80, 0x00);
+ SETOP(49, "ROL", 0x81, 0x85, 0x00, 0x00, 0x83, 0x00);
+ SETOP(50, "CSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x88);
+ SETOP(51, "BVS", 0x00, 0x00, 0x00, 0x00, 0x90, 0x00);
+ SETOP(52, "MUL", 0x91, 0x95, 0x00, 0x00, 0x93, 0x00);
+ SETOP(53, "SEV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x98);
+ SETOP(54, "BVC", 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00);
+ SETOP(55, "DIV", 0xA1, 0xA5, 0x00, 0x00, 0xA3, 0x00);
+ SETOP(56, "CLV", 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8);
+ SETOP(57, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0);
+ SETOP(58, "CMP", 0xB1, 0xF5, 0x00, 0x00, 0xE5, 0x00);
+ SETOP(59, "CPY", 0xB2, 0xF2, 0x00, 0x00, 0xE2, 0x00);
+ SETOP(60, "CAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB3);
+ SETOP(61, "CPX", 0xB4, 0xF4, 0x00, 0x00, 0xE4, 0x00);
+ SETOP(62, "CAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB5);
+ SETOP(63, "ENT", 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(64, "RTI", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0);
+ SETOP(65, "INC", 0x00, 0xE3, 0x00, 0x00, 0xE1, 0xC1);
+ SETOP(66, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2);
+ SETOP(67, "IAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3);
+ SETOP(68, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4);
+ SETOP(69, "IAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC5);
+ SETOP(70, "DEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1);
+ SETOP(71, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2);
+ SETOP(72, "DAY", 0x00, 0xF3, 0x00, 0x00, 0xF1, 0xD3);
+ SETOP(73, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4);
+ SETOP(74, "DAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5);
+ SETOP(75, "JSL", 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00);
+ SETOP(76, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8);
+ SETOP(77, "RTL", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0);
+ SETOP(78, "BRK", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8);
+ uint8_t done = 0;
+ uint64_t address = 0x0000;
+ while (!(done & 1)) {
+ char *buf = NULL;
+ char *ins;
+ char *postfix;
+ char mode[3];
+ opent op;
+ uint8_t addrmode = 0;
+ uint64_t value;
+ char *oprand;
+ char *cmd;
+ char *tmp = malloc(sizeof(char *)*128);
+ size_t size;
+ done &= ~6;
+ getline(&buf, &size, stdin);
+ cmd = strtok_r(buf, "\n", &tmp);
+ if (cmd != NULL) {
+ if (strcasecmp(cmd, "done") == 0) {
+ done |= 1;
+ } else {
+ ins = strtok(buf, " \n\t");
+ if (ins != NULL) {
+ oprand = strtok(NULL, "\t\n;, ");
+ strtok_r(ins, ".", &postfix);
+ }
+ if (strcasecmp(cmd, "quit") == 0 || strcasecmp(cmd, "q") == 0)
+ return 2;
+ if (strcasecmp(cmd, "viewmem") == 0) {
+ done |= 4;
+ printf("\t\t\t");
+ for (int ind = 0; ind < 0x10; ind++) {
+ printf("%02x", ind);
+ if (ind < 0x0F)
+ printf(" ");
+ }
+ printf("\n\n");
+ for (int hi = 0; hi < 0x10; hi++) {
+ printf("%016llx:\t", (address & ~0xF)+(hi*0x10));
+ for (int lo = 0; lo < 0x10; lo++) {
+ printf("%02x", addr[(address & ~0xF)+lo+(hi*0x10)]);
+ if (lo < 0x0F)
+ printf(" ");
+ }
+ printf("\n");
+ }
+ }
+ if (oprand == NULL && ins == NULL && postfix == NULL) {
+ done |= 2;
+ }
+ if (ins != NULL) {
+ for (int i = 0; i < strlen(ins); i++) {
+ if (ins[i] == ';') {
+ done |=6;
+ break;
+ }
+ }
+ if (strcasecmp(ins, ".org") == 0) {
+ done |= 6;
+ oprand = strtok(oprand, "$");
+ address = strtoull(oprand, NULL, 16);
+ printf("Origin for program code is now at address $%llx.\n", address);
+ }
+ if (strcasecmp(ins, ".byte") == 0 || strcasecmp(ins, ".word") == 0 || strcasecmp(ins, ".dword") == 0 || strcasecmp(ins, ".qword") == 0) {
+ done |= 6;
+ oprand = strtok(oprand, "$");
+ value = strtoull(oprand, NULL, 16);
+ if (strcasecmp(ins, ".byte") == 0)
+ addr[address++] = value & 0xFF;
+ if (strcasecmp(ins, ".word") == 0) {
+ addr[address] = value & 0xFF;
+ addr[address+1] = value >> 8;
+ address+=2;
+ }
+ if (strcasecmp(ins, ".dword") == 0) {
+ addr[address] = value & 0xFF;
+ addr[address+1] = value >> 8;
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ address+=4;
+ }
+ if (strcasecmp(ins, ".qword") == 0) {
+ addr[address] = value & 0xFF;
+ addr[address+1] = value >> 8;
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ addr[address+4] = value >> 32;
+ addr[address+5] = value >> 40;
+ addr[address+6] = value >> 48;
+ addr[address+7] = value >> 56;
+ address+=8;
+ }
+
+ printf("The value $%llx was placed at address $%llx.\n", value, address);
+ }
+ }
+
+ if (!(done & 2) && oprand != NULL) {
+ if (oprand[0] == '#' || oprand[0] == '$') {
+ if(oprand[0] == '#' && (oprand[1] == '$' || oprand[1] == '%')) {
+ mode[1] = oprand[1];
+ mode[2] = '\0';
+ } else {
+ mode[1] = '\0';
+ }
+ mode[0] = oprand[0];
+ oprand = strtok(oprand, "#$%");
+ if (mode[0] == '#') {
+ addrmode = 1;
+ if (mode[1] == '$')
+ value = strtoull(oprand, NULL, 16);
+ if (mode[1] == '%')
+ value = strtoull(oprand, NULL, 2);
+ }
+ if (mode[0] == '$') {
+ value = strtoull(oprand, NULL, 16);
+ if (value & 0xFFFFFFFF) {
+ addrmode = 2;
+ } else if (value & 0xFFFFFFFF00000000) {
+ addrmode = 5;
+ }
+ }
+ }
+ }
+ if (postfix != NULL && !(done & 6)) {
+ if (strcasecmp(postfix, "w") == 0) {
+ addr[address++] = 1;
+ } else if (strcasecmp(postfix, "d") == 0) {
+ addr[address++] = 2;
+ } else if (strcasecmp(postfix, "q") == 0) {
+ addr[address++] = 3;
+ } else {
+ addr[address++] = 0;
+ }
+ } else if (postfix == NULL && !(done & 6)) {
+ addr[address++] = 0;
+ }
+ if (ins != NULL && !(done & 6)) {
+ uint8_t i;
+ for (i = 0; i < 77; i++) {
+ if (strcasecmp(opcodes[i].mnemonic, ins) == 0) {
+ op = opcodes[i];
+ break;
+ }
+ }
+ uint8_t r = addr[address-1] & 3;
+ switch (addrmode) {
+ case 0:
+ if (op.impl || op.impl == CPS) {
+ addr[address++] = op.impl;
+ break;
+ } else {
+ fprintf(stderr, "oof, %s requires an operand.\n", op.mnemonic);
+ }
+ break;
+ case 1:
+ if (op.imm) {
+ addr[address++] = op.imm;
+ switch (op.imm) {
+ case PHP:
+ case PHA:
+ case PHY:
+ case PHX:
+ case PLP:
+ case PLA:
+ case PLY:
+ case PLX:
+ case STT:
+ case LSL:
+ case LSR:
+ case ROL:
+ case ROR:
+ case ENT:
+ addr[address++] = value & 0xFF;
+ break;
+ default:
+ addr[address] = value & 0xFF;
+ if (r & 1)
+ addr[address+1] = value >> 8;
+ if (r & 2)
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ if (r & 3)
+ addr[address+4] = value >> 32;
+ addr[address+5] = value >> 40;
+ addr[address+6] = value >> 48;
+ addr[address+7] = value >> 56;
+
+ address+=(1 << (r & 3));
+ break;
+
+ }
+ break;
+ } else {
+ fprintf(stderr, "oof, %s does not use Immediate data.\n", op.mnemonic);
+ }
+ break;
+ case 2:
+ if (op.zm) {
+ addr[address++] = op.zm;
+ addr[address] = value & 0xFF;
+ addr[address+1] = value >> 8;
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ address+=4;
+ break;
+ } else {
+ fprintf(stderr, "oof, %s does not use Zero Matrix.\n", op.mnemonic);
+ }
+ break;
+ case 3:
+ if (op.zmx) {
+ addr[address++] = op.zmy;
+ addr[address] = value & 0xFF;
+ addr[address+1] = value >> 8;
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ address+=4;
+ break;
+ } else {
+ fprintf(stderr, "oof, %s does not use Zero Matrix, indexed with x.\n", op.mnemonic);
+ }
+ break;
+ case 4:
+ if (op.zmy) {
+ addr[address++] = op.zmy;
+ addr[address] = value & 0xFF;
+ addr[address+1] = value >> 8;
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ address+=4;
+ break;
+ } else {
+ fprintf(stderr, "oof, %s does not use Zero Matrix, indexed with y.\n", op.mnemonic);
+ }
+ break;
+ case 5:
+ if (op.abs) {
+ addr[address++] = op.abs;
+ addr[address] = value & 0xFF;
+ addr[address+1] = value >> 8;
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ addr[address+4] = value >> 32;
+ addr[address+5] = value >> 40;
+ addr[address+6] = value >> 48;
+ addr[address+7] = value >> 56;
+ address+=8;
+ break;
+ } else {
+ fprintf(stderr, "oof, %s cannot be an absolute dictator.\n", op.mnemonic);
+ }
+ break;
+ }
+ if (!(done & 6))
+ printf("instruction: %s, ", ins);
+ #if (!__GLIBC__) || (__TINYC__)
+ printf("Postfix: %s, ", (postfix != NULL) ? postfix : "none");
+ #else
+ printf("Postfix: %s, ", (postfix[0] != '\0') ? postfix : "none");
+ #endif
+ printf("Operand: %s, Address: $%llx\n", (oprand != NULL) ? oprand : "none", address);
+ }
+ }
+ }
+ }
+ return 0;
+}
diff --git a/opcode.c b/opcode.c
index 32f4e9d..0bee207 100644
--- a/opcode.c
+++ b/opcode.c
@@ -9,15 +9,21 @@ void setps(struct sux *cpu, uint8_t 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;
+void adc(struct sux *cpu, uint64_t adr, uint8_t thread, uint8_t regsize) {
+ uint64_t value;
+ value = (uint64_t)addr[adr];
+ if (regsize >= 2)
+ value += (uint64_t)addr[adr+1] << 8;
+ if (regsize >= 4) {
+ value += (uint64_t)addr[adr+2] << 16;
+ value += (uint64_t)addr[adr+3] << 24;
+ }
+ if (regsize >= 8) {
+ value += (uint64_t)addr[adr+4] << 32;
+ value += (uint64_t)addr[adr+5] << 40;
+ value += (uint64_t)addr[adr+6] << 48;
+ value += (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);
@@ -27,15 +33,21 @@ void adc(struct sux *cpu, uint64_t adr, uint8_t thread) {
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;
+void sbc(struct sux *cpu, uint64_t adr, uint8_t thread, uint8_t regsize) {
+ uint64_t value;
+ value = (uint64_t)addr[adr];
+ if (regsize >= 2)
+ value += (uint64_t)addr[adr+1] << 8;
+ if (regsize >= 4) {
+ value += (uint64_t)addr[adr+2] << 16;
+ value += (uint64_t)addr[adr+3] << 24;
+ }
+ if (regsize >= 8) {
+ value += (uint64_t)addr[adr+4] << 32;
+ value += (uint64_t)addr[adr+5] << 40;
+ value += (uint64_t)addr[adr+6] << 48;
+ value += (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);
@@ -45,15 +57,21 @@ void sbc(struct sux *cpu, uint64_t adr, uint8_t thread) {
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;
+void mul(struct sux *cpu, uint64_t adr, uint8_t thread, uint8_t regsize) {
+ uint64_t value;
+ value = (uint64_t)addr[adr];
+ if (regsize >= 2)
+ value += (uint64_t)addr[adr+1] << 8;
+ if (regsize >= 4) {
+ value += (uint64_t)addr[adr+2] << 16;
+ value += (uint64_t)addr[adr+3] << 24;
+ }
+ if (regsize >= 8) {
+ value += (uint64_t)addr[adr+4] << 32;
+ value += (uint64_t)addr[adr+5] << 40;
+ value += (uint64_t)addr[adr+6] << 48;
+ value += (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);
@@ -63,15 +81,21 @@ void mul(struct sux *cpu, uint64_t adr, uint8_t thread) {
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;
+void divd(struct sux *cpu, uint64_t adr, uint8_t thread, uint8_t regsize) {
+ uint64_t value;
+ value = (uint64_t)addr[adr];
+ if (regsize >= 2)
+ value += (uint64_t)addr[adr+1] << 8;
+ if (regsize >= 4) {
+ value += (uint64_t)addr[adr+2] << 16;
+ value += (uint64_t)addr[adr+3] << 24;
+ }
+ if (regsize >= 8) {
+ value += (uint64_t)addr[adr+4] << 32;
+ value += (uint64_t)addr[adr+5] << 40;
+ value += (uint64_t)addr[adr+6] << 48;
+ value += (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);
@@ -88,15 +112,21 @@ uint64_t and(struct sux *cpu, uint64_t value, uint8_t 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;
+void and_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread, uint8_t regsize) {
+ uint64_t value;
+ value = (uint64_t)addr[adr];
+ if (regsize >= 2)
+ value += (uint64_t)addr[adr+1] << 8;
+ if (regsize >= 4) {
+ value += (uint64_t)addr[adr+2] << 16;
+ value += (uint64_t)addr[adr+3] << 24;
+ }
+ if (regsize >= 8) {
+ value += (uint64_t)addr[adr+4] << 32;
+ value += (uint64_t)addr[adr+5] << 40;
+ value += (uint64_t)addr[adr+6] << 48;
+ value += (uint64_t)addr[adr+7] << 56;
+ }
*reg &= value;
cpu->z[thread] = (*reg == 0);
cpu->n[thread] = (*reg >> 63);
@@ -112,15 +142,21 @@ uint64_t or(struct sux *cpu, uint64_t value, uint8_t 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;
+void or_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread, uint8_t regsize) {
+ uint64_t value;
+ value = (uint64_t)addr[adr];
+ if (regsize >= 2)
+ value += (uint64_t)addr[adr+1] << 8;
+ if (regsize >= 4) {
+ value += (uint64_t)addr[adr+2] << 16;
+ value += (uint64_t)addr[adr+3] << 24;
+ }
+ if (regsize >= 8) {
+ value += (uint64_t)addr[adr+4] << 32;
+ value += (uint64_t)addr[adr+5] << 40;
+ value += (uint64_t)addr[adr+6] << 48;
+ value += (uint64_t)addr[adr+7] << 56;
+ }
*reg |= value;
cpu->z[thread] = (*reg == 0);
cpu->n[thread] = (*reg >> 63);
@@ -136,15 +172,21 @@ uint64_t xor(struct sux *cpu, uint64_t value, uint8_t 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;
+void xor_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread, uint8_t regsize) {
+ uint64_t value;
+ value = (uint64_t)addr[adr];
+ if (regsize >= 2)
+ value += (uint64_t)addr[adr+1] << 8;
+ if (regsize >= 4) {
+ value += (uint64_t)addr[adr+2] << 16;
+ value += (uint64_t)addr[adr+3] << 24;
+ }
+ if (regsize >= 8) {
+ value += (uint64_t)addr[adr+4] << 32;
+ value += (uint64_t)addr[adr+5] << 40;
+ value += (uint64_t)addr[adr+6] << 48;
+ value += (uint64_t)addr[adr+7] << 56;
+ }
*reg ^= value;
cpu->z[thread] = (*reg == 0);
cpu->n[thread] = (*reg >> 63);
@@ -235,29 +277,39 @@ void ent(struct sux *cpu, uint8_t value) {
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;
+void ld(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread, uint8_t regsize) {
+ *reg = (uint64_t)addr[adr];
+ if (regsize >= 2)
+ *reg += (uint64_t)addr[adr+1] << 8;
+ if (regsize >= 4) {
+ *reg += (uint64_t)addr[adr+2] << 16;
+ *reg += (uint64_t)addr[adr+3] << 24;
+ }
+ if (regsize >= 8) {
+ *reg += (uint64_t)addr[adr+4] << 32;
+ *reg += (uint64_t)addr[adr+5] << 40;
+ *reg += (uint64_t)addr[adr+6] << 48;
+ *reg += (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) {
+void st(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread, uint8_t regsize) {
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;
+ if (regsize >= 2)
+ addr[adr+1] = *reg >> 8;
+ if (regsize >= 4) {
+ addr[adr+2] = *reg >> 16;
+ addr[adr+3] = *reg >> 24;
+ }
+ if (regsize >= 8) {
+ 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) {
@@ -274,15 +326,21 @@ uint8_t pull(struct sux *cpu) {
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;
+void cmp_addr(struct sux *cpu, uint64_t reg, uint64_t adr, uint8_t thread, uint8_t regsize) {
+ uint64_t value;
+ value = (uint64_t)addr[adr];
+ if (regsize >= 2)
+ value += (uint64_t)addr[adr+1] << 8;
+ if (regsize >= 4) {
+ value += (uint64_t)addr[adr+2] << 16;
+ value += (uint64_t)addr[adr+3] << 24;
+ }
+ if (regsize >= 8) {
+ value += (uint64_t)addr[adr+4] << 32;
+ value += (uint64_t)addr[adr+5] << 40;
+ value += (uint64_t)addr[adr+6] << 48;
+ value += (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;
@@ -313,6 +371,7 @@ void bfc(struct sux *cpu, uint8_t flag, uint64_t adr, uint8_t thread) {
uint64_t immaddr(struct sux *cpu, uint8_t thread, uint8_t size) {
uint64_t adr = cpu->pc[thread];
cpu->pc[thread]+=size;
+ clk+=size;
return adr;
}
@@ -326,6 +385,7 @@ uint64_t absaddr(struct sux *cpu, uint8_t thread) {
| (uint64_t)addr[cpu->pc[thread]+6] << 48
| (uint64_t)addr[cpu->pc[thread]+7] << 56;
cpu->pc[thread]+=8;
+ clk++;
return adr;
}
@@ -335,6 +395,7 @@ uint32_t zeromtx(struct sux *cpu, uint8_t thread) {
| (uint32_t)addr[cpu->pc[thread]+2] << 16
| (uint32_t)addr[cpu->pc[thread]+3] << 24;
cpu->pc[thread]+=4;
+ clk++;
return adr;
}
@@ -345,6 +406,7 @@ uint32_t zeromx(struct sux *cpu, uint8_t thread) {
| (uint32_t)addr[cpu->pc[thread]+3] << 24;
adr += cpu->x[thread];
cpu->pc[thread]+=4;
+ clk++;
return adr;
}
@@ -355,5 +417,6 @@ uint32_t zeromy(struct sux *cpu, uint8_t thread) {
| (uint32_t)addr[cpu->pc[thread]+3] << 24;
adr += cpu->y[thread];
cpu->pc[thread]+=4;
+ clk++;
return adr;
}
diff --git a/opcode.h b/opcode.h
index 3b44e4b..d83b74c 100644
--- a/opcode.h
+++ b/opcode.h
@@ -79,7 +79,9 @@
#define DAY 0xD3 /* Decrement Accumulator, and Y register. */
#define DEX 0xD4 /* DEcrement X register. */
#define DAX 0xD5 /* Decrement Accumulator, and X register. */
+#define JSL 0xE0 /* Jump to Subroutine Long. */
#define NOP 0xE8 /* No OPeration. */
+#define RTL 0xF0 /* ReTurn from subroutine Long. */
#define BRK 0xF8 /* BReaK. */
#define C ((uint64_t)1 << 0)
@@ -94,6 +96,7 @@
struct sux;
uint8_t *addr; /* Address Space. */
+uint64_t clk; /* Clock cycles. */
struct sux {
uint64_t ps; /* The processor status register. */
@@ -105,6 +108,16 @@ struct sux {
};
+typedef struct {
+ char mnemonic[4];
+ uint8_t imm;
+ uint8_t abs;
+ uint8_t zm;
+ uint8_t zmy;
+ uint8_t zmx;
+ uint8_t impl;
+} opent;
+
static const char *opname[0x100] = {
OPNAME(CPS),
[ADC] = "ADC #",
@@ -227,17 +240,20 @@ static const char *opname[0x100] = {
OPNAME(IAY),
OPNAME(INX),
OPNAME(IAX),
+ [0xD0] = "JMP zm",
[DEC] = "DEC A",
OPNAME(DEY),
OPNAME(DAY),
OPNAME(DEX),
OPNAME(DAX),
+ OPNAME(JSL),
[0xE1] = "INC a",
[0xE2] = "CPY a",
[0xE3] = "INC zm",
[0xE4] = "CPX a",
[0xE5] = "CMP a",
OPNAME(NOP),
+ OPNAME(RTL),
[0xF1] = "DEC a",
[0xF2] = "CPY zm",
[0xF3] = "DEC zm",
@@ -246,16 +262,17 @@ static const char *opname[0x100] = {
OPNAME(BRK),
};
-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 int asmmon();
+extern void adc(struct sux *cpu, uint64_t adr, uint8_t thread, uint8_t regsize);
+extern void sbc(struct sux *cpu, uint64_t adr, uint8_t thread, uint8_t regsize);
+extern void mul(struct sux *cpu, uint64_t adr, uint8_t thread, uint8_t regsize);
+extern void divd(struct sux *cpu, uint64_t adr, uint8_t thread, uint8_t regsize);
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 void and_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread, uint8_t regsize);
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 void or_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread, uint8_t regsize);
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 xor_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread, uint8_t regsize);
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);
@@ -266,11 +283,11 @@ 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 ld(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread, uint8_t regsize);
+extern void st(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread, uint8_t regsize);
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_addr(struct sux *cpu, uint64_t reg, uint64_t adr, uint8_t thread, uint8_t regsize);
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);
diff --git a/sux.c b/sux.c
index 0af4c06..f42c0da 100644
--- a/sux.c
+++ b/sux.c
@@ -1,22 +1,23 @@
#include "opcode.h"
+#define bench 0
+#if bench
+#include <time.h>
+#endif
-int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
+int run(struct sux *cpu, uint8_t prefix, uint8_t opcode, uint8_t thread) {
uint64_t address;
+ uint8_t regsize = (1 << (prefix & 3));
uint8_t tmp;
address = cpu->pc[thread];
- printf("pc: 0x%08llx, a: 0x%016llx, x: 0x%016llx, y: 0x%016llx"
- ", sp: 0x%04lx, ps: 0x%016llx, opcode: 0x%02x, inst: %s,\taddr $4000-7: 0x%016llx\n"
+#if !bench
+ printf("pc: 0x%llx, a: 0x%016llx, x: 0x%016llx, y: 0x%016llx"
+ ", sp: 0x%04lx, ps: 0x%016llx, opcode: 0x%02x, inst: %s\n"
, cpu->pc[thread], cpu->a[thread], cpu->x[thread], cpu->y[thread]
- , cpu->sp, cpu->ps, opcode, opname[opcode]
- , (uint64_t)addr[0x4000]
- | (uint64_t)addr[0x4001] << 8
- | (uint64_t)addr[0x4002] << 16
- | (uint64_t)addr[0x4003] << 24
- | (uint64_t)addr[0x4004] << 32
- | (uint64_t)addr[0x4005] << 40
- | (uint64_t)addr[0x4006] << 48
- | (uint64_t)addr[0x4007] << 56);
+ , cpu->sp, cpu->ps, opcode, opname[opcode]);
+ fflush(stdout);
+#endif
cpu->pc[thread]++;
+ clk++;
switch(opcode) {
case CPS: /* Clear Processor Status. */
for (uint8_t i = 0; i < 8; i++) {
@@ -29,9 +30,9 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
}
cpu->ps &= 0;
break;
- case ADC: adc(cpu, immaddr(cpu, thread, 8), thread); break; /* ADC Immediate. */
- case 0x03: adc(cpu, absaddr(cpu, thread), thread); break; /* ADC Absolute. */
- case 0x05: adc(cpu, zeromtx(cpu, thread), thread); break; /* ADC Zero Matrix. */
+ case ADC: adc(cpu, immaddr(cpu, thread, regsize), thread, regsize); break; /* ADC Immediate. */
+ case 0x03: adc(cpu, absaddr(cpu, thread), thread, regsize); break; /* ADC Absolute. */
+ case 0x05: adc(cpu, zeromtx(cpu, thread), thread, regsize); break; /* ADC Zero Matrix. */
case PHP: /* PusH Processor status to stack. */
tmp = addr[cpu->pc[thread]++];
if (tmp > 7)
@@ -68,13 +69,13 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
}
push(cpu, cpu->x[thread] & 0xFF);
break;
- case JMP: /* JuMP to memory location. */
+ case JMP: /* JMP Absolute. */
address = absaddr(cpu, thread);
cpu->pc[thread] = address;
break;
- case SBC: sbc(cpu, immaddr(cpu, thread, 8), thread); break; /* SBC Immediate. */
- case 0x13: sbc(cpu, absaddr(cpu, thread), thread); break; /* SBC Absolute. */
- case 0x15: sbc(cpu, zeromtx(cpu, thread), thread); break; /* SBC Zero Matrix. */
+ case SBC: sbc(cpu, immaddr(cpu, thread, regsize), thread, regsize); break; /* SBC Immediate. */
+ case 0x13: sbc(cpu, absaddr(cpu, thread), thread, regsize); break; /* SBC Absolute. */
+ case 0x15: sbc(cpu, zeromtx(cpu, thread), thread, regsize); break; /* SBC Zero Matrix. */
case PLP: /* PuLl Processor status from stack. */
tmp = addr[cpu->pc[thread]++];
if (tmp > 7)
@@ -123,133 +124,125 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
address = (uint64_t)addr[cpu->pc[thread]]
| (uint64_t)addr[cpu->pc[thread]+1] << 8
| (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- push(cpu, (uint64_t)cpu->pc[thread] >> 56);
- push(cpu, (uint64_t)cpu->pc[thread] >> 48);
- push(cpu, (uint64_t)cpu->pc[thread] >> 40);
- push(cpu, (uint64_t)cpu->pc[thread] >> 32);
+ | (uint64_t)addr[cpu->pc[thread]+3] << 24;
+ cpu->pc[thread]+=4;
push(cpu, (uint64_t)cpu->pc[thread] >> 24);
push(cpu, (uint64_t)cpu->pc[thread] >> 16);
push(cpu, (uint64_t)cpu->pc[thread] >> 8);
push(cpu, (uint64_t)cpu->pc[thread] & 0xFF);
cpu->pc[thread] = address;
break;
- case AND: and_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, 8), thread); break; /* AND Immediate. */
- case ANY: and_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, 8), thread); break; /* ANY Immediate. */
+ case AND: and_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* AND Immediate. */
+ case ANY: and_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ANY Immediate. */
case AAY: cpu->a[thread] = and(cpu, cpu->y[thread], thread); break;
- case ANX: and_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, 8), thread); break; /* ANX Immediate. */
+ case ANX: and_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ANX Immediate. */
case AAX: cpu->a[thread] = and(cpu, cpu->x[thread], thread); break;
case STT: stt(cpu, immaddr(cpu, thread, 1)); break; /* STart Thread. */
- case 0x29: and_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread); break; /* AND Absolute. */
- case 0x2B: and_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread); break; /* AND Zero Matrix. */
+ case 0x29: and_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* AND Absolute. */
+ case 0x2B: and_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* AND Zero Matrix. */
case BPO: bfc(cpu, cpu->n[thread], absaddr(cpu, thread), thread); break; /* Branch if POsitive. */
- case ORA: or_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, 8), thread); break; /* ORA Immediate. */
- case ORY: or_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, 8), thread); break; /* ORY Immediate. */
+ case ORA: or_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ORA Immediate. */
+ case ORY: or_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ORY Immediate. */
case OAY: cpu->a[thread] = or(cpu, cpu->y[thread], thread); break;
- case ORX: or_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, 8), thread); break; /* ORX Immediate. */
+ case ORX: or_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ORX Immediate. */
case OAX: cpu->a[thread] = or(cpu, cpu->x[thread], thread); break;
case SEI: /* SEt Interrupt. */
cpu->i[thread] = 1;
setps(cpu, thread);
break;
- case 0x39: or_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread); break; /* ORA Absolute. */
- case 0x3B: or_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread); break; /* ORA Zero Matrix. */
+ case 0x39: or_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* ORA Absolute. */
+ case 0x3B: or_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* ORA Zero Matrix. */
case BNG: bfs(cpu, cpu->n[thread], absaddr(cpu, thread), thread); break; /* Branch if NeGative. */
- case XOR: xor_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, 8), thread); break; /* XOR Immediate. */
- case XRY: xor_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, 8), thread); break; /* XRY Immediate. */
+ case XOR: xor_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* XOR Immediate. */
+ case XRY: xor_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* XRY Immediate. */
case XAY: cpu->a[thread] = xor(cpu, cpu->y[thread], thread); break;
- case XRX: xor_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, 9), thread); break; /* XRX Immediate. */
+ case XRX: xor_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* XRX Immediate. */
case XAX: cpu->a[thread] = xor(cpu, cpu->x[thread], thread); break;
case CLI: /* CLear Interrupt. */
cpu->i[thread] = 0;
setps(cpu, thread);
break;
- case 0x49: xor_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread); break; /* XOR Absolute. */
- case 0x4B: xor_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread); break; /* XOR Zero Matrix. */
+ case 0x49: xor_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* XOR Absolute. */
+ case 0x4B: xor_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* XOR Zero Matrix. */
case BCS: bfs(cpu, cpu->c[thread], absaddr(cpu, thread), thread); break; /* Branch if Carry Set. */
case LSL: lsl(cpu, immaddr(cpu, thread, 1), thread); break; /* LSL Immediate. */
- case 0x52: and_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread); break; /* ANY Absolute. */
+ case 0x52: and_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* ANY Absolute. */
case 0x53: lsl(cpu, absaddr(cpu, thread), thread); break; /* LSL Absolute. */
- case 0x54: and_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread); break; /* ANX Absolute. */
+ case 0x54: and_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* ANX Absolute. */
case 0x55: lsl(cpu, zeromtx(cpu, thread), thread); break; /* LSL Zero Matrix. */
case SEC: /* SEt Carry flag.*/
cpu->c[thread] = 1;
setps(cpu, thread);
break;
- case 0x59: ld(cpu, &cpu->a[thread], absaddr(cpu, thread), thread); break; /* LDA Absolute. */
- case 0x5A: ld(cpu, &cpu->y[thread], absaddr(cpu, thread), thread); break; /* LDY Absolute. */
- case STA: st(cpu, &cpu->a[thread], absaddr(cpu, thread), thread); break; /* STA Absolute. */
- case 0x5C: ld(cpu, &cpu->x[thread], absaddr(cpu, thread), thread); break; /* LDX Absolute. */
- case STY: st(cpu, &cpu->y[thread], absaddr(cpu, thread), thread); break; /* STY Absolute. */
- case STX: st(cpu, &cpu->x[thread], absaddr(cpu, thread), thread); break; /* STX Absolute. */
+ case 0x59: ld(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* LDA Absolute. */
+ case 0x5A: ld(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* LDY Absolute. */
+ case STA: st(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* STA Absolute. */
+ case 0x5C: ld(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* LDX Absolute. */
+ case STY: st(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* STY Absolute. */
+ case STX: st(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* STX Absolute. */
case BCC: bfc(cpu, cpu->c[thread], absaddr(cpu, thread), thread); break; /* Branch if Carry Clear. */
case LSR: lsr(cpu, immaddr(cpu, thread, 1), thread); break; /* LSR Immediate. */
- case 0x62: or_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread); break; /* ORY Absolute. */
+ case 0x62: or_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* ORY Absolute. */
case 0x63: lsr(cpu, absaddr(cpu, thread), thread); break; /* LSR Absolute. */
- case 0x64: or_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread); break; /* ORX Absolute. */
+ case 0x64: or_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* ORX Absolute. */
case 0x65: lsr(cpu, zeromtx(cpu, thread), thread); break; /* LSR Zero Matrix. */
case CLC: /* CLear Carry flag. */
cpu->c[thread] = 0;
setps(cpu, thread);
break;
- case LDA: ld(cpu, &cpu->a[thread], immaddr(cpu, thread, 8), thread); break; /* LDA Immediate. */
- case LDY: ld(cpu, &cpu->y[thread], immaddr(cpu, thread, 8), thread); break; /* LDY Immediate. */
- case LDX: ld(cpu, &cpu->x[thread], immaddr(cpu, thread, 8), thread); break; /* LDX Immediate. */
+ case LDA: ld(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* LDA Immediate. */
+ case LDY: ld(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* LDY Immediate. */
+ case LDX: ld(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* LDX Immediate. */
case BEQ: bfs(cpu, cpu->z[thread], absaddr(cpu, thread), thread); break; /* Branch if EQual. */
case ROL: rol(cpu, immaddr(cpu, thread, 1), thread); break; /* ROL Immediate. */
- case 0x72: xor_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread); break; /* XRY Absolute. */
+ case 0x72: xor_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* XRY Absolute. */
case 0x73: rol(cpu, absaddr(cpu, thread), thread); break; /* ROL Absolute. */
- case 0x74: xor_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread); break; /* XRX Absolute. */
+ case 0x74: xor_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* XRX Absolute. */
case 0x75: rol(cpu, zeromtx(cpu, thread), thread); break; /* ROL Zero Matrix. */
case SSP: /* Set Stack Protection flag. */
cpu->s[thread] = 1;
setps(cpu, thread);
break;
- case 0x79: ld(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread); break; /* LDA Zero Matrix. */
- case 0x7A: ld(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread); break; /* LDY Zero Matrix. */
- case 0x7B: st(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread); break; /* STA Zero Matrix. */
- case 0x7C: ld(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread); break; /* LDX Zero Matrix. */
- case 0x7D: st(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread); break; /* STY Zero Matrix. */
- case 0x7E: st(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread); break; /* STX Zero Matrix. */
+ case 0x79: ld(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* LDA Zero Matrix. */
+ case 0x7A: ld(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* LDY Zero Matrix. */
+ case 0x7B: st(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* STA Zero Matrix. */
+ case 0x7C: ld(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* LDX Zero Matrix. */
+ case 0x7D: st(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* STY Zero Matrix. */
+ case 0x7E: st(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* STX Zero Matrix. */
case BNE: bfc(cpu, cpu->z[thread], absaddr(cpu, thread), thread); break; /* Branch if Not Equal. */
case ROR: ror(cpu, immaddr(cpu, thread, 1), thread); break; /* ROR Immediate. */
- case 0x82: and_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread); break; /* ANY Zero Matrix. */
+ case 0x82: and_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* ANY Zero Matrix. */
case 0x83: ror(cpu, absaddr(cpu, thread), thread); break; /* ROR Absolute. */
- case 0x84: and_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread); break; /* ANX Zero Matrix. */
+ case 0x84: and_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* ANX Zero Matrix. */
case 0x85: ror(cpu, zeromtx(cpu, thread), thread); break; /* ROR Zero Matrix. */
case CSP: /* Clear Stack Protection flag. */
cpu->s[thread] = 0;
setps(cpu, thread);
break;
- case 0x89: ld(cpu, &cpu->a[thread], zeromx(cpu, thread), thread); break; /* LDA Zero Matrix, Indexed with X. */
- case 0x8A: ld(cpu, &cpu->y[thread], zeromx(cpu, thread), thread); break; /* LDY Zero Matrix, Indexed with X. */
- case 0x8B: st(cpu, &cpu->a[thread], zeromx(cpu, thread), thread); break; /* STA Zero Matrix, Indexed with X. */
- case 0x8D: st(cpu, &cpu->y[thread], zeromx(cpu, thread), thread); break; /* STY Zero Matrix, Indexed with X. */
+ case 0x89: ld(cpu, &cpu->a[thread], zeromx(cpu, thread), thread, regsize); break; /* LDA Zero Matrix, Indexed with X. */
+ case 0x8A: ld(cpu, &cpu->y[thread], zeromx(cpu, thread), thread, regsize); break; /* LDY Zero Matrix, Indexed with X. */
+ case 0x8B: st(cpu, &cpu->a[thread], zeromx(cpu, thread), thread, regsize); break; /* STA Zero Matrix, Indexed with X. */
+ case 0x8D: st(cpu, &cpu->y[thread], zeromx(cpu, thread), thread, regsize); break; /* STY Zero Matrix, Indexed with X. */
case BVS: bfs(cpu, cpu->v[thread], absaddr(cpu, thread), thread); break; /* Branch if oVerflow Set. */
- case MUL: mul(cpu, immaddr(cpu, thread, 8), thread); break; /* MUL Immediate. */
- case 0x92: or_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread); break; /* ORY Zero Matrix. */
- case 0x93: mul(cpu, absaddr(cpu, thread), thread); break; /* MUL Absolute. */
- case 0x94: or_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread); break; /* ORX Zero Matrix. */
- case 0x95: mul(cpu, zeromtx(cpu, thread), thread); break; /* MUL Zero Matrix. */
+ case MUL: mul(cpu, immaddr(cpu, thread, regsize), thread, regsize); break; /* MUL Immediate. */
+ case 0x92: or_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* ORY Zero Matrix. */
+ case 0x93: mul(cpu, absaddr(cpu, thread), thread, regsize); break; /* MUL Absolute. */
+ case 0x94: or_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* ORX Zero Matrix. */
+ case 0x95: mul(cpu, zeromtx(cpu, thread), thread, regsize); break; /* MUL Zero Matrix. */
case SEV: /* SEt oVerflow flag. */
cpu->v[thread] = 1;
setps(cpu, thread);
break;
- case 0x99: ld(cpu, &cpu->a[thread], zeromy(cpu, thread), thread); break; /* LDA Zero Matrix, Indexed with Y. */
- case 0x9B: ld(cpu, &cpu->x[thread], zeromy(cpu, thread), thread); break; /* STA Zero Matrix, Indexed with Y. */
- case 0x9C: st(cpu, &cpu->a[thread], zeromy(cpu, thread), thread); break; /* LDX Zero Matrix, Indexed with Y. */
- case 0x9E: st(cpu, &cpu->x[thread], zeromy(cpu, thread), thread); break; /* STX Zero Matrix, Indexed with Y. */
+ case 0x99: ld(cpu, &cpu->a[thread], zeromy(cpu, thread), thread, regsize); break; /* LDA Zero Matrix, Indexed with Y. */
+ case 0x9B: ld(cpu, &cpu->x[thread], zeromy(cpu, thread), thread, regsize); break; /* STA Zero Matrix, Indexed with Y. */
+ case 0x9C: st(cpu, &cpu->a[thread], zeromy(cpu, thread), thread, regsize); break; /* LDX Zero Matrix, Indexed with Y. */
+ case 0x9E: st(cpu, &cpu->x[thread], zeromy(cpu, thread), thread, regsize); break; /* STX Zero Matrix, Indexed with Y. */
case BVC: bfc(cpu, cpu->z[thread], absaddr(cpu, thread), thread); break; /* Branch if oVerflow Clear. */
- case DIV: divd(cpu, immaddr(cpu, thread, 8), thread); break; /* DIV Immediate. */
- case 0xA2: xor_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread); break; /* XRY Zero Matrix. */
- case 0xA3: divd(cpu, absaddr(cpu, thread), thread); break; /* DIV Absolute. */
- case 0xA4: xor_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread); break; /* XRX Zero Matrix. */
- case 0xA5: divd(cpu, zeromtx(cpu, thread), thread); break; /* DIV Zero Matrix. */
+ case DIV: divd(cpu, immaddr(cpu, thread, regsize), thread, regsize); break; /* DIV Immediate. */
+ case 0xA2: xor_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* XRY Zero Matrix. */
+ case 0xA3: divd(cpu, absaddr(cpu, thread), thread, regsize); break; /* DIV Absolute. */
+ case 0xA4: xor_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* XRX Zero Matrix. */
+ case 0xA5: divd(cpu, zeromtx(cpu, thread), thread, regsize); break; /* DIV Zero Matrix. */
case CLV: /* CLear oVerflow flag. */
cpu->v[thread] = 0;
setps(cpu, thread);
@@ -258,16 +251,12 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
cpu->pc[thread] = (uint64_t)pull(cpu);
cpu->pc[thread] += ((uint64_t)pull(cpu) << 8);
cpu->pc[thread] += ((uint64_t)pull(cpu) << 16);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 24);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 32);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 40);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 48);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 56) + 1;
+ cpu->pc[thread] += ((uint64_t)pull(cpu) << 24) + 1;
break;
- case CMP: cmp_addr(cpu, cpu->a[thread], immaddr(cpu, thread, 8), thread); break; /* CMP Immediate */
- case CPY: cmp_addr(cpu, cpu->y[thread], immaddr(cpu, thread, 8), thread); break; /* CPY Immediate */
+ case CMP: cmp_addr(cpu, cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* CMP Immediate. */
+ case CPY: cmp_addr(cpu, cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* CPY Immediate. */
case CAY: cmp(cpu, cpu->a[thread], cpu->y[thread], thread); break;
- case CPX: cmp_addr(cpu, cpu->x[thread], immaddr(cpu, thread, 8), thread); break; /* CPX Immediate */
+ case CPX: cmp_addr(cpu, cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* CPX Immediate. */
case CAX: cmp(cpu, cpu->a[thread], cpu->x[thread], thread); break;
case ENT: ent(cpu, immaddr(cpu, thread, 1)); break; /* ENd Thread. */
case RTI: /* ReTurn from Interupt routine. */
@@ -279,7 +268,7 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
cpu->pc[thread] += ((uint64_t)pull(cpu) << 32);
cpu->pc[thread] += ((uint64_t)pull(cpu) << 40);
cpu->pc[thread] += ((uint64_t)pull(cpu) << 48);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 56) + 1;
+ cpu->pc[thread] += ((uint64_t)pull(cpu) << 56);
break;
case INC: /* INC Accumulator. */
inc(cpu, &cpu->a[thread], thread);
@@ -288,22 +277,56 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
case IAY: inc(cpu, &cpu->a[thread], thread); inc(cpu, &cpu->y[thread], thread); break;
case INX: inc(cpu, &cpu->x[thread], thread); break;
case IAX: inc(cpu, &cpu->a[thread], thread); inc(cpu, &cpu->x[thread], thread); break;
+ case 0xD0: /* JMP Zero Matrix. */
+ address = zeromtx(cpu, thread);
+ cpu->pc[thread] = address;
+ break;
case DEC: dec(cpu, &cpu->a[thread], thread); break; /* DEC Accumulator. */
case DEY: dec(cpu, &cpu->y[thread], thread); break;
case DAY: dec(cpu, &cpu->a[thread], thread); dec(cpu, &cpu->y[thread], thread); break;
case DEX: dec(cpu, &cpu->x[thread], thread); break;
case DAX: dec(cpu, &cpu->a[thread], thread); dec(cpu, &cpu->x[thread], thread); break;
+ case JSL: /* Jump to Subroutine Long. */
+ address = (uint64_t)addr[cpu->pc[thread]]
+ | (uint64_t)addr[cpu->pc[thread]+1] << 8
+ | (uint64_t)addr[cpu->pc[thread]+2] << 16
+ | (uint64_t)addr[cpu->pc[thread]+3] << 24
+ | (uint64_t)addr[cpu->pc[thread]+4] << 32
+ | (uint64_t)addr[cpu->pc[thread]+5] << 40
+ | (uint64_t)addr[cpu->pc[thread]+6] << 48
+ | (uint64_t)addr[cpu->pc[thread]+7] << 56;
+ cpu->pc[thread]+=8;
+ push(cpu, (uint64_t)cpu->pc[thread] >> 56);
+ push(cpu, (uint64_t)cpu->pc[thread] >> 48);
+ push(cpu, (uint64_t)cpu->pc[thread] >> 40);
+ push(cpu, (uint64_t)cpu->pc[thread] >> 32);
+ push(cpu, (uint64_t)cpu->pc[thread] >> 24);
+ push(cpu, (uint64_t)cpu->pc[thread] >> 16);
+ push(cpu, (uint64_t)cpu->pc[thread] >> 8);
+ push(cpu, (uint64_t)cpu->pc[thread] & 0xFF);
+ cpu->pc[thread] = address;
+ break;
case 0xE1: inc_addr(cpu, absaddr(cpu, thread), thread); break; /* INC Absolute. */
- case 0xE2: cmp_addr(cpu, cpu->y[thread], absaddr(cpu, thread), thread); break; /* CPY Absolute. */
+ case 0xE2: cmp_addr(cpu, cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* CPY Absolute. */
case 0xE3: inc_addr(cpu, zeromtx(cpu, thread), thread); break; /* INC Zero Matrix. */
- case 0xE4: cmp_addr(cpu, cpu->x[thread], absaddr(cpu, thread), thread); break; /* CPX Absolute. */
- case 0xE5: cmp_addr(cpu, cpu->a[thread], absaddr(cpu, thread), thread); break; /* CMP Absolute. */
+ case 0xE4: cmp_addr(cpu, cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* CPX Absolute. */
+ case 0xE5: cmp_addr(cpu, cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* CMP Absolute. */
case NOP: break; /* No OPeration. */
+ case RTL: /* ReTurn from subroutine Long. */
+ cpu->pc[thread] = (uint64_t)pull(cpu);
+ cpu->pc[thread] += ((uint64_t)pull(cpu) << 8);
+ cpu->pc[thread] += ((uint64_t)pull(cpu) << 16);
+ cpu->pc[thread] += ((uint64_t)pull(cpu) << 24);
+ cpu->pc[thread] += ((uint64_t)pull(cpu) << 32);
+ cpu->pc[thread] += ((uint64_t)pull(cpu) << 40);
+ cpu->pc[thread] += ((uint64_t)pull(cpu) << 48);
+ cpu->pc[thread] += ((uint64_t)pull(cpu) << 56) + 1;
+ break;
case 0xF1: dec_addr(cpu, absaddr(cpu, thread), thread); break; /* DEC Absolute. */
- case 0xF2: cmp_addr(cpu, cpu->y[thread], zeromtx(cpu, thread), thread); break; /* CPY Zero Matrix. */
+ case 0xF2: cmp_addr(cpu, cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* CPY Zero Matrix. */
case 0xF3: dec_addr(cpu, zeromtx(cpu, thread), thread); break; /* DEC Zero Matrix. */
- case 0xF4: cmp_addr(cpu, cpu->x[thread], zeromtx(cpu, thread), thread); break; /* CPX Zero Matrix. */
- case 0xF5: cmp_addr(cpu, cpu->a[thread], zeromtx(cpu, thread), thread); break; /* CMP Zero Matrix. */
+ case 0xF4: cmp_addr(cpu, cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* CPX Zero Matrix. */
+ case 0xF5: cmp_addr(cpu, cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* CMP Zero Matrix. */
case BRK: /* BReaK. */
push(cpu, (uint64_t)cpu->pc[thread]-1 >> 56);
push(cpu, (uint64_t)cpu->pc[thread]-1 >> 48);
@@ -320,10 +343,10 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
| (uint64_t)addr[0xFFE1] << 8
| (uint64_t)addr[0xFFE2] << 16
| (uint64_t)addr[0xFFE3] << 24
- | (uint64_t)addr[0xFFF0] << 32
- | (uint64_t)addr[0xFFF1] << 40
- | (uint64_t)addr[0xFFF2] << 48
- | (uint64_t)addr[0xFFF3] << 56;
+ | (uint64_t)addr[0xFFE4] << 32
+ | (uint64_t)addr[0xFFE5] << 40
+ | (uint64_t)addr[0xFFE6] << 48
+ | (uint64_t)addr[0xFFE7] << 56;
default:
if(opcode != BRK) {
printf("Cool, you inputed a non existent opcode, which means\n"
@@ -336,6 +359,8 @@ int run(struct sux *cpu, uint8_t opcode, uint8_t thread) {
}
int main(int argc, char **argv) {
+
+
struct sux cpu;
cpu.a[0] = 0;
cpu.x[0] = 0;
@@ -343,101 +368,90 @@ int main(int argc, char **argv) {
cpu.sp = 0xFFFF;
addr = malloc(8*0x04000000);
int v = 0;
+ if (asmmon() == 2)
+ return 0;
- addr[0x8000] = 0x00; /* CPS */
- addr[0x8001] = 0x69; /* LDA #$01 */
- addr[0x8002] = 0x02;
- addr[0x8003] = 0x00;
- addr[0x8004] = 0x00;
- addr[0x8005] = 0x00;
- addr[0x8006] = 0x00;
- addr[0x8007] = 0x00;
- addr[0x8008] = 0x00;
- addr[0x8009] = 0x00;
- addr[0x800A] = 0x7B; /* STA $4000 */
- addr[0x800B] = 0x00;
- addr[0x800C] = 0x40;
- addr[0x800D] = 0x00;
- addr[0x800E] = 0x00;
- addr[0x800F] = 0x7C; /* LDX $4000 */
- addr[0x8010] = 0x00;
- addr[0x8011] = 0x40;
- addr[0x8012] = 0x00;
- addr[0x8013] = 0x00;
- addr[0x8014] = 0x05; /* ADC $4000 */
- addr[0x8015] = 0x00;
- addr[0x8016] = 0x40;
- addr[0x8017] = 0x00;
- addr[0x8018] = 0x00;
- addr[0x8019] = 0xF8; /* BRK */
- addr[0x801A] = 0x10; /* JMP $800A */
- addr[0x801B] = 0x0A;
- addr[0x801C] = 0x80;
- addr[0x801D] = 0x00;
- addr[0x801E] = 0x00;
- addr[0x801F] = 0x00;
- addr[0x8020] = 0x00;
- addr[0x8021] = 0x00;
- addr[0x8022] = 0x00;
-
- addr[0x28000] = 0xE8; /* NOP */
- addr[0x28001] = 0x6A; /* LDY #$800A10E8 */
- addr[0x28002] = 0xE8;
- addr[0x28003] = 0x10;
- addr[0x28004] = 0x0A;
- addr[0x28005] = 0x80;
- addr[0x28006] = 0x00;
- addr[0x28007] = 0x00;
- addr[0x28008] = 0x00;
- addr[0x28009] = 0x00;
- addr[0x2800A] = 0x7D; /* STY $8019 */
- addr[0x2800B] = 0x19;
- addr[0x2800C] = 0x80;
- addr[0x2800D] = 0x00;
- addr[0x2800E] = 0x00;
- addr[0x2800F] = 0xC0; /* RTI */
-
+#if 0
+ /* Reset Vector. */
addr[0xFFC0] = 0x00;
addr[0xFFC1] = 0x80;
addr[0xFFC2] = 0x00;
addr[0xFFC3] = 0x00;
- addr[0xFFD0] = 0x00;
- addr[0xFFD1] = 0x00;
- addr[0xFFD2] = 0x00;
- addr[0xFFD3] = 0x00;
-
+ addr[0xFFC4] = 0x00;
+ addr[0xFFC5] = 0x00;
+ addr[0xFFC6] = 0x00;
+ addr[0xFFC7] = 0x00;
+#endif
+#if 0
+ /* BRK Vector. */
addr[0xFFE0] = 0x00;
addr[0xFFE1] = 0x80;
addr[0xFFE2] = 0x02;
addr[0xFFE3] = 0x00;
- addr[0xFFF0] = 0x00;
- addr[0xFFF1] = 0x00;
- addr[0xFFF2] = 0x00;
- addr[0xFFF3] = 0x00;
-
+ addr[0xFFE4] = 0x00;
+ addr[0xFFE5] = 0x00;
+ addr[0xFFE6] = 0x00;
+ addr[0xFFE7] = 0x00;
+#endif
cpu.pc[0] = (uint64_t)addr[0xFFC0]
| (uint64_t)addr[0xFFC1] << 8
| (uint64_t)addr[0xFFC2] << 16
| (uint64_t)addr[0xFFC3] << 24
- | (uint64_t)addr[0xFFD0] << 32
- | (uint64_t)addr[0xFFD1] << 40
- | (uint64_t)addr[0xFFD2] << 48
- | (uint64_t)addr[0xFFD3] << 56;
+ | (uint64_t)addr[0xFFC4] << 32
+ | (uint64_t)addr[0xFFC5] << 40
+ | (uint64_t)addr[0xFFC6] << 48
+ | (uint64_t)addr[0xFFC7] << 56;
uint64_t inst = 0;
uint8_t lines = 2;
+ uint8_t prefix = 0;
uint8_t opcode = 0;
uint8_t end = 0;
+#if bench
+ double ipc;
+ clock_t st, en;
+ double t0;
+#endif
printf("\033[2J");
+#if bench
+ st = clock();
+#endif
while (!end) {
+ prefix = addr[cpu.pc[0]++];
opcode = addr[cpu.pc[0]];
+#if !bench
printf("\033[%uH\033[2K", lines);
lines++;
- run(&cpu, opcode, 0);
-
+#endif
+ run(&cpu, prefix, opcode, 0);
+#if !bench
if (lines > 24)
lines = 2;
- printf("\033[HInstructions executed: %llu\n", inst++);
+#endif
+#if bench
+ t0 = ((double)clock() - (double)st)/(double)CLOCKS_PER_SEC;
+#endif
+ inst++;
+
+#if !bench
+ printf("\033[HInstructions executed: %llu, Clock cycles: %llu\n", inst, clk);
+ fflush(stdout);
+#endif
+#if bench
+ if (t0 >= 1.00) {
+ end = 1;
+ }
+#endif
}
+#if bench
+ en = (double)clock();
+ double tm = (double)(en - st);
+ double clkspd = (t0*1000000)/clk;
+ double mhz = 1000000.0/clkspd/1000000;
+ double ips = (double)inst/(double)tm;
+ ipc=(double)inst/(double)clk;
+ printf("\033[2J");
+ printf("Instructions executed: %llu, Instructions per Second in MIPS: %f, Clock cycles: %llu, Clock Speed in MHz: %f\n", inst, ips, clk, mhz);
+#endif
free(addr);
return 0;
}
diff --git a/test/test.s b/test/test.s
new file mode 100644
index 0000000..3e8a7f2
--- /dev/null
+++ b/test/test.s
@@ -0,0 +1,13 @@
+; Testing Sux assembly, and the machine language monitor.
+;
+; Writen by mr b0nk 500 <b0nk@b0nk.xyz>
+.org $8000
+cps ; Clear the processor status register.
+lda.w #$1000 ; Load 0x1000 into the accumulator.
+rol #$1 ; Then rotate the accumulator left by 1 bit.
+jmp $8006 ; And then loop.
+
+.org $FFC0 ; Reset vector.
+.qword $8000
+done
+