From ca89989d057a19b647514656d96d00ff23be9640 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Sat, 30 Nov 2019 19:57:46 -0500 Subject: 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. --- Makefile | 4 +- asmmon.c | 359 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ opcode.c | 241 +++++++++++++++++++++++++--------------- opcode.h | 37 +++++-- sux.c | 362 +++++++++++++++++++++++++++++++----------------------------- test/test.s | 13 +++ 6 files changed, 742 insertions(+), 274 deletions(-) create mode 100644 asmmon.c create mode 100644 test/test.s 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 + +#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 +#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 +.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 + -- cgit v1.2.3-13-gbd6f