diff options
author | mrb0nk500 <b0nk@b0nk.xyz> | 2019-12-08 20:45:55 -0500 |
---|---|---|
committer | mrb0nk500 <b0nk@b0nk.xyz> | 2019-12-08 20:45:55 -0500 |
commit | 3dfde833082fc66cededd0206ae5fc76162867b6 (patch) | |
tree | 70ab1961552731bf58c13e82f57199b817ef8c5f | |
parent | 1e3787256c8fb98c41e3263fe697f30557a895fe (diff) |
Added support for resolving fixup labels.
AKA, referencing a label before it has been declared
yet.
-rw-r--r-- | asmmon.c | 234 | ||||
-rw-r--r-- | opcode.h | 9 | ||||
-rw-r--r-- | sux.c | 204 | ||||
-rw-r--r-- | test/fib.s | 68 | ||||
-rw-r--r-- | test/test-stack.s | 19 | ||||
-rw-r--r-- | test/test-the-tests.s | 32 |
6 files changed, 311 insertions, 255 deletions
@@ -4,7 +4,7 @@ #define debug 1 -#define OPNUM 85 +#define OPNUM 87 #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; \ @@ -54,19 +54,74 @@ struct label *mklabel(const char *name, uint64_t adr, uint8_t def) { return l; } -void use_label(const char *name, uint64_t *adr) { +uint64_t use_label(const char *name, uint64_t adr) { struct label *l = mklabel(name, 0, 0); + adr++; if (l->def) { - *adr = l->adr; + addr[adr] = l->adr & 0xFF; + if (l->adr & 0xFF00) + addr[adr+1] = l->adr >> 8; + if (l->adr & 0xFF000000) { + addr[adr+2] = l->adr >> 16; + addr[adr+3] = l->adr >> 24; + } + if (l->adr & 0xFF00000000000000) { + addr[adr+4] = l->adr >> 32; + addr[adr+5] = l->adr >> 40; + addr[adr+6] = l->adr >> 48; + addr[adr+7] = l->adr >> 56; + } + return l->adr; } else { + printf("oof, label %s, does not exist, yet.\n", name); struct fixup *f = malloc(sizeof(*f)); f->nxt = fixups; - f->adr = *adr; + f->adr = adr; f->l = l; fixups = f; + return adr-1; + } +} +void reslv_fixups(void) { + struct fixup *f; + for (f = fixups; f; f = f->nxt) { + if (f->l->def) { + addr[f->adr] = f->l->adr & 0xFF; + if (f->l->adr & 0xFF00) + addr[f->adr+1] = f->l->adr >> 8; + if (f->l->adr & 0xFF000000) { + addr[f->adr+2] = f->l->adr >> 16; + addr[f->adr+3] = f->l->adr >> 24; + } + if (f->l->adr & 0xFF00000000000000) { + addr[f->adr+4] = f->l->adr >> 32; + addr[f->adr+5] = f->l->adr >> 40; + addr[f->adr+6] = f->l->adr >> 48; + addr[f->adr+7] = f->l->adr >> 56; + } + } else { + printf("oof, undefined reference to '%s', at $%016llx.\n", f->l->name, f->adr); + } + } +} +void viewmem(uint64_t address) { + 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"); } } - int asmmon() { opent opcodes[OPNUM]; /* mne IMM ZM ZMX ZMY ABS IMPL*/ @@ -95,66 +150,68 @@ int asmmon() { SETOP(22, "ANX", 0x24, 0x84, 0x00, 0x00, 0x54, 0x00); SETOP(23, "AAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x25); SETOP(24, "STT", 0x28, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(25, "BPO", 0x00, 0x00, 0x00, 0x00, 0x30, 0x00); - SETOP(26, "ORA", 0x31, 0x3B, 0x00, 0x00, 0x39, 0x00); - SETOP(27, "ORY", 0x32, 0x00, 0x00, 0x00, 0x62, 0x00); - SETOP(28, "OAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x33); - SETOP(29, "ORX", 0x34, 0x94, 0x00, 0x00, 0x64, 0x00); - SETOP(30, "OAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x35); - SETOP(31, "SEI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x38); - SETOP(32, "BNG", 0x00, 0x00, 0x00, 0x00, 0x40, 0x00); - SETOP(33, "XOR", 0x41, 0x4B, 0x00, 0x00, 0x49, 0x00); - SETOP(34, "XRY", 0x42, 0xA2, 0x00, 0x00, 0x72, 0x00); - SETOP(35, "XAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x43); - SETOP(36, "XRX", 0x44, 0xA4, 0x00, 0x00, 0x74, 0x00); - SETOP(37, "XAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x45); - SETOP(38, "CLI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x48); - SETOP(39, "BCS", 0x00, 0x00, 0x00, 0x00, 0x50, 0x00); - SETOP(40, "LSL", 0x51, 0x55, 0x00, 0x00, 0x53, 0x00); - SETOP(41, "SEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x58); - SETOP(42, "STA", 0x00, 0x7B, 0x8B, 0x9B, 0x5B, 0x00); - SETOP(43, "STY", 0x00, 0x7D, 0x8D, 0x00, 0x5D, 0x00); - SETOP(44, "STX", 0x00, 0x7E, 0x00, 0x9E, 0x5E, 0x00); - SETOP(45, "BCC", 0x00, 0x00, 0x00, 0x00, 0x60, 0x00); - SETOP(46, "LSR", 0x61, 0x65, 0x00, 0x00, 0x63, 0x00); - SETOP(47, "CLC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x68); - SETOP(48, "LDA", 0x69, 0x79, 0x89, 0x99, 0x59, 0x00); - SETOP(49, "LDY", 0x6A, 0x7A, 0x8A, 0x00, 0x5A, 0x00); - SETOP(50, "LDX", 0x6C, 0x7C, 0x00, 0x9C, 0x5C, 0x00); - SETOP(51, "BEQ", 0x00, 0x00, 0x00, 0x00, 0x70, 0x00); - SETOP(52, "ROL", 0x71, 0x75, 0x00, 0x00, 0x73, 0x00); - SETOP(53, "SSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x78); - SETOP(54, "BNE", 0x00, 0x00, 0x00, 0x00, 0x80, 0x00); - SETOP(55, "ROR", 0x81, 0x85, 0x00, 0x00, 0x83, 0x00); - SETOP(56, "CSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x88); - SETOP(57, "BVS", 0x00, 0x00, 0x00, 0x00, 0x90, 0x00); - SETOP(58, "MUL", 0x91, 0x95, 0x00, 0x00, 0x93, 0x00); - SETOP(59, "SEV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x98); - SETOP(60, "BVC", 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00); - SETOP(61, "DIV", 0xA1, 0xA5, 0x00, 0x00, 0xA3, 0x00); - SETOP(62, "CLV", 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8); - SETOP(63, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0); - SETOP(64, "CMP", 0xB1, 0xF5, 0x00, 0x00, 0xE5, 0x00); - SETOP(65, "CPY", 0xB2, 0xF2, 0x00, 0x00, 0xE2, 0x00); - SETOP(66, "CAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB3); - SETOP(67, "CPX", 0xB4, 0xF4, 0x00, 0x00, 0xE4, 0x00); - SETOP(68, "CAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB5); - SETOP(69, "ENT", 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00); - SETOP(70, "RTI", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0); - SETOP(71, "INC", 0x00, 0xE3, 0x00, 0x00, 0xE1, 0xC1); - SETOP(72, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2); - SETOP(73, "IAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3); - SETOP(74, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4); - SETOP(75, "IAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC5); - SETOP(76, "DEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1); - SETOP(77, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2); - SETOP(78, "DAY", 0x00, 0xF3, 0x00, 0x00, 0xF1, 0xD3); - SETOP(79, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4); - SETOP(80, "DAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5); - SETOP(81, "JSL", 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00); - SETOP(82, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8); - SETOP(83, "RTL", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0); - SETOP(84, "BRK", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8); + SETOP(25, "TSX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E); + SETOP(26, "BPO", 0x00, 0x00, 0x00, 0x00, 0x30, 0x00); + SETOP(27, "ORA", 0x31, 0x3B, 0x00, 0x00, 0x39, 0x00); + SETOP(28, "ORY", 0x32, 0x00, 0x00, 0x00, 0x62, 0x00); + SETOP(29, "OAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x33); + SETOP(23, "ORX", 0x34, 0x94, 0x00, 0x00, 0x64, 0x00); + SETOP(31, "OAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x35); + SETOP(32, "SEI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x38); + SETOP(33, "TXS", 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(34, "BNG", 0x00, 0x00, 0x00, 0x00, 0x40, 0x00); + SETOP(35, "XOR", 0x41, 0x4B, 0x00, 0x00, 0x49, 0x00); + SETOP(36, "XRY", 0x42, 0xA2, 0x00, 0x00, 0x72, 0x00); + SETOP(37, "XAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x43); + SETOP(38, "XRX", 0x44, 0xA4, 0x00, 0x00, 0x74, 0x00); + SETOP(39, "XAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x45); + SETOP(40, "CLI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x48); + SETOP(41, "BCS", 0x00, 0x00, 0x00, 0x00, 0x50, 0x00); + SETOP(42, "LSL", 0x51, 0x55, 0x00, 0x00, 0x53, 0x00); + SETOP(43, "SEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x58); + SETOP(44, "STA", 0x00, 0x7B, 0x8B, 0x9B, 0x5B, 0x00); + SETOP(45, "STY", 0x00, 0x7D, 0x8D, 0x00, 0x5D, 0x00); + SETOP(46, "STX", 0x00, 0x7E, 0x00, 0x9E, 0x5E, 0x00); + SETOP(47, "BCC", 0x00, 0x00, 0x00, 0x00, 0x60, 0x00); + SETOP(48, "LSR", 0x61, 0x65, 0x00, 0x00, 0x63, 0x00); + SETOP(49, "CLC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x68); + SETOP(50, "LDA", 0x69, 0x79, 0x89, 0x99, 0x59, 0x00); + SETOP(51, "LDY", 0x6A, 0x7A, 0x8A, 0x00, 0x5A, 0x00); + SETOP(52, "LDX", 0x6C, 0x7C, 0x00, 0x9C, 0x5C, 0x00); + SETOP(53, "BEQ", 0x00, 0x00, 0x00, 0x00, 0x70, 0x00); + SETOP(54, "ROL", 0x71, 0x75, 0x00, 0x00, 0x73, 0x00); + SETOP(55, "SSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x78); + SETOP(56, "BNE", 0x00, 0x00, 0x00, 0x00, 0x80, 0x00); + SETOP(57, "ROR", 0x81, 0x85, 0x00, 0x00, 0x83, 0x00); + SETOP(58, "CSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x88); + SETOP(59, "BVS", 0x00, 0x00, 0x00, 0x00, 0x90, 0x00); + SETOP(60, "MUL", 0x91, 0x95, 0x00, 0x00, 0x93, 0x00); + SETOP(61, "SEV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x98); + SETOP(62, "BVC", 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00); + SETOP(63, "DIV", 0xA1, 0xA5, 0x00, 0x00, 0xA3, 0x00); + SETOP(64, "CLV", 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8); + SETOP(65, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0); + SETOP(66, "CMP", 0xB1, 0xF5, 0x00, 0x00, 0xE5, 0x00); + SETOP(67, "CPY", 0xB2, 0xF2, 0x00, 0x00, 0xE2, 0x00); + SETOP(68, "CAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB3); + SETOP(69, "CPX", 0xB4, 0xF4, 0x00, 0x00, 0xE4, 0x00); + SETOP(70, "CAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB5); + SETOP(71, "ENT", 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00); + SETOP(72, "RTI", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0); + SETOP(73, "INC", 0x00, 0xE3, 0x00, 0x00, 0xE1, 0xC1); + SETOP(74, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2); + SETOP(75, "IAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3); + SETOP(76, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4); + SETOP(77, "IAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC5); + SETOP(78, "DEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1); + SETOP(79, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2); + SETOP(80, "DAY", 0x00, 0xF3, 0x00, 0x00, 0xF1, 0xD3); + SETOP(81, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4); + SETOP(82, "DAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5); + SETOP(83, "JSL", 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00); + SETOP(84, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8); + SETOP(85, "RTL", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0); + SETOP(86, "BRK", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8); uint8_t done = 0; uint64_t address = 0x0000; while (!(done & 1)) { @@ -164,7 +221,7 @@ int asmmon() { char mode[3]; opent op; uint8_t addrmode = 0; - uint64_t value; + uint64_t value = 0; char *oprand; char *cmd; char *tmp = malloc(sizeof(char *)*128); @@ -181,26 +238,12 @@ int asmmon() { oprand = strtok(NULL, "\t\n "); strtok_r(ins, ".", &postfix); } - if (strcasecmp(cmd, "quit") == 0 || strcasecmp(cmd, "q") == 0) + 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"); - } + viewmem(address); } if (oprand == NULL && ins == NULL && postfix == NULL) { done |= 2; @@ -245,7 +288,7 @@ int asmmon() { break; } if (isalnum(oprand[i]) || oprand[i] == '_') { - use_label(oprand, &value); + use_label(oprand, address); sprintf(oprand, "%llx", value); break; } @@ -281,6 +324,10 @@ int asmmon() { } } + if (oprand == NULL && !strcasecmp(ins, "TXS")) + addrmode = 1; + else if (oprand != NULL && !strcasecmp(ins, "TXS")) + addr[address++] = 0x17; if (!(done & 2) && oprand != NULL) { if (oprand[0] == '#' || oprand[0] == '$') { if(oprand[0] == '#' && (oprand[1] == '$' || oprand[1] == '%')) { @@ -323,19 +370,20 @@ int asmmon() { break; } if (isalnum(oprand[i]) || oprand[i] == '_') { - use_label(oprand, &value); + value = use_label(oprand, address); if (value == 0) addrmode = 2; - if (value & 0xFFFFFFFF) { + if (value & 0xFFFFFFFF || value == 0) { char *stf[] = {"BPO", "BNG", "BCS", "BCC", "BEQ", "BNE", "BVS", "BVC"}; for (int i = 0; i < 8; i++) { - if (strcasecmp(ins, stf[i]) == 0) { + if (!strcasecmp(ins, stf[i])) { addrmode = 5; break; } else { addrmode = 2; } } + } else if (value & 0xFFFFFFFF00000000) { addrmode = 5; } @@ -362,6 +410,7 @@ int asmmon() { case PLY: case PLX: case STT: + case TXS: case LSL: case LSR: case ROL: @@ -429,6 +478,8 @@ int asmmon() { break; case 1: if (op.imm) { + if (addr[address-1] == 0x17 && op.imm == TXS) + r = 0x17; addr[address++] = op.imm; switch (op.imm) { case PHP: @@ -447,6 +498,13 @@ int asmmon() { case ENT: addr[address++] = value & 0xFF; break; + case TXS: + if (r == 0x17) { + addr[address] = value & 0xFF; + addr[address+2] = value >> 8; + address+=2; + } + break; default: addr[address] = value & 0xFF; if (r & 0x10) @@ -462,7 +520,6 @@ int asmmon() { address+=(1 << ((r & 0x30) >> 4)); break; - } break; } else { @@ -541,5 +598,6 @@ int asmmon() { } } } + reslv_fixups(); return 0; } @@ -29,6 +29,7 @@ #define ANX 0x24 /* bitwise ANd with X register. */ #define AAX 0x25 /* bitwise And with Accumulator, and X register. */ #define STT 0x28 /* STart Threads. */ +#define TSX 0x2E /* Transfer Stack pointer to X. */ #define BPO 0x30 /* Branch if POsitive. */ #define ORA 0x31 /* bitwise OR with Accumulator. */ #define ORY 0x32 /* bitwise OR with Y register. */ @@ -36,6 +37,7 @@ #define ORX 0x34 /* bitwise OR with X register. */ #define OAX 0x35 /* bitwise Or with Accumulator, and X register. */ #define SEI 0x38 /* SEt Interupt flag. */ +#define TXS 0x3E /* Transfer X to Stack pointer. */ #define BNG 0x40 /* Branch if NeGative. */ #define XOR 0x41 /* bitwise XOR with accumulator. */ #define XRY 0x42 /* bitwise XoR with Y register. */ @@ -97,8 +99,6 @@ #define V ((uint64_t)1 << 6) #define N ((uint64_t)1 << 7) -#define STK_STADDR 0x010000 /* Starting address of the stack. */ - struct sux; uint8_t *addr; /* Address Space. */ @@ -108,7 +108,8 @@ struct sux { uint64_t ps; /* The processor status register. */ uint64_t a[8], y[8], x[8]; /* Registers A, X, and Y. */ uint64_t pc[8]; /* Program counter. */ - uint16_t sp; /* Stack pointer. */ + uint16_t sp[8]; /* Stack pointer. */ + uint16_t stk_st[8]; /* Starting address of each threads stack. */ uint8_t crt; /* Current running threads. */ uint8_t c[8], z[8], i[8], s[8], v[8], n[8]; /* Processor Status Flags. */ @@ -154,6 +155,7 @@ static const char *opname[0x100] = { [ANX] = "ANX #", OPNAME(AAX), OPNAME(STT), + OPNAME(TSX), [0x29] = "AND a", [0x2B] = "AND zm", OPNAME(BPO), @@ -163,6 +165,7 @@ static const char *opname[0x100] = { [ORX] = "ORX #", OPNAME(OAX), OPNAME(SEI), + OPNAME(TXS), [0x39] = "ORA a", [0x3B] = "ORA zm", OPNAME(BNG), @@ -14,7 +14,6 @@ uint64_t tclk; /* Total Clock cycles. */ uint64_t inst[THREADS]; uint64_t inss; uint8_t threads_done = 0; -uint8_t lines[THREADS]; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; struct suxthr { @@ -38,7 +37,9 @@ void *run(void *args) { uint64_t value = 0; uint64_t iclk = 0; uint64_t ins = 0; - uint16_t tv = 0xFF50; /* Thread Vector. */ + char *s = malloc(2048); + uint8_t lines = (6*thread)+2; + uint16_t tv = 0xFF50; /* Starting address of the Thread Vectors. */ #if bench gettimeofday(&str[thread], 0); #endif @@ -51,15 +52,16 @@ void *run(void *args) { opcode = addr[cpu->pc[thread]]; #if !bench - printf("\033[%uH", lines[thread]); - printf("pc: 0x%08llx, a: 0x%016llx, x: 0x%016llx, y: 0x%016llx" + sprintf(s, "\033[%uH" + "pc: 0x%08llx, a: 0x%016llx, x: 0x%016llx, y: 0x%016llx" ", sp: 0x%04lx, ps: 0x%016llx, prefix: 0x%02x, opcode: 0x%02x, thread: %u, inst: %s \r" + , lines , cpu->pc[thread], cpu->a[thread], cpu->x[thread], cpu->y[thread] - , cpu->sp, cpu->ps, prefix, opcode, thread, opname[opcode]); - fflush(stdout); - lines[thread]++; - if (lines[thread] > 6*(thread+1)) - lines[thread] = (6*thread)+2; + , cpu->sp[thread], cpu->ps, prefix, opcode, thread, opname[opcode]); + fwrite(s, sizeof(char), strlen(s), stdout); + lines++; + if (lines > 6*(thread+1)) + lines = (6*thread)+2; #endif uint8_t rs = (prefix & 0x30) >> 4; @@ -138,12 +140,10 @@ void *run(void *args) { tmp = 7; for (int8_t i = tmp*8; i >= 0; i-=8) { if (i) - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->ps >> i; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->ps >> i; else - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->ps & 0xFF; - cpu->sp--; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->ps & 0xFF; + cpu->sp[thread]--; } break; case PHA: /* PusH Accumulator to stack. */ @@ -152,12 +152,10 @@ void *run(void *args) { tmp = 7; for (int8_t i = tmp*8; i >= 0; i-=8) { if (i) - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->a[thread] >> i; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->a[thread] >> i; else - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->a[thread] & 0xFF; - cpu->sp--; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->a[thread] & 0xFF; + cpu->sp[thread]--; } break; case PHY: /* PusH Y register to stack. */ @@ -166,12 +164,10 @@ void *run(void *args) { tmp = 7; for (int8_t i = tmp*8; i >= 0; i-=8) { if (i) - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->y[thread] >> i; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->y[thread] >> i; else - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->y[thread] & 0xFF; - cpu->sp--; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->y[thread] & 0xFF; + cpu->sp[thread]--; } break; case TAY: /* Transfer Accumulator to Y. */ @@ -180,6 +176,8 @@ void *run(void *args) { case TYA: /* Transfer Y to Accumulator. */ case TXA: /* Transfer X to Accumulator. */ case TXY: /* Transfer X to Y. */ + case TSX: /* Transfer Stack pointer to X. */ + case TXS: /* Transfer X to Stack pointer. */ if (opcode == TAY) cpu->y[thread] = cpu->a[thread]; if (opcode == TAX) @@ -192,6 +190,18 @@ void *run(void *args) { cpu->a[thread] = cpu->x[thread]; if (opcode == TXY) cpu->y[thread] = cpu->x[thread]; + if (opcode == TSX) { + cpu->x[thread] = cpu->sp[thread] & 0xFFFF; + cpu->x[thread] = cpu->stk_st[thread] << 16; + } + if (opcode == TXS) { + cpu->sp[thread] = cpu->x[thread]; + if (prefix == 0x17 && (value == thread+1 || value > 8)) { + cpu->stk_st[thread] = value & 0xFF; + cpu->stk_st[thread] += value << 16; + cpu->pc[thread]+=2; + } + } if (opcode == TYA || opcode == TXA) { cpu->z[thread] = (cpu->a[thread] == 0); cpu->n[thread] = (cpu->a[thread] >> 63); @@ -213,12 +223,10 @@ void *run(void *args) { tmp = 7; for (int8_t i = tmp*8; i >= 0; i-=8) { if (i) - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->x[thread] >> i; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->x[thread] >> i; else - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->x[thread] & 0xFF; - cpu->sp--; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->x[thread] & 0xFF; + cpu->sp[thread]--; } break; case JMP: /* JMP Absolute. */ @@ -291,13 +299,11 @@ void *run(void *args) { if (tmp > 7) tmp = 7; for (uint8_t i = 0; i < (tmp+1)*8; i+=8) { - cpu->sp++; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; + cpu->sp[thread]++; if (i) - cpu->ps += (uint64_t)addr[STK_STADDR+cpu->sp] << i; + cpu->ps += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; else - cpu->ps = (uint64_t)addr[STK_STADDR+cpu->sp] & 0xFF; + cpu->ps = (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF; } break; case PLA: /* PuLl Accumulator from stack. */ @@ -305,13 +311,11 @@ void *run(void *args) { if (tmp > 7) tmp = 7; for (uint8_t i = 0; i < (tmp+1)*8; i+=8) { - cpu->sp++; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; + cpu->sp[thread]++; if (i) - cpu->a[thread] += (uint64_t)addr[STK_STADDR+cpu->sp] << i; + cpu->a[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; else - cpu->a[thread] = (uint64_t)addr[STK_STADDR+cpu->sp] & 0xFF; + cpu->a[thread] = (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF; } break; case PLY: /* PuLl Y register from stack. */ @@ -319,13 +323,11 @@ void *run(void *args) { if (tmp > 7) tmp = 7; for (uint8_t i = 0; i < (tmp+1)*8; i+=8) { - cpu->sp++; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; + cpu->sp[thread]++; if (i) - cpu->y[thread] += (uint64_t)addr[STK_STADDR+cpu->sp] << i; + cpu->y[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; else - cpu->y[thread] = (uint64_t)addr[STK_STADDR+cpu->sp] & 0xFF; + cpu->y[thread] = (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF; } break; case PLX: /* PuLl X register from stack. */ @@ -333,13 +335,11 @@ void *run(void *args) { if (tmp > 7) tmp = 7; for (uint8_t i = 0; i < (tmp+1)*8; i+=8) { - cpu->sp++; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; + cpu->sp[thread]++; if (i) - cpu->x[thread] += (uint64_t)addr[STK_STADDR+cpu->sp] << i; + cpu->x[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; else - cpu->x[thread] = (uint64_t)addr[STK_STADDR+cpu->sp] & 0xFF; + cpu->x[thread] = (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF; } break; case JSR: /* Jump to SubRoutine. */ @@ -350,12 +350,10 @@ void *run(void *args) { cpu->pc[thread]+=4; for (int8_t i = 24; i >= 0; i-=8) { if (i) - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->pc[thread] >> i; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> i; else - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->pc[thread] & 0xFF; - cpu->sp--; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] & 0xFF; + cpu->sp[thread]--; } cpu->pc[thread] = address; break; @@ -1099,15 +1097,13 @@ void *run(void *args) { break; case RTS: /* ReTurn from Subroutine. */ for (uint8_t i = 0; i < 32; i+=8) { - cpu->sp++; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; + cpu->sp[thread]++; if (i < 24) - cpu->pc[thread] += addr[STK_STADDR+cpu->sp] << i; + cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; else if (i == 24) - cpu->pc[thread] += addr[STK_STADDR+cpu->sp] << i +1; + cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i +1; else - cpu->pc[thread] = addr[STK_STADDR+cpu->sp]; + cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]]; } break; case CMP: /* CMP Immediate. */ @@ -1193,20 +1189,16 @@ void *run(void *args) { cpu->pc[i+1] = cpu->pc[0]+(i+1); break; case RTI: /* ReTurn from Interupt routine. */ - cpu->sp++; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; - cpu->ps = addr[STK_STADDR+cpu->sp] << 8*thread; + cpu->sp[thread]++; + cpu->ps = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 8*thread; for (uint8_t i = 0; i < 64; i+=8) { - cpu->sp++; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; + cpu->sp[thread]++; if (i < 56) - cpu->pc[thread] += addr[STK_STADDR+cpu->sp] << i; + cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; else if (i == 56) - cpu->pc[thread] += addr[STK_STADDR+cpu->sp] << i +1; + cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i +1; else - cpu->pc[thread] = addr[STK_STADDR+cpu->sp]; + cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]]; } break; case INC: /* INC Accumulator. */ @@ -1277,12 +1269,10 @@ void *run(void *args) { cpu->pc[thread]+=8; for (int8_t i = 56; i >= 0; i-=8) { if (i) - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->pc[thread] >> i; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> i; else - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->pc[thread] & 0xFF; - cpu->sp--; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] & 0xFF; + cpu->sp[thread]--; } cpu->pc[thread] = address; break; @@ -1314,15 +1304,13 @@ void *run(void *args) { break; case RTL: /* ReTurn from subroutine Long. */ for (uint8_t i = 0; i < 64; i+=8) { - cpu->sp++; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; + cpu->sp[thread]++; if (i < 56) - cpu->pc[thread] = addr[STK_STADDR+cpu->sp] << i; + cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; else if (i == 56) - cpu->pc[thread] = addr[STK_STADDR+cpu->sp] << i + 1; + cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i + 1; else - cpu->pc[thread] = addr[STK_STADDR+cpu->sp]; + cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]]; } break; case 0xF1: /* DEC Absolute. */ @@ -1352,17 +1340,13 @@ void *run(void *args) { case BRK: /* BReaK. */ for (uint8_t i = 56; i >= 0; i-=8) { if (i) - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->pc[thread]-1 >> i; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread]-1 >> i; else - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->pc[thread]-1 & 0xFF; - cpu->sp--; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; - } - addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->ps >> 8*thread; - cpu->sp--; - addr[0xFF90] = cpu->sp & 0xFF; - addr[0xFF91] = cpu->sp >> 8; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread]-1 & 0xFF; + cpu->sp[thread]--; + } + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->ps >> 8*thread; + cpu->sp[thread]--; cpu->i[thread] = 1; setps(cpu, thread); cpu->pc[thread] = (uint64_t)addr[0xFFE0] @@ -1384,7 +1368,8 @@ void *run(void *args) { } ins++; #if !bench - printf("\033[%uHInstructions executed: %llu, Clock cycles: %llu\n", (6*thread)+1, ins, iclk); + sprintf(s, "\033[%uHInstructions executed: %llu, Clock cycles: %llu\n", (6*thread)+1, ins, iclk); + fwrite(s, sizeof(char), strlen(s), stdout); fflush(stdout); #endif if (ins >= BENCH_INST) { @@ -1400,10 +1385,12 @@ void *run(void *args) { #endif } } + free(s); } int main(int argc, char **argv) { struct suxthr thr[THREADS]; + char *tmp = malloc(2048); ibcount = 0; addr = malloc(0x04000000); inss = 0; @@ -1412,19 +1399,20 @@ int main(int argc, char **argv) { if (asmmon() == 2) return 0; for (int i = 0; i < THREADS; i++) { - thr[i].sx.sp = 0xFFFF; + thr[i].sx.sp[i] = 0xFFFF; + thr[i].sx.stk_st[i] = i+1; if (i) { thr[i].sx.a[i] = 0; thr[i].sx.x[i] = 0; thr[i].sx.y[i] = 0; - thr[i].sx.pc[i] = (uint64_t)addr[0xFF50] - | (uint64_t)addr[0xFF51] << 8 - | (uint64_t)addr[0xFF52] << 16 - | (uint64_t)addr[0xFF53] << 24 - | (uint64_t)addr[0xFF54] << 32 - | (uint64_t)addr[0xFF55] << 40 - | (uint64_t)addr[0xFF56] << 48 - | (uint64_t)addr[0xFF57] << 56; + thr[i].sx.pc[i] = (uint64_t)addr[0xFF50+(8*i)] + | (uint64_t)addr[0xFF51+(8*i)] << 8 + | (uint64_t)addr[0xFF52+(8*i)] << 16 + | (uint64_t)addr[0xFF53+(8*i)] << 24 + | (uint64_t)addr[0xFF54+(8*i)] << 32 + | (uint64_t)addr[0xFF55+(8*i)] << 40 + | (uint64_t)addr[0xFF56+(8*i)] << 48 + | (uint64_t)addr[0xFF57+(8*i)] << 56; } else { thr[i].sx.a[i] = 0; thr[i].sx.x[i] = 0; @@ -1441,12 +1429,13 @@ int main(int argc, char **argv) { thr[i].th = i; } for (int i = 0; i < THREADS; i++) { - lines[i] = (6*i)+2; inst[i] = 0; } pthread_t therads[THREADS]; int result; - puts("\033[2J\033[H"); + sprintf(tmp, "\033[2J\033[H"); + fwrite(tmp, sizeof(char), strlen(tmp), stdout); + fflush(stdout); for (int i = 0; i < THREADS; i++) { result = pthread_create(&therads[i], NULL, run, &thr[i]); assert(!result); @@ -1481,11 +1470,16 @@ int main(int argc, char **argv) { } clkspd = (tm[i]/1000000)*1000000/clk[i]; mhz = 1000000.0/clkspd/1000000; - printf("Instructions executed for thread %i: %llu, Instructions per Second for thread %i in MIPS: %f, tm: %f\n", i, inst[i], i, ips[i], tm[i]/1000000); + sprintf(tmp, "Instructions executed for thread %i: %llu, Instructions per Second for thread %i in MIPS: %f, tm: %f\n", i, inst[i], i, ips[i], tm[i]/1000000); + fwrite(tmp, sizeof(char), strlen(tmp), stdout); + fflush(stdout); } clkspd = (ttm/1000000)*1000000/tclk; mhz = 1000000.0/clkspd/1000000; - printf("Total Instructions executed: %llu, Total Instructions per Second in MIPS: %f, Clock cycles: %llu, Clock Speed in MHz: %f, tm: %f\n", inss, ipst, tclk, mhz, ttm/1000000); + sprintf(tmp, "Total Instructions executed: %llu, Total Instructions per Second in MIPS: %f, Clock cycles: %llu, Clock Speed in MHz: %f, tm: %f\n", inss, ipst, tclk, mhz, ttm/1000000); + fwrite(tmp, sizeof(char), strlen(tmp), stdout); + fflush(stdout); + free(tmp); } #endif free(addr); @@ -7,62 +7,62 @@ ; Variables for thread 0. .org $1000 x: -.qword $0 + .qword $0 y: -.qword $0 + .qword $0 z: -.qword $0 + .qword $0 ; Variables for thread 1. .org $2000 x2: -.qword $0 + .qword $0 y2: -.qword $0 + .qword $0 z2: -.qword $0 + .qword $0 .org $0 init: -cps ; Clear the Processor Status register. + cps ; Clear the Processor Status register. start: -lda #$0 ; Clear the accumulator. -ldy #$1 ; y=1. -sty.q y ; Store y into memory. + lda #$0 ; Clear the accumulator. + ldy #$1 ; y=1. + sty.q y ; Store y into memory. fib: -ldx #$0 ; x=0. -ldx.q x ; Output the value of x. -adc.q y ; Add x with y. -sta.q z ; z=x+y -ldy.q y -sty.q x ; x=y. -sta.q y ; y=z. -lda.q x -bcs start ; Start all over again, if the carry flag was set. -jmp fib ; Otherwise, keep looping. + ldx #$0 ; x=0. + ldx.q x ; Output the value of x. + adc.q y ; Add x with y. + sta.q z ; z=x+y + ldy.q y + sty.q x ; x=y. + sta.q y ; y=z. + lda.q x + bcs start ; Start all over again, if the carry flag was set. + jmp fib ; Otherwise, keep looping. .org $8000 init2: -cps ; Clear the Processor Status register. + cps ; Clear the Processor Status register. start2: -lda #$0 ; Clear the accumulator. -ldy #$1 ; y2=1. -sty.q y2 ; Store y into memory. + lda #$0 ; Clear the accumulator. + ldy #$1 ; y2=1. + sty.q y2 ; Store y into memory. fib2: -ldx #$0 ; x2=0. -ldx.q x2 ; Output the value of x2. -adc.q y2 ; Add x2 with y2. -sta.q z2 ; z2=x2+y2 -ldy.q y2 -sty.q x2 ; x2=y2. -sta.q y2 ; y2=z2. -lda.q x2 -bcs start2 ; Start all over again, if the carry flag was set. -jmp fib2 ; Otherwise, keep looping. + ldx #$0 ; x2=0. + ldx.q x2 ; Output the value of x2. + adc.q y2 ; Add x2 with y2. + sta.q z2 ; z2=x2+y2 + ldy.q y2 + sty.q x2 ; x2=y2. + sta.q y2 ; y2=z2. + lda.q x2 + bcs start2 ; Start all over again, if the carry flag was set. + jmp fib2 ; Otherwise, keep looping. ; Set up the thread vectors. .org $FF50 diff --git a/test/test-stack.s b/test/test-stack.s index 88ed25c..5c7e0fd 100644 --- a/test/test-stack.s +++ b/test/test-stack.s @@ -1,10 +1,25 @@ init: cps +ldx.w #$FFFF +txs +ldx.d #$00 loop: iax -pha #$8 -ply #$8 +pha #$08 +ply #$08 jmp loop + +.org $FFC0 +.qword init +.org $FF50 +.qword init +.qword init +.qword init +.qword init +.qword init +.qword init +.qword init + done diff --git a/test/test-the-tests.s b/test/test-the-tests.s index 314ed45..5f1e255 100644 --- a/test/test-the-tests.s +++ b/test/test-the-tests.s @@ -6,7 +6,7 @@ lstart: lda #$01 lshft: -lsl #$1 +lsl #$01 bcs rstart jmp lshft @@ -18,31 +18,17 @@ lsr #$1 bcs lstart jmp rshft - -.org $8000 -init2: -cps - -lstart2: -lda #$01 - -lshft2: -lsl #$1 -bcs rstart2 -jmp lshft2 - -rstart2: -lda.q #$8000000000000000 - -rshft2: -lsr #$1 -bcs lstart2 -jmp rshft2 - .org $FFC0 .qword init .org $FF50 -.qword init2 +.qword init +.qword init +.qword init +.qword init +.qword init +.qword init +.qword init +.qword init done |