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. --- asmmon.c | 359 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 asmmon.c (limited to 'asmmon.c') 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; +} -- cgit v1.2.3-13-gbd6f