From 59dc46ca8fe1eb6f98abb98fe8579aeaedd2ff15 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Thu, 2 Apr 2020 19:04:12 -0400 Subject: Made the emulator less bloated, and faster. --- asmmon.c | 151 ++++- opcode.h | 64 +-- programs/c-ports/subasm.c | 24 +- programs/c-ports/subeditor.c | 205 ++++++- programs/c-ports/subeditor.h | 19 +- programs/subeditor.s | 1266 ++++++++++++++++++++++-------------------- sux.c | 878 ++++++++++++----------------- test/asr.s | 8 +- test/subroutine.s | 48 +- 9 files changed, 1414 insertions(+), 1249 deletions(-) diff --git a/asmmon.c b/asmmon.c index 8b896cf..3f715ac 100644 --- a/asmmon.c +++ b/asmmon.c @@ -88,22 +88,22 @@ void reslv_fixups(void) { addr[f->adr+7] = f->l->adr >> 56; } } else { - printf("oof, undefined reference to '%s', at $%016llx.\n", f->l->name, f->adr); + 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); + printf("%02X", ind); if (ind < 0x0F) printf(" "); } printf("\n\n"); for (int hi = 0; hi < 0x10; hi++) { - printf("%016llx:\t", (address & ~0xF)+(hi*0x10)); + printf("%016llX:\t", (address & ~0xF)+(hi*0x10)); for (int lo = 0; lo < 0x10; lo++) { - printf("%02x", addr[(address & ~0xF)+lo+(hi*0x10)]); + printf("%02X", addr[(address & ~0xF)+lo+(hi*0x10)]); if (lo < 0x0F) printf(" "); } @@ -310,6 +310,7 @@ int asmmon(const char *fn) { } uint8_t done = 0; uint64_t address = 0x0000; + uint64_t bytecount = 0; uint64_t start, end; uint8_t prefix, opcode; while (!(done & 1)) { @@ -321,6 +322,7 @@ int asmmon(const char *fn) { uint8_t addrmode = IMPL; uint8_t addrtok = 0; uint64_t value = 0; + uint64_t val2 = 0; char *oprand; char *oprand2; char *cmd; @@ -386,6 +388,7 @@ int asmmon(const char *fn) { } } if (!strcasecmp(cmd, "quit") || !strcasecmp(cmd, "q")) { + printf("The total size of the program code is, %llu bytes in decimal, and $%llX bytes in hex.\n", bytecount, bytecount); return 2; } if (!strcasecmp(cmd, "viewmem") || !strcasecmp(cmd, "vm") || !strcasecmp(cmd, "v")) { @@ -588,6 +591,9 @@ int asmmon(const char *fn) { done |= 6; break; } + if (i && ins[i] == '=') { + /*ins = strtok_r(oprand2)*/ + } if (ins[i] == ';') { if (i && (ins[i-1] == ' ' || ins[i-1] == '\t')) ins[i] = '\0'; @@ -797,8 +803,16 @@ int asmmon(const char *fn) { mode[0] = oprand[0]; mode[1] = oprand[1]; strtok_r(oprand, "+-", &oprand2); - if (ir[0] == 'x' || ir[0] == 'y') + if (ir[0] == 'x' || ir[0] == 'y') { oprand2 = strtok_r(oprand2, ",)", &tmp2); + } + if (oprand2 != NULL) { + int i = 0; + for (; (oprand2[i] == '$' || oprand2[i] == '%') || isxdigit(oprand2[i]); i++); + if (i) { + oprand2[i] = '\0'; + } + } uint8_t isimm = oprand[0] == '#'; /* This flag is used for checking if there is a secondary token. */ uint8_t issectok = (oprand[1] == '$' || oprand[1] == '%' || isdigit(oprand[1])); @@ -821,10 +835,15 @@ int asmmon(const char *fn) { else value = strtoull(oprand, NULL, 10); if (mode[0] != '(') { - if ((value & 0xFF0000 || value & 0xFFFF00000000 || value & 0xFFFF0000 || !(value & 0xFF00))) + if ((value & 0xFF0000 || value & 0xFFFF00000000 || value & 0xFFFF0000 || !(value & 0xFF00))) { addrmode = ZM; - else if (value & 0xFF00000000 || value & 0xFF000000000000 || value & 0xFF00000000000000 || (value & 0xFF00)) - addrmode = ABS; + } else if (value & 0xFF00000000 || value & 0xFF000000000000 || value & 0xFF00000000000000 || (value & 0xFF00)) { + if (ir[0] == 'x' || ir[0] == 'y') { + addrmode = ZM; + } else { + addrmode = ABS; + } + } } if (addrmode == ZM || addrmode == IND) { if (value & 0xFFFF00) @@ -879,10 +898,15 @@ int asmmon(const char *fn) { value = use_label(oprand, address); if (!isimm) { if (mode[0] != '(') { - if ((value & 0xFF0000 || value & 0xFFFF00000000 || value & 0xFFFF0000 || !(value & 0xFF00))) + if ((value & 0xFF0000 || value & 0xFFFF00000000 || value & 0xFFFF0000 || !(value & 0xFF00))) { addrmode = ZM; - else if (value & 0xFF00000000 || value & 0xFF000000000000 || value & 0xFF00000000000000 || (value & 0xFF00)) - addrmode = ABS; + } else if (value & 0xFF00000000 || value & 0xFF000000000000 || value & 0xFF00000000000000 || (value & 0xFF00)) { + if (ir[0] == 'x' || ir[0] == 'y') { + addrmode = ZM; + } else { + addrmode = ABS; + } + } } if (addrmode == ZM || addrmode == IND) { if (value & 0xFFFF00) @@ -926,15 +950,21 @@ int asmmon(const char *fn) { } } if (oprand2 != NULL && (addrtok == 1 || addrtok == 2)) { - uint64_t val2 = 0; mode[0] = oprand2[0]; - oprand2 = strtok(oprand2, "$%"); - if (mode[0] == '$') - val2 = strtoull(oprand2, NULL, 16); - else if (mode[0] == '%') - val2 = strtoull(oprand2, NULL, 2); - else + if (mode[0] == '$' || mode[0] == '%') { + oprand2++; + printf("mode[0]: %i, oprand2: %s\n", mode[0], oprand2); + switch (mode[0]) { + case '$': + val2 = strtoull(oprand2, NULL, 16); + break; + case '%': + val2 = strtoull(oprand2, NULL, 2); + break; + } + } else { val2 = strtoull(oprand2, NULL, 10); + } switch (addrtok) { case 1: value += val2; @@ -1023,6 +1053,7 @@ int asmmon(const char *fn) { r = prefix; addr[address] = prefix; address += 1; + bytecount+=1; } else { r = 0; } @@ -1031,6 +1062,7 @@ int asmmon(const char *fn) { case IMPL: if (op.impl || op.impl == CPS) { addr[address++] = op.impl; + bytecount+=1; break; } else { fprintf(stderr, "oof, %s requires an operand.\n", op.mnemonic); @@ -1041,6 +1073,7 @@ int asmmon(const char *fn) { if ((prefix & 0x30) == 0x10 && op.imm == TXS) r = prefix; addr[address++] = op.imm; + bytecount+=1; switch (op.imm) { case PHP: case PHA: @@ -1058,12 +1091,14 @@ int asmmon(const char *fn) { case ASR: case ENT: addr[address++] = value & 0xFF; + bytecount+=1; break; case TXS: if ((r & 0x30) == 0x10) { addr[address] = value & 0xFF; addr[address+2] = value >> 8; address+=2; + bytecount+=2; } break; default: @@ -1083,6 +1118,7 @@ int asmmon(const char *fn) { } address+=r2; + bytecount+=r2; break; } break; @@ -1093,21 +1129,26 @@ int asmmon(const char *fn) { case ZM: if (op.zm) { addr[address++] = op.zm; + bytecount+=1; addr[address] = value & 0xFF; switch ((r & 0x0C) >> 2) { case 2: addr[address+5] = (uint64_t)value >> 40; addr[address+4] = (uint64_t)value >> 32; address += 2; + bytecount+=2; case 3: addr[address+3] = value >> 24; address += 1; + bytecount+=1; case 1: addr[address+2] = value >> 16; addr[address+1] = value >> 8; address += 2; + bytecount+=2; } address += 1; + bytecount+=1; break; } else { fprintf(stderr, "oof, %s does not use Zero Matrix.\n", op.mnemonic); @@ -1116,21 +1157,26 @@ int asmmon(const char *fn) { case ZMX: if (op.zmx) { addr[address++] = op.zmx; + bytecount+=1; addr[address] = value & 0xFF; switch ((r & 0x0C) >> 2) { case 2: addr[address+5] = (uint64_t)value >> 40; addr[address+4] = (uint64_t)value >> 32; address += 2; + bytecount+=2; case 3: addr[address+3] = value >> 24; address += 1; + bytecount+=1; case 1: addr[address+2] = value >> 16; addr[address+1] = value >> 8; address += 2; + bytecount+=2; } address += 1; + bytecount+=1; break; } else { fprintf(stderr, "oof, %s does not use Zero Matrix, indexed with x.\n", op.mnemonic); @@ -1139,21 +1185,26 @@ int asmmon(const char *fn) { case ZMY: if (op.zmy) { addr[address++] = op.zmy; + bytecount+=1; addr[address] = value & 0xFF; switch ((r & 0x0C) >> 2) { case 2: addr[address+5] = (uint64_t)value >> 40; addr[address+4] = (uint64_t)value >> 32; address += 2; + bytecount+=2; case 3: addr[address+3] = value >> 24; address += 1; + bytecount+=1; case 1: addr[address+2] = value >> 16; addr[address+1] = value >> 8; address += 2; + bytecount+=2; } address += 1; + bytecount+=1; break; } else { fprintf(stderr, "oof, %s does not use Zero Matrix, indexed with y.\n", op.mnemonic); @@ -1162,23 +1213,28 @@ int asmmon(const char *fn) { case ABS: if (op.abs) { addr[address++] = op.abs; + bytecount+=1; addr[address] = value & 0xFF; addr[address+1] = value >> 8; switch ((r & 0x0C) >> 2) { case 3: addr[address+7] = value >> 56; address += 1; + bytecount+=1; case 2: addr[address+6] = (uint64_t)value >> 48; addr[address+5] = (uint64_t)value >> 40; address += 2; + bytecount+=2; case 1: addr[address+4] = (uint64_t)value >> 32; addr[address+3] = value >> 24; addr[address+2] = value >> 16; address += 3; + bytecount+=3; } address += 2; + bytecount+=2; break; } else { fprintf(stderr, "oof, %s cannot be an absolute dictator.\n", op.mnemonic); @@ -1187,21 +1243,26 @@ int asmmon(const char *fn) { case IND: if (op.ind) { addr[address++] = op.ind; + bytecount+=1; addr[address] = value & 0xFF; switch ((r & 0x0C) >> 2) { case 2: addr[address+5] = (uint64_t)value >> 40; addr[address+4] = (uint64_t)value >> 32; address += 2; + bytecount+=2; case 3: addr[address+3] = value >> 24; address += 1; + bytecount+=1; case 1: addr[address+2] = value >> 16; addr[address+1] = value >> 8; address += 2; + bytecount+=2; } address += 1; + bytecount+=1; break; } else { fprintf(stderr, "oof, %s cannot use pointers.\n", op.mnemonic); @@ -1210,21 +1271,26 @@ int asmmon(const char *fn) { case INDX: if (op.inx) { addr[address++] = op.inx; + bytecount+=1; addr[address] = value & 0xFF; switch ((r & 0x0C) >> 2) { case 2: addr[address+5] = (uint64_t)value >> 40; addr[address+4] = (uint64_t)value >> 32; address += 2; + bytecount+=2; case 3: addr[address+3] = value >> 24; address += 1; + bytecount+=1; case 1: addr[address+2] = value >> 16; addr[address+1] = value >> 8; address += 2; + bytecount+=2; } address += 1; + bytecount+=1; break; } else { fprintf(stderr, "oof, %s does not use Indexed Indirect.\n", op.mnemonic); @@ -1233,21 +1299,26 @@ int asmmon(const char *fn) { case INDY: if (op.iny) { addr[address++] = op.iny; + bytecount+=1; addr[address] = value & 0xFF; switch ((r & 0x0C) >> 2) { case 2: addr[address+5] = (uint64_t)value >> 40; addr[address+4] = (uint64_t)value >> 32; address += 2; + bytecount+=2; case 3: addr[address+3] = value >> 24; address += 1; + bytecount+=1; case 1: addr[address+2] = value >> 16; addr[address+1] = value >> 8; address += 2; + bytecount+=2; } address += 1; + bytecount+=1; break; } else { fprintf(stderr, "oof, %s does not use Indirect Indexed.\n", op.mnemonic); @@ -1256,16 +1327,46 @@ int asmmon(const char *fn) { } #if debug if (!(done & 6)) { - printf("instruction: %s, ", ins); - printf("addrmode: %s, ", adrmode[addrmode]); + printf("Instruction: %s, ", ins); + printf("Addressing Mode: %s,", adrmode[addrmode]); + switch (addrmode) { + case ZM: + printf(" "); + break; + case IMM: + case ABS: + case ZMX: + case ZMY: + case IND: + printf(" "); + break; + case IMPL: + case INDX: + case INDY: + printf(" "); + break; + } + printf("Address: $%llX", address); #if (!__GLIBC__) || (__TINYC__) - printf("Postfix: %s, ", (postfix != NULL) ? postfix : "none"); + if (postfix != NULL) { #else - printf("Postfix: %s, ", (postfix[0] != '\0') ? postfix : "none"); + if (postfix[0] != '\0') { #endif - printf("Operand: %s, ", (oprand != NULL && !(done & 16)) ? oprand : "none"); - printf("Index Register: %s, ", (ir != NULL && !(done & 32)) ? ir : "none"); - printf("Address: $%llx\n", address); + printf(", Suffix: %s", postfix); + } + if (prefix) { + printf(", Prefix: $%02X", prefix); + } + if (oprand != NULL && !(done & 16)) { + printf(", Operand: %s", oprand); + } + if (addrtok) { + printf(",\tArithmetic mode, and operand: %s, $%llX", (addrtok == 1) ? "+" : "-", val2); + } + if (ir[0] != '\0' && !(done & 32)) { + printf(",\tIndex Register: %s", ir); + } + puts(""); } #endif } diff --git a/opcode.h b/opcode.h index 1a7ae53..47fe125 100644 --- a/opcode.h +++ b/opcode.h @@ -211,8 +211,6 @@ struct sux { 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. */ - }; typedef struct { @@ -231,6 +229,34 @@ typedef struct { opent opcodes[OPNUM]; enum {IMPL, IMM, ZM, ZMX, ZMY, ABS, IND, INDX, INDY}; +enum { + DIR_ORG, + DIR_BYTE, + DIR_WORD, + DIR_DWORD, + DIR_QWORD +}; + +enum { + TOK_DIR, + TOK_LABEL, + TOK_SYM, + TOK_STRING, + TOK_CHAR, + TOK_OPCODE, + TOK_RS, + TOK_COMMENT, + TOK_HEX, + TOK_DEC, + TOK_BIN +}; + +enum { + BASE_HEX, + BASE_DEC, + BASE_BIN +}; + static const char *adrmode[9] = { [0] = "IMPL", [1] = "IMM", @@ -806,37 +832,3 @@ static const char *opname[0x100] = { }; 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, 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, 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, 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); -extern void lsr(struct sux *cpu, uint64_t adr, uint8_t thread); -extern void inc(struct sux *cpu, uint64_t *reg, uint8_t thread); -extern void inc_addr(struct sux *cpu, uint64_t adr, uint8_t thread); -extern void dec(struct sux *cpu, uint64_t *reg, uint8_t thread); -extern void dec_addr(struct sux *cpu, uint64_t adr, uint8_t thread); -extern void stt(struct sux *cpu, uint8_t value); -extern void ent(struct sux *cpu, uint8_t value); -extern void ld(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread, 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, 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); -extern void setps(struct sux *cpu, uint8_t thread); -extern uint64_t immaddr(struct sux *cpu, uint8_t thread, uint8_t size); -extern uint64_t absaddr(struct sux *cpu, uint8_t thread); -extern uint32_t zeromtx(struct sux *cpu, uint8_t thread); -extern uint32_t zeromx(struct sux *cpu, uint8_t thread); -extern uint32_t zeromy(struct sux *cpu, uint8_t thread); diff --git a/programs/c-ports/subasm.c b/programs/c-ports/subasm.c index 89d1507..73bb74c 100644 --- a/programs/c-ports/subasm.c +++ b/programs/c-ports/subasm.c @@ -1,18 +1,7 @@ #include "subeditor.h" -struct line { - uint8_t dir; - uint8_t mne; - uint8_t am; - uint8_t opbase; - uint16_t com; - uint16_t label; - uint64_t op; -}; -char *label[0x1000]; + uint64_t label_addr[0x1000]; -/*char *comment[0x1000];*/ -/*char *string[0x1000];*/ enum dir { DIR_ORG, @@ -52,9 +41,8 @@ enum base { }; -char lexeme[0x100]; +char lexeme[0x200]; uint8_t lex_type; -struct line tokline[0x1000]; uint16_t linenum = 10; static const char *mne_t[90] = { @@ -258,7 +246,7 @@ uint8_t lex(char *str) { uint16_t j = 0; lex_type = 0xFF; uint8_t k = 0; - int line = 40; + int line = 56; int16_t ln = -1; int y, x; char lnum[6]; @@ -333,12 +321,12 @@ uint8_t lex(char *str) { case ';': i++; while (str[i] != '\0') { - lexeme[j++] = str[i++]; + lexeme[j] = str[i]; /*comment[linenum][j] = str[i];*/ - /*j++, i++;*/ + j++, i++; } lexeme[j] = '\0'; - /*comment[linenum][j] = '\0';*/ + comment[linenum][j] = '\0'; lex_type = TOK_COMMENT; break; case '#': diff --git a/programs/c-ports/subeditor.c b/programs/c-ports/subeditor.c index 76ee544..44ca288 100644 --- a/programs/c-ports/subeditor.c +++ b/programs/c-ports/subeditor.c @@ -45,6 +45,7 @@ uint8_t scr_trow = 0; uint8_t scr_tcol = 0; uint16_t scr_ptr = 0; uint16_t scr_ptr2 = 0; +uint16_t scr_ptr3 = 0; uint8_t byte = 0; uint8_t mask = 0; @@ -141,6 +142,62 @@ void clr_cbuf() { } } +#define dir(a) tokline[a].dir +#define mne(a) tokline[a].mne +#define amo(a) tokline[a].am +#define opb(a) tokline[a].opbase +#define com(a) tokline[a].com +#define lab(a) tokline[a].label +#define opc(a) tokline[a].op + +#define tok(a) { \ + dir(a) = 0xFF; \ + mne(a) = 0xFF; \ + amo(a) = 0xFF; \ + opb(a) = 0xFF; \ + com(a) = 0xFFFF; \ + lab(a) = 0xFFFF; \ + opc(a) = 0xFF; \ +} +void clr_tokline() { + uint16_t i = 0; + for (; i < 0x2000;) { + tok(i+0x00); + tok(i+0x01); + tok(i+0x02); + tok(i+0x03); + tok(i+0x04); + tok(i+0x05); + tok(i+0x06); + tok(i+0x07); + tok(i+0x08); + tok(i+0x09); + tok(i+0x0A); + tok(i+0x0B); + tok(i+0x0C); + tok(i+0x0D); + tok(i+0x0E); + tok(i+0x0F); + tok(i+0x10); + tok(i+0x11); + tok(i+0x12); + tok(i+0x13); + tok(i+0x14); + tok(i+0x15); + tok(i+0x16); + tok(i+0x17); + tok(i+0x18); + tok(i+0x19); + tok(i+0x1A); + tok(i+0x1B); + tok(i+0x1C); + tok(i+0x1D); + tok(i+0x1E); + tok(i+0x1F); + i+=0x20; + } +} + void update_pos() { scr_ptr = (scr_row+scr_str)*80; scr_ptr += scr_col; @@ -163,12 +220,26 @@ void rdrw_row() { } scr_col++; if (!buffer[ptr+i]) { - update_pos(); + #if !debug + waddch(scr, ' '); + #endif } } scr_col = 0; } +void rdrw_ln(uint8_t start, uint8_t end) { + uint8_t tmp_row = scr_row; + uint8_t tmp_col = scr_col; + scr_row = start; + for (; scr_row <= end; ) { + rdrw_row(); + ++scr_row; + } + scr_row = tmp_row; + scr_col = tmp_col; +} + void scrl_down() { scr_str++; scr_end++; @@ -201,9 +272,6 @@ void bitpos(uint8_t row) { bit = row & 7; mask = bits[bit]; byte = bitmask >> 3; - #if debug - /*mvwprintw(scr, 2, 0, "bit: $%02X, row: $%02X, byte: $%02X, mask: $%02X, bitmask: $%02X\r", bit, row, byte, mask, bitmask);*/ - #endif } void clrbit (uint8_t row) { @@ -231,28 +299,68 @@ uint8_t getbit() { return (mask & bitabl[byte]); } -void findst() { +uint8_t findst() { + uint8_t line_count = 0; while (getbit()) { + line_count++; scr_row--; if ((int8_t)scr_row < 0) { + line_count--; scr_row++; + break; } } + return line_count; } +void fndend() { + uint16_t i = scr_ptr; + for (; buffer[i] != '\0'; i++); + scr_ptr3 = i; +} + +void findend() { + fndend(); + c = (uint16_t)(scr_ptr3/80); +} + + void shftln(uint16_t src, uint16_t dst, uint8_t flag) { if (!flag) { while (buffer[src] != '\0') { buffer[dst++] = buffer[src]; buffer[src++] = '\0'; } + scr_ptr2 = scr_ptr; + scr_ptr = src; + findend(); + scr_ptr = scr_ptr2; + if ((scr_ptr3 % 80 == 0) && (c > scr_row)) { + clrbit(c); + } } else { while (scr_ptr <= src) { - mvwprintw(scr, 2, 0, "buffer[0x%04X]: $%02X, buffer[0x%04X]: $%02X, src: $%04X, dst: $%04X, scr_ptr: $%04X\r", src, buffer[src], dst, buffer[dst], src, dst, scr_ptr); - wrefresh(scr); + if ((int16_t) src < 0) { + src = 0; + buffer[src] = '\0'; + break; + } buffer[dst--] = buffer[src]; buffer[src--] = '\0'; } + if (buffer[src+1] == '\0') { + buffer[src+1] = ' '; + } + scr_ptr2 = scr_ptr; + scr_ptr = src; + findend(); + scr_ptr = scr_ptr2; + if (buffer[src+1] == ' ') { + buffer[src+1] = '\0'; + } + if (c > scr_row) { + setbit(c); + } } } @@ -262,6 +370,8 @@ void print_char(char ch) { uint8_t is_esc = 0; uint8_t done = 0; uint16_t i = 0; + uint16_t x = 0; + uint16_t y = 0; a = ch; switch (ch) { case 0x1B: @@ -387,6 +497,7 @@ void print_char(char ch) { scr_str = 0; clr_bitabl(); clr_buf(); + clr_tokline(); clr_cbuf(); scr_row = 0; scr_col = 0; @@ -409,7 +520,6 @@ void print_char(char ch) { break; } } - clrbit(scr_row+scr_str); scr_row--; scr_col = 80; update_pos(); @@ -417,23 +527,52 @@ void print_char(char ch) { break; } } - scr_col--; - update_pos(); - buffer[scr_ptr] = 0; + e = 0; + scr_trow = scr_row; + findend(); + scr_row = c; + e = findst(); + buffer[--scr_ptr] = 0; shftln(scr_ptr+1, scr_ptr, 0); #if !debug - wdelch(scr); + int y, x; + getyx(scr, y, x); + if (x > 0) { + wmove(scr, y, x-1); + } + wdelch(scr); #endif + if (e) { + findend(); + scr_tcol = scr_col; + rdrw_ln(scr_row, c); + scr_col = scr_tcol; + } + scr_row = scr_trow; + scr_col--; + update_pos(); break; default: - if (buffer[scr_ptr] != '\0') { - for (i = scr_ptr; buffer[i] != '\0'; i++); - scr_ptr2 = scr_ptr-1; - shftln(i-1, i, 1); - i = 0; + d = 0; + if (buffer[scr_ptr] != '\0' && !b) { + fndend(); + scr_ptr3++; + shftln(scr_ptr3-2, scr_ptr3-1, 1); + scr_trow = scr_row; + scr_tcol = scr_col; + a = ch; + buffer[scr_ptr] = ch; + findend(); + scr_row = c; + findst(); + rdrw_ln(scr_row, c); + scr_row = scr_trow; + scr_col = scr_tcol; + update_pos(); + } else { + a = ch; + buffer[scr_ptr] = ch; } - a = ch; - buffer[scr_ptr] = ch; scr_col++; #if !debug waddch(scr, ch); @@ -457,19 +596,26 @@ void print_char(char ch) { uint8_t getkey(char ch) { e = 0; + b = 0; if (ch == '\n') { uint16_t i = 0; uint16_t ptr; + scr_trow = scr_row; + findend(); + scr_row = c; e = scr_row; - findst(scr_row); + findst(); ptr = (scr_row+scr_str)*80; for (;buffer[ptr+i] != '\0';i++) { cmd_buf[i] = buffer[ptr+i]; } + if (e <= 23) { + scr_row = e; + } else { + scr_row = 23; + } } - if (e) { - scr_row = e; - } + print_char(ch); wrefresh(scr); if (a == '\n') { @@ -481,9 +627,11 @@ uint8_t getkey(char ch) { void print_str(const char *str) { uint16_t i = 0; + b = 1; for (;str[i] != '\0'; i++) { print_char(str[i]); } + b = 0; } uint8_t dabbed() { @@ -525,6 +673,7 @@ int main() { cmd_buf = malloc(0x400); clr_bitabl(); clr_buf(); + clr_tokline(); uint8_t end = 0; uint8_t next = 1; char ch; @@ -541,6 +690,7 @@ int main() { #define maxline 24 #endif uint8_t ln = 0; + int row, col; mvwprintw(scr, ln++, 0, "scr_row: $%02X, scr_col: $%02X\r", scr_row, scr_col); mvwprintw(scr, ln++, 0, "scr_str: $%02X, scr_end: $%02X, scr_ptr: $%04X\r", scr_str, scr_end, scr_ptr); wmove(scr, ++ln, 0); @@ -550,6 +700,15 @@ int main() { for (uint16_t i = 0; i < maxline; i++) { for (uint16_t j = 0; j < 80; j++) { wprintw(scr, "%02x", buffer[(j+(i*80))]); + if (j == scr_col && i == scr_row) { + getyx(scr, row, col); + wmove(scr, ln++, 0); + wclrtoeol(scr); + wmove(scr, row+1, col-2); + wprintw(scr, "/\\\r"); + wmove(scr, row, col); + wrefresh(scr); + } } wprintw(scr, ", i: $%02X\r", i); wmove(scr, ln++, 0); diff --git a/programs/c-ports/subeditor.h b/programs/c-ports/subeditor.h index ddb8947..452dfb3 100644 --- a/programs/c-ports/subeditor.h +++ b/programs/c-ports/subeditor.h @@ -4,11 +4,12 @@ #include #include -#define debug 0 +#define debug 1 #define debug_cmd_buf 0 extern WINDOW *scr; +/* SuBEditor Stuff. */ extern char *buffer; extern char *cmd_buf; @@ -35,6 +36,22 @@ extern uint8_t scr_str; extern uint8_t scr_end; extern uint8_t wrapped; +/* SuBAsm Stuff. */ +struct line { + uint8_t dir; + uint8_t mne; + uint8_t am; + uint8_t opbase; + uint16_t com; + uint16_t label; + uint64_t op; +}; + +char *label[0x1000]; +char *comment[0x1000]; +char *str[0x1000]; +struct line tokline[0x1000]; + extern void print_str(const char *str); extern int str_cmp(const char *s0, const char *s1); extern uint8_t subasm(); diff --git a/programs/subeditor.s b/programs/subeditor.s index 1001f83..eaecab5 100644 --- a/programs/subeditor.s +++ b/programs/subeditor.s @@ -3,8 +3,8 @@ ; Writen in Sux assembly by ; mr b0nk 500 +.org $A000 ; String Literals/Constants. -.org $1000 tok: .byte "dab" msg: @@ -15,7 +15,6 @@ string2: .byte "You typed, " ; Linewrap bitmask table. -.org $1100 bits: .byte $80 .byte $40 @@ -73,11 +72,11 @@ bitabl: .qword $0 .qword $0 scr_str: -.byte $0 + .byte $0 scr_end: -.byte $0 + .byte $0 wrapped: -.byte $0 + .byte $0 ; Pointers ptr: @@ -92,471 +91,503 @@ ptr5: .qword $0 ptr6: .qword $0 +scr_ptr3: + .word $0 ; Main program .org $8000 reset: - cps - ldx.w #$FFFF - txs - ldy #0 - tyx - lda #23 - sta scr_end - lda.w #buffer - sta.q ptr5 - lda.w #cmd_buf - sta.q ptr6 - tya - sta scr_str - sta.q bitabl - sta.q bitabl+8 - jsl clr_buf - jmp start + cps ; Reset the processor status register. + ldx.w #$FFFF ; Reset the stack pointer. + txs ; + ldy #0 ; Reset the Y register. + tyx ; Reset the X register. + lda #23 ; Set the end of the screen back to 23. + sta scr_end ; + lda.w #buffer ; Place the address for the screen buffer + sta.q ptr5 ; into one of the pointers. + lda.w #cmd_buf ; Place the address for the command buffer + sta.q ptr6 ; into one of the pointers. + tya ; Reset the Accumulator. + sta scr_str ; Set the start of the screen back to zero. + sta.q bitabl ; Reset the first half of the linewrap table. + sta.q bitabl+8 ; Reset the second half of the linewrap table. + jsl clr_buf ; Clear the screen buffer. + jmp start ; Goto the start of the main program. clr_buf: - phb #1 - ldb #0 + phb #1 ; Preserve whatever was in B. + ldb #0 ; Clear B. + lda.w #buffer+8 ; + sta.q ptr4 ; + tba ; clr_buf_st: - cpy.w #$1FFF - bcs clr_buf_end - sta.q (ptr5), y - tya - adc #8 - tay - tba - sta.q (ptr5), y - tya - adc #8 - tay - tba - sta.q (ptr5), y - tya - adc #8 - tay - tba - sta.q (ptr5), y - tya - adc #8 - tay - tba - jmp clr_buf_st + cpy.w #$1FFF ; Did we clear all of the screen buffer? + bcs clr_buf_end ; Yes, so we're done. + sta.q (ptr5), y ; No, so clear eight bytes. + sta.q (ptr4), y ; Clear eight more bytes. + tya ; Copy the buffer index. + adc #$10 ; Increment the index by 16. + tay ; Update the index. + tba ; Reset the Accumulator. + sta.q (ptr5), y ; Do this one more time, to clear 32 bytes. + sta.q (ptr4), y ; + tya ; + adc #$10 ; + tay ; + tba ; + jmp clr_buf_st ; Keep looping. clr_buf_end: - ldy.w zero - plb #1 - rtl + ldy.w zero ; Set the index back to zero. + plb #1 ; Get whatever was in the B register, back. + rtl ; End of clr_buf. start: - lda #0 - sta $C000 - tax - phy #2 - tay - jsl clr_cbuf - ply #2 - ;lda #1 - ;sta $C010 - lda.w #string - jsl print_str - lda.w zero - jmp rset_a + lda #0 ; TODO: Update this for the Super VIA. + sta end ; + sta $C000 ; Clear the controll register of the I/O adapter. + tax ; Reset X. + phy #2 ; Save the cursor index for later. + tay ; Reset the cursor index. + jsl clr_cbuf ; Clear the command buffer. + ply #2 ; Get back the cursor index. + lda.w #string ; Print the startup message. + jsl print_str ; + lda.w zero ; Reset the Accumulator. + jmp read ; Start reading the keyboard. clr_cbuf: - phb #1 - ldb #0 + phb #1 ; Start of callee preservation. + ldb #0 ; Reset the B register. + lda.w #cmd_buf+8; + sta.q ptr4 ; + tba ; clr_cbuf_st: - cpy.w #$3FF - bcs clr_cbuf_end - sta.q (ptr6), y - tya - adc #8 - tay - tba - sta.q (ptr6), y - tya - adc #8 - tay - tba - sta.q (ptr6), y - tya - adc #8 - tay - tba - sta.q (ptr6), y - tya - adc #8 - tay - tba - jmp clr_cbuf_st -clr_cbuf_end: - plb #1 - rtl + cpy.w #$3FF ; Did we clear all of the command buffer? + bcs clr_cbuf_nd ; Yes, so we're done. + sta.q (ptr6), y ; No, so clear eight bytes. + sta.q (ptr4), y ; Clear eight more bytes. + tya ; Copy the buffer index. + adc #$10 ; Increment the index by 16. + tay ; Update the index. + tba ; Reset the Accumulator. + sta.q (ptr6), y ; Do this one more time, to clear 32 bytes. + sta.q (ptr4), y ; + tya ; + adc #$10 ; + tay ; + tba ; + jmp clr_cbuf_st ; Keep looping. +clr_cbuf_nd: + plb #1 ; End of callee preservation. + rtl ; End of clr_cbuf. -pull_y: - ply #2 -rset_a: - lda #0 - sta $C000 - inc read: - lda $C000 ; Get control register. - beq rset_a ; Loop until we get a character. - jsl getchar ; We got a key. - beq parse ; We got a newline, so start parsing the line. - jmp rset_a ; We didn't get a newline, so keep getting more characters. + lda $C000 ; Did we get a key? + beq read ; No, so try again. + jsl getchar ; Yes, and was it a newline? + beq parse ; Yes, so start parsing the line. + jmp read ; No, so keep looping. print_str: - sta.q ptr - ldb #0 - tba - inb - stb b + sta.q ptr ; Place the string pointer into the main pointer. + ldb #0 ; Clear the B register. + tba ; Clear the Accumulator. + inb ; Enable replace mode. + stb b ; pntstr_st: - phy #2 - txy - lda (ptr), y ; Get character at offset x. - beq pntstr_end ; Did we find a null terminator? - ply #2 - inx - jsl print_char - jmp pntstr_st + phy #2 ; Save the cursor index. + txy ; Copy the string index into Y. + lda (ptr), y ; Are we at the end of the string? + beq pntstr_end ; Yes, so we're done. + ply #2 ; No, so get the cursor index back. + inx ; Increment the string index. + jsl print_char ; Print the character. + jmp pntstr_st ; Keep looping. pntstr_end: - ply #2 - ldb #0 - stb b - rtl - + ply #2 ; Get the cursor index back. + ldb #0 ; Enable insert mode. + stb b ; + rtl ; End of print_str. getbit: - clc - lda scr_str - bne getbt0 - ldx scr_row - jmp getbt1 + clc ; Clear the carry flag. + lda scr_str ; Has the screen been scrolled? + bne getbt0 ; Yes, so add the screen offset to the current line number. + ldx scr_row ; No, so just use the current line number. + jmp getbt1 ; Start getting the bit. getbt0: - lda scr_row - adc scr_str - tax + lda scr_row ; Get the current line number. + adc scr_str ; Add the screen offset to it. + tax ; Use it as the wrap index. getbt1: - jsl bitpos - ldb bitabl, x - aba - cmp #1 - jmp bitout + jsl bitpos ; Get the bit, and byte position. + ldb bitabl, x ; Get one byte of the wrap table. + aba ; Mask out the bit of the current line number. + cmp #1 ; Set the carry flag, if true. + jmp bitout ; We are done. clrbit: - jsl bitpos - xor #$FF - ldb bitabl, x - aba + jsl bitpos ; Get the bit, and byte position. + xor #$FF ; Invert the bitmask. + ldb bitabl, x ; Get one byte of the wrap table. + aba ; Clear the bit of the current line number. bitsav: - sta bitabl, x + sta bitabl, x ; Update the wrap table. bitout: - ldx bitmask - rtl + ldx bitmask ; Return the bitmask. + rtl ; We are done. setbit: - jsl bitpos - ldb bitabl, x - oab - jmp bitsav + jsl bitpos ; Get the bit, and byte position. + ldb bitabl, x ; Get one byte of the wrap table. + oab ; Set the bit of the current line number. + jmp bitsav ; Save the bit. bitpos: - pha #1 - lda.w #bits - sta.q ptr3 - lda.w zero - pla #1 - stx bitmask - txa - and #7 - phy #2 - tay - tax - lda (ptr3), y - ply #2 - pha #1 - lda bitmask - lsr #3 - tax - pla #1 - rtl - + pha #1 ; Save the parameter. + lda.w #bits ; Place the address of the bitmask table, + sta.q ptr3 ; in the third pointer. + lda.w zero ; Clear the Accumulator. + pla #1 ; Get the parameter back. + stx bitmask ; Make the line number the bitmask. + txa ; Copy it to the Accumulator. + and #7 ; Get the bit position. + phy #2 ; Save the cursor index. + tay ; Use the bit position as the index. + tax ; Copy it into X. + lda (ptr3), y ; Get the bitmask. + ply #2 ; Get back the cursor index. + pha #1 ; Save the bitmask. + lda bitmask ; Get the line number. + lsr #3 ; Get the byte position. + tax ; Copy it into X. + pla #1 ; Get back the bitmask. + rtl ; End of bitpos. getchar: lda $C002 ; Get typed character. - ldb #0 - stb e - stb b - pha #1 - phy #2 - cmp #10 - beq cmd_cpy + ldb #0 ; + stb e ; + stb b ; + pha #1 ; + phy #2 ; + cmp #10 ; + beq cmd_cpy ; getchar_pnt: - ply #2 - pla #1 - ldb e - bne reset_row -getchar_pnt1: - jsl print_char - lda a - cmp #10 - beq getchar_line - jmp getchar_char + ply #2 ; + pla #1 ; + ldb e ; + bne reset_row ; +getchar_pt1: + jsl print_char ; + lda a ; + cmp #10 ; + beq getchar_ln ; + jmp getchar_chr ; reset_row: - ldb e - stb scr_row - jmp getchar_pnt1 - + ldb e ; + cpb #23 ; + beq reset_row2 ; + bcs reset_row1 ; + jmp reset_row2 ; +reset_row1: + ldb #23 ; +reset_row2: + stb scr_row ; + jmp getchar_pt1 ; cmd_cpy: - ldb scr_row - stb e - jsl findst - clc - lda scr_row - adc scr_str - mul #80 - tay - ldx.w #$0 -cmd_cpy_strt: - lda (ptr5), y - beq getchar_pnt - phy #2 - txy - sta (ptr6), y - inx - ply #2 - iny - jmp cmd_cpy_strt -getchar_line: - lda #0 - jmp getchar_end -getchar_char: - lda #1 + lda scr_row ; + sta scr_trow ; + jsl findend ; + sta scr_row ; + sta e ; + jsl findst ; + clc ; + lda scr_row ; + adc scr_str ; + mul #80 ; + tay ; + ldx.w #$0 ; +cmd_cpy_st: + lda (ptr5), y ; + beq getchar_pnt ; + phy #2 ; + txy ; + sta (ptr6), y ; + inx ; + ply #2 ; + iny ; + jmp cmd_cpy_st ; +getchar_ln: + lda #0 ; + jmp getchar_end ; +getchar_chr: + lda #1 ; getchar_end: - rtl + rtl ; findst: - jsl getbit - bcc findst_done - dec scr_row - bpo findst - inc scr_row + lda #0 ; +findst_lp: + pha #1 ; + jsl getbit ; + pla #1 ; + bcc findst_done ; + inc ; + dec scr_row ; + bpo findst_lp ; + dec ; + inc scr_row ; findst_done: - rtl + cmp #0 ; + rtl ; + +fndend: + phy #2 ; +fndend_lp: + lda (ptr5), y ; Are we at the end of the string? + beq fndend_done ; Yes, so we're done. + iny ; No, so increment the cursor index. + jmp fndend_lp ; Keep looping. +fndend_done: + sty.w scr_ptr3 ; + ply #2 ; + rtl ; End of fndend. + +findend: + jsl fndend ; + lda.w scr_ptr3 ; + div #80 ; + rtl ; parse: - lda #0 - tax - jsl dabbed - beq start - lda #0 - tax - jmp result + lda #0 ; + tax ; + jsl dabbed ; + beq start ; + lda #0 ; + tax ; + jmp result ; print_char: - sta a - cmp #$1B - beq esc - cmp #$A + sta a ; + cmp #$1B ; + beq esc ; + cmp #$A ; beq nl ; Did the user type a newline? - cmp #$C - beq clr_scr - cmp #19 - beq en_step - cmp #18 - beq dis_step - cmp #8 + cmp #$C ; + beq clr_scr ; + cmp #19 ; + beq en_step ; + cmp #18 ; + beq dis_step ; + cmp #8 ; beq bs ; Did the user type a backspace? - cmp #$7F + cmp #$7F ; beq bs ; Did the user type a backspace? - sta a + sta a ; printc: + lda #0 ; + sta d ; lda (ptr5), y ; Are we at the end of the string? beq printc_save ; Yes, so just print the character. lda b ; No, but was the flag set? bne printc_save ; Yes, so don't shift the line. sty.w scr_ptr ; No, so save the cursor index for later. -prntc_fndnd: - lda (ptr5), y ; Are we at the end of the string? - beq prntc_movln ; Yes, so make room for the next character. - iny ; No, so increment the cursor index. - jmp prntc_fndnd ; Keep looping. -printc_updt: - jmp prntc_updt2 -prntc_updt1: - pla #1 - clc - adc scr_row - sta scr_row - jsl update_pos + jsl fndend ; + jmp prntc_movln ; +prntc_updt: + lda scr_col ; + sta scr_tcol ; prntc_updt2: - lda scr_row - pha #1 - lda scr_col - pha #1 - jsl rdrw_row - pla #1 - sta scr_col - pla #1 - sta scr_row - jsl update_pos + jsl findend ; + sta e ; + sta scr_row ; + jsl findst ; + lda scr_row ; prntc_updt3: - ldb scr_row - lda scr_trow - sec - sab - pha #1 - tab - sec - sab - clc - sta scr_row -prntc_updt4: - jsl getbit - bcs prntc_updt1 - pla #1 - lda scr_trow - sta scr_row - jsl update_pos - dec d - jmp printc_sav1 + sta f ; + jsl rdrw_ln ; + lda scr_trow ; + sta scr_row ; + lda scr_tcol ; + sta scr_col ; + jsl update_pos ; + dec d ; + jmp printc_sav1 ; prntc_movln: - tyx - dey - ldb #1 - stb d - jsl shftln - ldb #1 - stb d - lda scr_row - sta scr_trow + ldy.w scr_ptr3 ; + inc scr_ptr3 ; + tyx ; + dey ; + ldb #1 ; + stb d ; + jsl shftln ; + ldb #1 ; + stb d ; + lda a ; + sta (ptr5), y ; store typed character into the input buffer. + lda scr_row ; + sta scr_trow ; + jmp prntc_updt ; printc_save: - ldb d - bne printc_updt + ldb d ; + bne prntc_updt ; printc_sav1: - lda a - sta (ptr5), y ; Store typed character into the input buffer. + lda a ; + sta (ptr5), y ; store typed character into the input buffer. printc_inc: inc scr_col ; Increment the cursor's x coordinate. - iny + iny ; printc_2: - ldb #1 - stb f - ldb scr_col - cpb #80 - bcs printc_4 + ldb #1 ; + stb f ; + ldb scr_col ; + cpb #80 ; + bcs printc_4 ; printc_3: sta $C001 ; Echo typed character. - ldb f - beq printc_wrap - jmp printc_end + ldb f ; + beq printc_wrap ; + jmp printc_end ; printc_4: - ldb scr_row - cpb #23 - bcs printc_scrl + ldb scr_row ; + cpb #23 ; + bcs printc_scrl ; printc_5: - ldb #0 - stb f - jmp printc_3 + ldb #0 ; + stb f ; + jmp printc_3 ; printc_scrl: sta $C001 ; Echo typed character. - clc - lda #1 - sta wrapped - jsl scrl_down + clc ; + lda #1 ; + sta wrapped ; + jsl scrl_down ; printc_wrap: - ldb #0 - stb scr_col - ldb scr_row - cpb #23 - bcs printc_wrap2 + ldb #0 ; + stb scr_col ; + ldb scr_row ; + cpb #23 ; + bcs printc_wrp2 ; printc_wrap1: - inc scr_row -printc_wrap2: - phx #2 - clc - lda scr_row - adc scr_str - tax - jsl setbit - plx #2 - jsl update_pos + inc scr_row ; +printc_wrp2: + phx #2 ; + clc ; + lda scr_row ; + adc scr_str ; + tax ; + jsl setbit ; + plx #2 ; + jsl update_pos ; printc_end: - rtl + rtl ; nl: - lda #0 - ldb (ptr5), y - bne nl1 + lda #0 ; + ldb (ptr5), y ; + bne nl1 ; sta (ptr5), y ; Store said terminator into the input buffer. nl1: - sta scr_col - lda scr_row - cmp #23 - bne nl_inc - jsl scrl_down - lda #10 - sta a - jmp printc_end + sta scr_col ; + lda scr_row ; + cmp #23 ; + bcc nl_inc ; + jsl scrl_down ; + lda #10 ; + sta a ; + jmp printc_end ; nl_inc: - inc scr_row - jsl update_pos - lda #10 - sta a - jmp printc_end + inc scr_row ; + jsl update_pos ; + lda #10 ; + sta a ; + jmp printc_end ; clr_scr: - lda #23 - sta scr_end - lda #0 - sta scr_str - sta.q bitabl - sta.q bitabl+8 - tay - jsl clr_buf - tay - jsl clr_cbuf - sta scr_col - sta scr_row - jsl update_pos - lda #$C - sta $C001 - jmp printc_end + lda #23 ; + sta scr_end ; + lda #0 ; + sta scr_str ; + sta.q bitabl ; + sta.q bitabl+8 ; + tay ; + jsl clr_buf ; + tay ; + jsl clr_cbuf ; + sta scr_col ; + sta scr_row ; + jsl update_pos ; + lda #$C ; + sta $C001 ; + jmp printc_end ; en_step: - lda $C010 - beq step_en - jmp stp_end + lda $C010 ; + beq step_en ; + jmp printc_end ; step_en: - lda #1 - sta $C010 - jmp stp_end + lda #1 ; + sta $C010 ; + jmp printc_end ; dis_step: - lda $C010 - bne step_dis - jmp stp_end + lda $C010 ; + bne step_dis ; + jmp printc_end ; step_dis: - lda #0 - sta $C010 -stp_end: - jmp printc_end + lda #0 ; + sta $C010 ; + jmp printc_end ; back: + ldb #0 ; + stb e ; + stb f ; + lda scr_row ; + sta scr_trow ; + jsl findend ; + sta scr_row ; +back0: + jsl findst ; + beq back1 ; + bcs back_updt ; + lda scr_trow ; + sta scr_row ; +back1: dey ; Decrement the buffer's offset. lda #0 ; Place a null terminator sta (ptr5), y ; into the buffer. tyx ; Copy the current cursor index to X. iny ; Increment cursor index. - ldb #0 - stb d - jsl shftln ; Move/Shift line back by one character. + ldb #0 ; + stb d ; + jsl shftln ; Shift line back by one character. lda #$7F ; Print a backspace to the screen. sta $C001 ; + lda e ; + beq back3 ; +back2: + jsl findend ; + sta e ; + lda scr_col ; + sta scr_tcol ; + jsl rdrw_ln ; + lda scr_tcol ; + sta scr_col ; +back3: + lda scr_trow ; + sta scr_row ; dec scr_col ; Move the cursor back by one column, jsl update_pos ; and update it's position. jmp printc_end ; We are done. +back_updt: + lda scr_row ; + sta f ; + inc e ; + jmp back1 ; bs: lda scr_col ; Are we at the far left of the screen? @@ -585,20 +616,20 @@ backwrp: tax ; Transfer that into X. backwrp2: dec scr_row ; Move up by one row. - jsl clrbit ; Clear the wrap bit for this row. +; jsl clrbit ; Clear the wrap bit for this row. ldb #80 ; Move the cursor to the absolute right of the screen. stb scr_col ; jsl update_pos ; Update the cursor's position. jmp back ; Delete the previous character. shftln: - ldb d ; Is the flag set? - beq shftln_lp1 ; Yes, so shift, and increment. - jmp shftln_lp0 ; No, so shift, and decrement. + ldb d ; Is the flag not set? + beq shftln_lp1 ; Yes, so shift, and decrement. + ldb #0 ; Clear the B register. + jmp shftln_lp0 ; No, so shift, and increment. shftln_neg: ldy.w zero ; Set the source poition to 0. - lda #0 ; Clear the character - sta (ptr5), y ; that is in the source. + stb (ptr5), y ; Clear the character that is in the source. jmp shftln_end ; We are done. shftln_lp0: sty.w scr_ptr2 ; Save the source position for later. @@ -613,26 +644,61 @@ shftln_lp01: txy ; Set our position to the destination. sta (ptr5), y ; Place the character from the source position, to the destination position. ply #2 ; Set our position back to the source. - lda #0 ; Clear the character - sta (ptr5), y ; that is in the source. - dey ; Decrement the source position. + stb (ptr5), y ; Clear the character that is in the source. bng shftln_neg ; The source underflowed, so set it back to zero, + dey ; Decrement the source position. dex ; Decrement the destination position. jmp shftln_lp0 ; Keep looping. shftln_lp1: + stx.w scr_ptr2 ; Save the destination position for later. lda (ptr5), y ; Is the character at the source position, a null terminator? - beq shftln_end ; Yes, so we're done. + beq shftln_end1 ; Yes, so we're done. phy #2 ; No, so save the source position for later. txy ; Set our position to the destination. sta (ptr5), y ; Place the character from the source position, to the destination position. inx ; Increment the destination position. ply #2 ; Set our position back to the source. - lda #0 ; Clear the character - sta (ptr5), y ; that is in the source. + stb (ptr5), y ; Clear the character that is in the source. iny ; Increment the source position. jmp shftln_lp1 ; Keep looping. +shftln_wrap: + tax ; Use the ending line as a parameter for setbit. + jsl setbit ; Set the wrap bit of the ending line. + jmp shftln_end2 ; We are done. +shftln_wrp1: + tax ; Use the ending line as a parameter for clrbit. + jsl clrbit ; Clear the wrap bit of the ending line. + jmp shftln_end2 ; We are done. shftln_end: - rtl ; We are done. + lda (ptr5), y ; Is this character a null terminator? + bne shftln_nd0 ; No, so just find the end of the line. + lda #$20 ; Yes, so convert it to a space for now. + sta (ptr5), y ; +shftln_nd0: + jsl findend ; Find the ending line. + sta d ; Save ending line for later. + lda (ptr5), y ; Is this character a space? + cmp #$20 ; + bne shftln_nd1 ; No, so skip the conversion. + lda #0 ; Yes, so convert it back to zero. + sta (ptr5), y ; +shftln_nd1: + lda d ; Get the ending line. + cmp scr_row ; Is the ending line greater than the starting line? + beq shftln_end2 ; No, so we're done. + bcs shftln_wrap ; Yes, so set the wrap bit. + jmp shftln_end2 ; No, so we're done. +shftln_end1: + jsl findend ; Find the ending line. + cpb #0 ; Is the remainder zero? + beq shftln_nd01 ; Yes, so check if the ending line is greater than the starting line. + jmp shftln_end2 ; No, so we're done. +shftln_nd01: + cmp scr_row ; Is the ending line greater than the starting line? + beq shftln_end2 ; No, so we're done. + bcs shftln_wrp1 ; Yes, so clear the wrap bit. +shftln_end2: + rtl ; End of shftln. esc: lda $C000 ; Get the next character. @@ -657,9 +723,9 @@ esc: bne esc_end ; Yes, so we're done. jsl isright ; No, so check if the user pressed right. esc_end: - lda #0 ; Set the D pseudo register to zero. + lda #0 ; Clear the D pseudo register. sta d ; - jmp printc_end ; Go back to getting user input. + jmp printc_end ; We are done. shftesc: lda $C000 ; Skip the '['. @@ -667,22 +733,22 @@ shftesc: beq printc_end ; We have an error, so discard it, and go back to getting user input. lda $C002 ; Get the escape code. sta c ; Store the escape code, until we need it. - lda #0 ; + lda #0 ; Use the D pseudo register as a skip flag. sta d ; jsl isshftup ; Check if the user pressed shift+up. - lda d ; - bne shftesc_end ; - jsl isshftdown ; Check if the user pressed shift+down. + lda d ; Was it successful? + bne shftesc_end ; Yes, so we're done. + jsl isshftdown ; No, so check if the user pressed shift+down. shftesc_end: - lda #0 ; + lda #0 ; Clear the D pseudo register. sta d ; - jmp printc_end ; Go back to getting user input. + jmp printc_end ; We are done. isup: lda c ; No, so load the escape code back into the accumulator. cmp #$41 ; Did the user press the up arrow key? - bne isup_done ; Yes, so we're done. - lda scr_row ; No, so is the cursor at the top of the screen? + bne isup_done ; No, so we're done. + lda scr_row ; Yes, but is the cursor at the top of the screen? beq isup_scrl ; Yes, so check if we need to scroll. isup_2: lda c ; No, so load the escape code back into the accumulator. @@ -693,16 +759,18 @@ isup_scrl: lda scr_str ; Are we at the top of the screen buffer? beq isup_done ; Yes, so we're done. jsl scrl_up ; No, so scroll up. + lda #1 ; Tell the escape routine that we were successful. + sta d ; isup_done: rtl ; End of isup. isdown: lda c ; No, so load the escape code back into the accumulator. cmp #$42 ; Did the user press the down arrow key? - bne isdown_done - lda scr_row ; Start checking the y coordinate of the cursor. + bne isdown_done ; No, so we're done. + lda scr_row ; Yes, so start checking the y coordinate of the cursor. cmp #23 ; Is the cursor at the bottom of the screen? - beq isdown_scrl ; Yes, so return. + beq isdown_scrl ; Yes, so scroll down. lda c ; No, so load the escape code back into the accumulator. cmp #$42 ; Did the user press the down arrow key? beq down ; Yes, so move the cursor down. @@ -717,6 +785,8 @@ isdown_scrl: sta scr_row ; lda scr_tcol ; Load the cursor's column number. sta scr_col ; + lda #1 ; Tell the escape routine that we were successful. + sta d ; isdown_done: rtl ; End of isdown. @@ -735,8 +805,8 @@ isright_wrp: dec scr_row ; No, so move the cursor back up a row. jmp isright_dne ; We are done. isright_scr: -; lda scr_str ; Are we at the top of the screen buffer? -; beq isright_end ; Yes, so we're done. + lda scr_str ; Are we at the top of the screen buffer? + beq isright_end ; Yes, so we're done. lda #1 ; No, so scroll down. sta wrapped ; Set the wrapped flag. jsl scrl_down ; Scroll down. @@ -748,7 +818,7 @@ wrap_inc: cmp #23 ; Are we at the bottom of the screen? beq isright_nd2 ; No, so we're done. bcs isright_scr ; Yes, so check if we are scrolling down. - jmp isright_nd2 ; We are done. + jmp isright_nd2 ; No, so we're done. isright_end: dec scr_row ; Move back up a row. isright_nd2: @@ -759,29 +829,29 @@ isright_dne: rtl ; End of isright. isleft: - lda c - cmp #$43 - beq isleft_done - lda scr_col ; Is the cursor at the far left of the screen? + lda c ; Get the saved character. + cmp #$43 ; Did the user press right? + beq isleft_done ; Yes, so we're done + lda scr_col ; No, but is the cursor at the far left of the screen? beq isleft_wrp ; Yes, so start checking if this is a wrapped line. lda c ; No, so load the escape code back into the accumulator. cmp #$44 ; Did the user press the left arrow key? beq left ; Yes, so move the cursor left. - jmp isleft_done ; We are done. + jmp isleft_done ; No, so we're done. isleft_wrp: jsl getbit ; Is the current line, a wrapped line? bcs wrap_dec ; Yes, so wrap back up a line. - jmp isleft_done ; No, so return. + jmp isleft_done ; No, so we're done. wrap_dec: lda scr_row ; Is the cursor at the top of the screen? - beq wrap_dec1 ; Yes, so don't move up a row. - lda #1 ; No, so move up a row. - sta wrapped ; Set the wrapped flag. - dec scr_row ; Move the cursor up by one row. + beq wrap_dec1 ; Yes, so don't move up a line. + lda #1 ; No, so set the wrapped flag. + sta wrapped ; + dec scr_row ; Move the cursor up one line. wrap_dec1: lda #79 ; Move the Cursor to the far right of the screen. sta scr_col ; - lda #1 ; Tell the escape routine to stop after this. + lda #1 ; Tell the escape routine that we were successful. sta d ; lda scr_row ; Are we at the top of the screen? beq isleft_scrl ; Yes, so check if we need to scroll. @@ -801,81 +871,81 @@ isleft_done: rtl ; End of isleft. up: - dec scr_row - jsl update_pos - lda #1 - sta d - jmp isup_done + dec scr_row ; Move the cursor up a line. + jsl update_pos ; Update it's position. + lda #1 ; Tell the escape routine that we succeded. + sta d ; + jmp isup_done ; We are done. down: - inc scr_row - jsl update_pos - lda #1 - sta d - jmp isdown_done + inc scr_row ; Move the cursor down a line. + jsl update_pos ; Update it's position. + lda #1 ; Tell the escape routine that we succeded. + sta d ; + jmp isdown_done ; We are done. right: - inc scr_col - jsl update_pos - jmp isright_dne + inc scr_col ; Move the cursor right by one character. + jsl update_pos ; Update it's position. + jmp isright_dne ; We are done. left: - dec scr_col - jsl update_pos - lda #1 - sta d - jmp isleft_done + dec scr_col ; Move the cursor left a character. + jsl update_pos ; Update it's position. + lda #1 ; Tell the escape routine that we succeded. + sta d ; + jmp isleft_done ; We are done isshftup: lda c ; Load the escape code back into the accumulator. cmp #$41 ; Did the user press the up arrow key? - bne isshftup_done - lda #1 - sta d - lda scr_str - beq isshftup_done - jmp shftup -isshftup_done: - rtl + bne shftup_done ; + lda #1 ; + sta d ; + lda scr_str ; + beq shftup_done ; + jmp shftup ; +shftup_done: + rtl ; isshftdown: lda c ; Load the escape code back into the accumulator. cmp #$42 ; Did the user press the down arrow key? - bne isshftdown_done - lda #1 - sta d - lda scr_end - cmp #71 - bcs isshftdown_done - jmp shftdown -isshftdown_done: - rtl + bne shftdn_done ; + lda #1 ; + sta d ; + lda scr_end ; + cmp #71 ; + bcs shftdn_done ; + jmp shftdown ; +shftdn_done: + rtl ; shftup: - jsl scrl_up - lda #1 - sta d - jmp isshftup_done + jsl scrl_up ; + lda #1 ; + sta d ; + jmp shftup_done ; shftdown: - jsl scrl_down - lda #1 - sta d - jmp isshftdown_done + jsl scrl_down ; + lda #1 ; + sta d ; + jmp shftdn_done ; update_pos: - ldb #1 - stb f - clc - lda scr_row - adc scr_str - tay - clc - lsl #6 - tab - tya - lsl #4 - aab - clc - adc scr_col - tay + ldb #1 ; Set the F pseudo register to one, to fix some bugs. + stb f ; + clc ; Clear the carry flag. + lda scr_row ; Add the cursor's line number, + adc scr_str ; with the starting line number to get the absolute line number. + tay ; Place it in the Y regster for now. + clc ; Clear the carry flag. + lsl #6 ; Multiply the absolute line number by 64. + tab ; Use it as a second operand. + tya ; Place the absolute line number back into the Accumulator + lsl #4 ; Multiply the absolute line number by 16. + aab ; Add both the Accumulator, and the B register together, to multiply the line number by 80. + clc ; Clear the carry flag. + adc scr_col ; Add the cursor's column number to get the screen index. + tay ; Place the index into the Y register. lda #$1B ; Print an escape character sta $C001 ; to the screen. lda #$5B ; Print '[' @@ -911,190 +981,180 @@ getcol: rtl ; End of getrow. scrl_down: - inc scr_str - inc scr_end + inc scr_str ; Increment the starting line of the screen. + inc scr_end ; Increment the ending line of the screen. lda #$1B ; Print an escape character sta $C001 ; to the screen. lda #$5B ; Print '[' sta $C001 ; to the screen, and start the escape sequence. lda #$54 ; Print 'T' sta $C001 ; to the screen, and end the escape sequence. - lda wrapped - beq scrldn_save + lda scr_row ; Get the cursor's line number. + pha #1 ; Save it in the stack. + lda wrapped ; Was the wrapped flag set? + beq scrldn_save ; Yes, so save the cursor position. scrldn1: - jsl rdrw_row - lda wrapped - beq scrldn_load - jmp scrldn_end + jsl rdrw_row ; Redraw this row. + lda wrapped ; Was the wrapped flag set? + beq scrldn_load ; Yes, so load the previous cursor position back. + jmp scrldn_end ; No, so we're done. scrldn_save: - lda scr_row - pha #1 - lda scr_col - pha #1 - jmp scrldn1 + lda scr_col ; Get the cursor's column number. + pha #1 ; Save it in the stack. + jmp scrldn1 ; Start redrawing the current row. scrldn_load: - pla #1 - sta scr_col - pla #1 - sta scr_row - jsl update_pos + pla #1 ; Get the cursor's previous column number back. + sta scr_col ; scrldn_end: - lda #0 - sta wrapped + pla #1 ; Get the cursor's previous line number back. + sta scr_row ; + jsl update_pos ; Update the cursor's position. + lda #0 ; Clear the wrapped flag. + sta wrapped ; scrldn_done: - rtl + rtl ; End of scrl_down. scrl_up: - dec scr_str - dec scr_end + dec scr_str ; + dec scr_end ; lda #$1B ; Print an escape character sta $C001 ; to the screen. lda #$5B ; Print '[' sta $C001 ; to the screen, and start the escape sequence. lda #$53 ; Print 'S' sta $C001 ; to the screen, and end the escape sequence. - lda scr_row - pha #1 - lda scr_col - pha #1 - lda #0 - sta scr_row - jsl rdrw_row - pla #1 - sta scr_col - pla #1 - sta scr_row - jsl update_pos + lda scr_row ; + pha #1 ; + lda scr_col ; + pha #1 ; + lda #0 ; + sta scr_row ; + jsl rdrw_row ; + pla #1 ; + sta scr_col ; + pla #1 ; + sta scr_row ; + jsl update_pos ; scrlup_done: - rtl + rtl ; rdrw_row: - lda #0 - sta scr_col - jsl update_pos + lda #0 ; + sta scr_col ; + jsl update_pos ; rdrow_st: - lda (ptr5), y - beq rdrow_inc - sta $C001 + lda (ptr5), y ; + beq rdrow_inc ; + sta $C001 ; rdrow_inc: - inc scr_col - lda (ptr5), y - beq rdrow_skip + inc scr_col ; + lda (ptr5), y ; + beq rdrow_skip ; rdrow_inc1: - iny + iny ; rdrow_inc2: - lda scr_col - cmp #80 - bcs rdrow_end - jmp rdrow_st + lda scr_col ; + cmp #80 ; + bcs rdrow_end ; + jmp rdrow_st ; rdrow_skip: - lda #$20 + lda #$20 ; sta $C001 ; to the screen. - jmp rdrow_inc1 + jmp rdrow_inc1 ; rdrow_end: - lda #0 - sta scr_col - jsl update_pos + lda #0 ; + sta scr_col ; + jsl update_pos ; rdrow_done: - rtl - -;rdrw_scr: -; lda scr_row -; sta e -; lda #0 -; sta scr_row -; lda scr_col -; sta f -; jsl update_pos -;rdscr_st: -; jsl rdrw_row -; lda scr_row -; cmp #23 -; beq rdscr_inc -; bcs rdscr_done -;rdscr_inc: -; inc scr_row -; jmp rdscr_st -;rdscr_done: -; lda e -; sta scr_row -; lda f -; sta scr_col -; jsl update_pos -; lda #0 -; sta e -; sta f -; rtl + rtl ; result: - lda.w #string2 - ldx.w zero - jsl print_str + lda.w #string2 ; + ldx.w zero ; + jsl print_str ; rset_x: lda #0 ; Reset a. tax ; Reset x. jmp print_buf ; Print the input buffer. dabbed: - ldb #0 - lda.w #tok - sta.q ptr2 - tba + ldb #0 ; + lda.w #tok ; + sta.q ptr2 ; + tba ; dab_st: - phy #2 - txy + phy #2 ; + txy ; lda (ptr6), y ; Get a character from the input buffer. beq dab_pend ; Are we done with printing the buffer? - cmp (ptr2), y - beq chk_str - jmp dab_pend + cmp (ptr2), y ; + beq chk_str ; + jmp dab_pend ; chk_str: - ply #2 - inx - cpx #3 - bne dab_st - ldx #0 + ply #2 ; + inx ; + cpx #3 ; + bne dab_st ; + ldx #0 ; pnt_msg: - lda.w #msg - ldx #0 - stx.q ptr - jsl print_str - jmp dab_peqnd + lda.w #msg ; + ldx #0 ; + stx.q ptr ; + jsl print_str ; + jmp dab_peqnd ; dab_pend: - ply #2 - lda #1 - jmp dab_end + ply #2 ; + lda #1 ; + jmp dab_end ; dab_peqnd: - lda #0 - jmp dab_end + lda #0 ; + jmp dab_end ; dab_end: - rtl + rtl ; print_buf: - lda.w #cmd_buf - jsl print_str - lda.w zero + lda.w #cmd_buf ; + jsl print_str ; + lda.w zero ; cmd_clr: - lda #10 - jsl print_char - jmp start + lda #10 ; + jsl print_char ; + jmp start ; + +rdrw_ln: + lda scr_row ; + pha #1 ; + inc end ; + lda f ; + sta scr_row ; + lda scr_col ; + pha #1 ; + jsl update_pos ; +rdrwln_lp: + lda scr_row ; + cmp e ; + beq rdrwln_lp1 ; + bcs rdrwln_done ; +rdrwln_lp1: + jsl rdrw_row ; +rdrwln_inc: + inc scr_row ; + jmp rdrwln_lp ; +rdrwln_done: + pla #1 ; + sta scr_col ; + pla #1 ; + sta scr_row ; + jsl update_pos ; + lda #0 ; + sta e ; + sta f ; + dec end ; + rtl ; .org $FFC0 .qword reset r -;.org $8000 -;v -;.org $8100 -;v -;.org $8200 -;v -;.org $8300 -;v -;.org $8400 -;v -;.org $8500 -;v -;q done diff --git a/sux.c b/sux.c index 9afff16..164ca4a 100644 --- a/sux.c +++ b/sux.c @@ -4,8 +4,8 @@ #include #include #define bench 0 -#define debug 0 -#define IO 1 +#define debug 1 +#define IO 0 #define keypoll 0 #if bench #include @@ -21,15 +21,8 @@ #define STEP_ADDR 0xC010 #define CURSES_BACKSPACE 0x7F -#define setflag(flag, bit) (flag) ? (cpu->ps |= (bit << (thread << 3))) : (cpu->ps &= ~(bit << (thread << 3))) -#define clearflags(thread) {\ - cpu->c[thread] = 0;\ - cpu->z[thread] = 0;\ - cpu->i[thread] = 0;\ - cpu->s[thread] = 0;\ - cpu->v[thread] = 0;\ - cpu->n[thread] = 0;\ -} +#define setflag(flag, bit) ((flag)) ? (cpu->ps |= (bit << (thread << 3))) : (cpu->ps &= ~(bit << (thread << 3))) +#define getflag(bit) (cpu->ps & (bit << (thread << 3))) uint64_t clk[THREADS]; /* Per Thread Clock cycles. */ uint64_t tclk; /* Total Clock cycles. */ @@ -91,6 +84,8 @@ void *run(void *args) { gettimeofday(&str[thread], 0); #endif #if debug && !bench + uint8_t scr_row = 0xFF, scr_col = 0xFF; + uint8_t updt = 0; #if keypoll pthread_mutex_lock(&mutex); #endif @@ -111,8 +106,7 @@ void *run(void *args) { } addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->ps >> 8*thread; cpu->sp[thread]--; - cpu->i[thread] = 1; - setflag(cpu->i[thread], I); + setflag(1, I); cpu->pc[thread] = (uint64_t)addr[0xFFA0] | (uint64_t)addr[0xFFA1] << 8 | (uint64_t)addr[0xFFA2] << 16 @@ -139,14 +133,29 @@ void *run(void *args) { #if keypoll pthread_mutex_lock(&mutex); #endif - /*mvwprintw(scr, lines, 0, "pc: $%08llx, a: $%016llx, b: $%016llx, x: $%016llx, y: $%016llx" - ", sp: $%04lx, ps: $%016llx, prefix: $%02x, opcode: $%02x, thread: %u, inst: " - , cpu->pc[thread], cpu->a[thread], cpu->b[thread], cpu->x[thread], cpu->y[thread] - , cpu->sp[thread], cpu->ps, prefix, opcode, thread);*/ - mvwprintw(scr, lines, 0, "pc: $%08llx, a: $%016llx, b: $%016llx, x: $%016llx, y: $%016llx" - ", sp: $%04lx, ps: $%016llx, prefix: $%02x, opcode: $%02x, inst: " - , cpu->pc[thread], cpu->a[thread], cpu->b[thread], cpu->x[thread], cpu->y[thread] - , cpu->sp[thread], cpu->ps, prefix, opcode); + wmove(scr, lines, 0); + wclrtoeol(scr); + wprintw(scr, + "pc: $%08llX" + ", a: $%016llX" + ", b: $%016llX" + ", x: $%016llX" + ", y: $%016llX" + , cpu->pc[thread] + , cpu->a[thread] + , cpu->b[thread] + , cpu->x[thread] + , cpu->y[thread]); + wprintw(scr, + ", sp: $%04X" + ", ps: $%04X" + ", prefix: $%02x" + ", opcode: $%02x" + ", inst: " + , cpu->sp[thread] + , cpu->ps + , prefix + , opcode); #if keypoll pthread_mutex_unlock(&mutex); #endif @@ -200,28 +209,19 @@ void *run(void *args) { case ZMY: address = addr[cpu->pc[thread]]; switch (addrsize) { - case 3: - address |= addr[cpu->pc[thread]+1] << 8; - address |= addr[cpu->pc[thread]+2] << 16; - address |= addr[cpu->pc[thread]+3] << 24; - cpu->pc[thread]+=4; - break; case 2: - address |= addr[cpu->pc[thread]+1] << 8; - address |= addr[cpu->pc[thread]+2] << 16; - address |= addr[cpu->pc[thread]+3] << 24; - address |= (uint64_t)addr[cpu->pc[thread]+4] << 32; address |= (uint64_t)addr[cpu->pc[thread]+5] << 40; - cpu->pc[thread]+=6; - break; + address |= (uint64_t)addr[cpu->pc[thread]+4] << 32; + cpu->pc[thread]+=2; + case 3: + address |= addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=1; case 1: - address |= addr[cpu->pc[thread]+1] << 8; address |= addr[cpu->pc[thread]+2] << 16; - cpu->pc[thread]+=3; - break; + address |= addr[cpu->pc[thread]+1] << 8; + cpu->pc[thread]+=2; case 0: cpu->pc[thread]+=1; - break; } tmpaddr = address; switch (optype[opcode]) { @@ -241,28 +241,19 @@ void *run(void *args) { case INDY: address = addr[cpu->pc[thread]]; switch (addrsize) { - case 3: - address |= addr[cpu->pc[thread]+1] << 8; - address |= addr[cpu->pc[thread]+2] << 16; - address |= addr[cpu->pc[thread]+3] << 24; - cpu->pc[thread]+=4; - break; case 2: - address |= addr[cpu->pc[thread]+1] << 8; - address |= addr[cpu->pc[thread]+2] << 16; - address |= addr[cpu->pc[thread]+3] << 24; - address |= (uint64_t)addr[cpu->pc[thread]+4] << 32; address |= (uint64_t)addr[cpu->pc[thread]+5] << 40; - cpu->pc[thread]+=6; - break; + address |= (uint64_t)addr[cpu->pc[thread]+4] << 32; + cpu->pc[thread]+=2; + case 3: + address |= addr[cpu->pc[thread]+3] << 24; + cpu->pc[thread]+=1; case 1: - address |= addr[cpu->pc[thread]+1] << 8; address |= addr[cpu->pc[thread]+2] << 16; - cpu->pc[thread]+=3; - break; + address |= addr[cpu->pc[thread]+1] << 8; + cpu->pc[thread]+=2; case 0: cpu->pc[thread]+=1; - break; } iclk++; tmpaddr = address; @@ -289,36 +280,23 @@ void *run(void *args) { break; case ABS: address = addr[cpu->pc[thread]]; - address |= addr[cpu->pc[thread]+1] << 8; switch (addrsize) { case 3: - address |= addr[cpu->pc[thread]+2] << 16; - address |= addr[cpu->pc[thread]+3] << 24; - address |= (uint64_t)addr[cpu->pc[thread]+4] << 32; - address |= (uint64_t)addr[cpu->pc[thread]+5] << 40; - address |= (uint64_t)addr[cpu->pc[thread]+6] << 48; address |= (uint64_t)addr[cpu->pc[thread]+7] << 56; - cpu->pc[thread]+=8; - iclk++; - break; + cpu->pc[thread]+=1; case 2: - address |= addr[cpu->pc[thread]+2] << 16; - address |= addr[cpu->pc[thread]+3] << 24; - address |= (uint64_t)addr[cpu->pc[thread]+4] << 32; - address |= (uint64_t)addr[cpu->pc[thread]+5] << 40; address |= (uint64_t)addr[cpu->pc[thread]+6] << 48; - cpu->pc[thread]+=7; + address |= (uint64_t)addr[cpu->pc[thread]+5] << 40; + cpu->pc[thread]+=2; iclk++; - break; case 1: - address |= addr[cpu->pc[thread]+2] << 16; - address |= addr[cpu->pc[thread]+3] << 24; address |= (uint64_t)addr[cpu->pc[thread]+4] << 32; - cpu->pc[thread]+=5; - break; + address |= addr[cpu->pc[thread]+3] << 24; + address |= addr[cpu->pc[thread]+2] << 16; + cpu->pc[thread]+=3; case 0: + address |= addr[cpu->pc[thread]+1] << 8; cpu->pc[thread]+=2; - break; } break; @@ -337,11 +315,9 @@ void *run(void *args) { value |= addr[address+1] << 8; } #if debug && !bench - int row, col; #if keypoll pthread_mutex_lock(&mutex); #endif - getyx(scr,row, col); char postfix[3]; char op[4]; op[0] = opname[opcode][0]; @@ -363,18 +339,13 @@ void *run(void *args) { postfix[2] = '\0'; } switch (optype[opcode]) { - case IMPL: - mvwprintw(scr, lines, col, "%s \r" , opname[opcode]); - break; + case IMPL: wprintw(scr, "%s\r" , opname[opcode]); break; case IMM: - if (regsize == 1) { - mvwprintw(scr, lines, col, "%s #$%02x \r" , op, value); - } else if (regsize == 2) { - mvwprintw(scr, lines, col, "%s%s #$%04x \r" , op, postfix, value); - } else if (regsize == 4) { - mvwprintw(scr, lines, col, "%s%s #$%08x \r" , op, postfix, value); - } else if (regsize == 8) { - mvwprintw(scr, lines, col, "%s%s #$%016llx\r" , op, postfix, value); + switch(regsize) { + case 1: wprintw(scr, "%s #$%02X\r" , op, value); break; + case 2: wprintw(scr, "%s%s #$%04X\r" , op, postfix, value); break; + case 4: wprintw(scr, "%s%s #$%08X\r" , op, postfix, value); break; + case 8: wprintw(scr, "%s%s #$%016llX\r" , op, postfix, value); break; } break; case ZM: @@ -385,114 +356,85 @@ void *run(void *args) { else if (optype[opcode] == ZMY) tmpaddr = address - cpu->y[thread]; switch (addrsize) { - case 3: - mvwprintw(scr, lines, col, "%s%s $%08x%s \r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); - break; - case 2: - mvwprintw(scr, lines, col, "%s%s $%014llx%s \r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); - break; - case 1: - mvwprintw(scr, lines, col, "%s%s $%06x%s \r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); - break; - case 0: - mvwprintw(scr, lines, col, "%s%s $%02x%s \r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); - break; + case 3: wprintw(scr, "%s%s $%08X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break; + case 2: wprintw(scr, "%s%s $%014llX%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break; + case 1: wprintw(scr, "%s%s $%06X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break; + case 0: wprintw(scr, "%s%s $%02X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break; } break; case IND: case INDX: case INDY: switch (addrsize) { - case 3: - mvwprintw(scr, lines, col, "%s%s ($%08x%s \r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? "" : ((optype[opcode] == INDX) ? ", x" : ", y")); - break; - case 2: - mvwprintw(scr, lines, col, "%s%s ($%012llx%s \r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? "" : ((optype[opcode] == INDX) ? ", x" : ", y")); - break; - case 1: - mvwprintw(scr, lines, col, "%s%s ($%06x%s \r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? "" : ((optype[opcode] == INDX) ? ", x" : ", y")); - break; - case 0: - mvwprintw(scr, lines, col, "%s%s ($%02x%s \r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? "" : ((optype[opcode] == INDX) ? ", x" : ", y")); - break; + case 3: wprintw(scr, "%s%s ($%08X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break; + case 2: wprintw(scr, "%s%s ($%012llX%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break; + case 1: wprintw(scr, "%s%s ($%06X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break; + case 0: wprintw(scr, "%s%s ($%02X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break; } break; case ABS: tmpaddr = address; switch (addrsize) { - case 3: - mvwprintw(scr, lines, col, "%s%s $%016x\r" , op, postfix, tmpaddr); - break; - case 2: - mvwprintw(scr, lines, col, "%s%s $%014llx \r" , op, postfix, tmpaddr); - break; - case 1: - mvwprintw(scr, lines, col, "%s%s $%010llx \r" , op, postfix, tmpaddr); - break; - case 0: - mvwprintw(scr, lines, col, "%s%s $%04x \r" , op, postfix, tmpaddr); - break; + case 3: wprintw(scr, "%s%s $%016llX\r" , op, postfix, tmpaddr); break; + case 2: wprintw(scr, "%s%s $%014llX\r" , op, postfix, tmpaddr); break; + case 1: wprintw(scr, "%s%s $%010llX\r" , op, postfix, tmpaddr); break; + case 0: wprintw(scr, "%s%s $%04X\r" , op, postfix, tmpaddr ); break; } break; - if (addrsize) - mvwprintw(scr, lines, col, "%s%s $%016llx\r" , op, postfix, value); - else - mvwprintw(scr, lines, col, "%s%s $%04x \r" , op, postfix, tmpaddr); - break; - } - mvwprintw(scr, 28, 0, "TX_ADDR: $%02X, RX_ADDR: $%02X\r", addr[TX_ADDR], addr[RX_ADDR]); - mvwprintw(scr, 29, 0, "address: $%016llx, scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u\r", address, addr[0], addr[1], addr[0x26], addr[0x27]); + mvwprintw(scr, 27, 0, "TX_ADDR: $%02X, RX_ADDR: $%02X\r", addr[TX_ADDR], addr[RX_ADDR]); + mvwprintw(scr, 28, 0, "scr_ptr3: %04X\r", (addr[0x5C] << 8) | addr[0x5B]); + mvwprintw(scr, 29, 0, "address: $%016llx, scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u\r", address, addr[0], addr[1], addr[0x28], addr[0x29]); mvwprintw(scr, 32, 0, "bitabl: %02x %02x %02x %02x %02x %02x %02x %02x " "%02x %02x %02x %02x %02x %02x %02x %02x\r" - , addr[0x16], addr[0x17], addr[0x18], addr[0x19], addr[0x1A], addr[0x1B], addr[0x1C], addr[0x1D] - , addr[0x1E], addr[0x1F], addr[0x20], addr[0x21], addr[0x22], addr[0x23], addr[0x24], addr[0x25]); - mvwprintw(scr, 33, 0, "buffer:\r"); - uint8_t ln = 34; + , addr[0x18], addr[0x19], addr[0x1A], addr[0x1B], addr[0x1C], addr[0x1D], addr[0x1E], addr[0x1F] + , addr[0x20], addr[0x21], addr[0x22], addr[0x23], addr[0x24], addr[0x25], addr[0x26], addr[0x27]); + uint8_t ln = 33; + uint16_t line_idx = 0; uint16_t tmpad = 0x2000; - for (uint16_t i = 0; i < 20; i+=2) { - mvwprintw(scr, ln++, 0, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x " - "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x, i: %02x\r" - , addr[tmpad+(0x00)+(i*0x10)], addr[tmpad+(0x01)+(i*0x10)], addr[tmpad+(0x02)+(i*0x10)], addr[tmpad+(0x03)+(i*0x10)] - , addr[tmpad+(0x04)+(i*0x10)], addr[tmpad+(0x05)+(i*0x10)], addr[tmpad+(0x06)+(i*0x10)], addr[tmpad+(0x07)+(i*0x10)] - , addr[tmpad+(0x08)+(i*0x10)], addr[tmpad+(0x09)+(i*0x10)], addr[tmpad+(0x0A)+(i*0x10)], addr[tmpad+(0x0B)+(i*0x10)] - , addr[tmpad+(0x0C)+(i*0x10)], addr[tmpad+(0x0D)+(i*0x10)], addr[tmpad+(0x0E)+(i*0x10)], addr[tmpad+(0x0F)+(i*0x10)] - , addr[tmpad+(0x10)+(i*0x10)], addr[tmpad+(0x11)+(i*0x10)], addr[tmpad+(0x12)+(i*0x10)], addr[tmpad+(0x13)+(i*0x10)] - , addr[tmpad+(0x14)+(i*0x10)], addr[tmpad+(0x15)+(i*0x10)], addr[tmpad+(0x16)+(i*0x10)], addr[tmpad+(0x17)+(i*0x10)] - , addr[tmpad+(0x18)+(i*0x10)], addr[tmpad+(0x19)+(i*0x10)], addr[tmpad+(0x1A)+(i*0x10)], addr[tmpad+(0x1B)+(i*0x10)] - , addr[tmpad+(0x1C)+(i*0x10)], addr[tmpad+(0x1D)+(i*0x10)], addr[tmpad+(0x1E)+(i*0x10)], addr[tmpad+(0x1F)+(i*0x10)] - , i); - + int row, col; + uint8_t iscursor = 0; + mvwprintw(scr, ln++, 0, "buffer:\r"); + if (updt) { + scr_row = addr[0]; + scr_col = addr[1]; + wmove(scr, ln++, 0); + for (uint8_t i = 0; i < 10; i++) { + line_idx = (i << 6) + (i << 4); + for (uint8_t j = 0; j < 0x50; j++) { + wprintw(scr, "%02X", addr[tmpad+j+line_idx]); + if ((addr[0]+addr[0x28]) == i && addr[1] == j) { + iscursor=1; + getyx(scr,row, col); + wmove(scr, ln++, 0); + wclrtoeol(scr); + wmove(scr, row+1, col-2); + wprintw(scr, "/\\\r"); + wmove(scr, row, col); + } + } + wprintw(scr, ", i: %02X\r", i); + if (!iscursor) { + wmove(scr, ln, 0); + wclrtoeol(scr); + } + iscursor = 0; + wmove(scr, ln++, 0); + } + updt = 0; } - tmpad = 0x4000; + /*tmpad = 0x4000; + line_idx = 0; mvwprintw(scr, ln++, 0, "cmd_buf:\r"); - for (uint16_t i = 0; i < 20; i+=2) { - mvwprintw(scr, ln++, 0, "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x " - "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x, i: %02x\r" - , addr[0x4000+(0x00)+(i*0x10)], addr[0x4000+(0x01)+(i*0x10)], addr[0x4000+(0x02)+(i*0x10)], addr[0x4000+(0x03)+(i*0x10)] - , addr[0x4000+(0x04)+(i*0x10)], addr[0x4000+(0x05)+(i*0x10)], addr[0x4000+(0x06)+(i*0x10)], addr[0x4000+(0x07)+(i*0x10)] - , addr[0x4000+(0x08)+(i*0x10)], addr[0x4000+(0x09)+(i*0x10)], addr[0x4000+(0x0A)+(i*0x10)], addr[0x4000+(0x0B)+(i*0x10)] - , addr[0x4000+(0x0C)+(i*0x10)], addr[0x4000+(0x0D)+(i*0x10)], addr[0x4000+(0x0E)+(i*0x10)], addr[0x4000+(0x0F)+(i*0x10)] - , addr[0x4000+(0x10)+(i*0x10)], addr[0x4000+(0x11)+(i*0x10)], addr[0x4000+(0x12)+(i*0x10)], addr[0x4000+(0x13)+(i*0x10)] - , addr[0x4000+(0x14)+(i*0x10)], addr[0x4000+(0x15)+(i*0x10)], addr[0x4000+(0x16)+(i*0x10)], addr[0x4000+(0x17)+(i*0x10)] - , addr[0x4000+(0x18)+(i*0x10)], addr[0x4000+(0x19)+(i*0x10)], addr[0x4000+(0x1A)+(i*0x10)], addr[0x4000+(0x1B)+(i*0x10)] - , addr[0x4000+(0x1C)+(i*0x10)], addr[0x4000+(0x1D)+(i*0x10)], addr[0x4000+(0x1E)+(i*0x10)], addr[0x4000+(0x1F)+(i*0x10)] - , i); - - } - mvwprintw(scr, ln++, 0, "ptr: $%02x%02x%02x%02x%02x%02x%02x%02x\r" - , addr[0x30], addr[0x2F], addr[0x2E], addr[0x2D], addr[0x2C], addr[0x2B], addr[0x2A], addr[0x29]); - mvwprintw(scr, ln++, 0, "ptr2: $%02x%02x%02x%02x%02x%02x%02x%02x\r" - , addr[0x38], addr[0x37], addr[0x36], addr[0x35], addr[0x34], addr[0x33], addr[0x32], addr[0x31]); - mvwprintw(scr, ln++, 0, "ptr3: $%02x%02x%02x%02x%02x%02x%02x%02x\r" - , addr[0x40], addr[0x3F], addr[0x3E], addr[0x3D], addr[0x3C], addr[0x3B], addr[0x3A], addr[0x39]); - mvwprintw(scr, ln++, 0, "ptr4: $%02x%02x%02x%02x%02x%02x%02x%02x\r" - , addr[0x48], addr[0x47], addr[0x46], addr[0x45], addr[0x44], addr[0x43], addr[0x42], addr[0x41]); - mvwprintw(scr, ln++, 0, "ptr5: $%02x%02x%02x%02x%02x%02x%02x%02x\r" - , addr[0x50], addr[0x4F], addr[0x4E], addr[0x4D], addr[0x4C], addr[0x4B], addr[0x4A], addr[0x49]); - mvwprintw(scr, ln++, 0, "ptr6: $%02x%02x%02x%02x%02x%02x%02x%02x\r" - , addr[0x58], addr[0x57], addr[0x56], addr[0x55], addr[0x54], addr[0x53], addr[0x52], addr[0x51]); - wrefresh(scr); + for (uint8_t i = 0; i < 20; i++) { + wmove(scr, ln); + line_idx = (i << 4)+(i << 6); + for (uint8_t j = 0; j < 0x10; j++) { + wprintw(scr, "%02X ", addr[tmpad+j+line_idx]); + } + wprintw(scr, ", i: %02X\r", i); + ln++; + }*/ #if keypoll pthread_mutex_unlock(&mutex); #endif @@ -500,14 +442,6 @@ void *run(void *args) { #endif switch(opcode) { case CPS: /* Clear Processor Status. */ - clearflags(0); - clearflags(1); - clearflags(2); - clearflags(3); - clearflags(4); - clearflags(5); - clearflags(6); - clearflags(7); cpu->ps &= 0; break; case ADC: /* ADC Immediate. */ @@ -516,17 +450,12 @@ void *run(void *args) { case ADC_Z: /* ADC Zero Matrix. */ if (opcode == AAB) value = cpu->b[thread]; - sum = cpu->a[thread]+value+cpu->c[thread]; + sum = cpu->a[thread]+value+getflag(C); cpu->a[thread] = sum; - cpu->z[thread] = (sum == 0); - cpu->n[thread] = (sum >> 63); - cpu->v[thread] = !((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000); - cpu->c[thread] = (sum < value); - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); - setflag(cpu->v[thread], V); - setflag(cpu->c[thread], C); - setflag(cpu->i[thread], I); + setflag(sum == 0, Z); + setflag((sum >> 63), N); + setflag(((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000), V); + setflag((sum < value), C); break; case PHB: /* PusH B register to stack. */ case PHP: /* PusH Processor status to stack. */ @@ -534,28 +463,23 @@ void *run(void *args) { case PHY: /* PusH Y register to stack. */ case PHX: /* PusH X register to stack. */ tmp = value; - if (opcode == PHB) { - reg = cpu->b[thread]; - } else if (opcode == PHP) { - reg = cpu->ps; - } else if (opcode == PHA) { - reg = cpu->a[thread]; - } else if (opcode == PHY) { - reg = cpu->y[thread]; - } else if (opcode == PHX) { - reg = cpu->x[thread]; + switch (opcode) { + case PHA: reg = cpu->a[thread]; break; + case PHB: reg = cpu->b[thread]; break; + case PHX: reg = cpu->x[thread]; break; + case PHY: reg = cpu->y[thread]; break; + case PHP: reg = cpu->ps; break; } - if (tmp > 7) tmp = 7; switch (tmp) { - case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (tmp--<<3); - case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (tmp--<<3); - case 5: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (tmp--<<3); - case 4: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (tmp--<<3); - case 3: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (tmp--<<3); - case 2: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (tmp--<<3); - case 1: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (tmp--<<3); + case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (7<<3); + case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (6<<3); + case 5: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (5<<3); + case 4: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (4<<3); + case 3: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (3<<3); + case 2: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (2<<3); + case 1: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (1<<3); case 0: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg & 0xFF; } break; @@ -570,38 +494,21 @@ void *run(void *args) { case TBA: /* Transfer B to Accumulator. */ case TXS: /* Transfer X to Stack pointer. */ switch (opcode) { - case TAY: - cpu->y[thread] = cpu->a[thread]; - break; - case TAX: - cpu->x[thread] = cpu->a[thread]; - break; - case TYX: - cpu->x[thread] = cpu->y[thread]; - break; - case TYA: - cpu->a[thread] = cpu->y[thread]; + case TAY: cpu->y[thread] = cpu->a[thread]; break; + case TAX: cpu->x[thread] = cpu->a[thread]; break; + case TYX: cpu->x[thread] = cpu->y[thread]; break; + case TYA: cpu->a[thread] = cpu->y[thread]; break; + case TXA: cpu->a[thread] = cpu->x[thread]; break; + case TXY: cpu->y[thread] = cpu->x[thread]; break; + case TAB: cpu->b[thread] = cpu->a[thread]; + setflag(cpu->b[thread] == 0, Z); + setflag(cpu->b[thread] >> 63, N); break; - case TXA: - cpu->a[thread] = cpu->x[thread]; - break; - case TXY: - cpu->y[thread] = cpu->x[thread]; - break; - case TAB: - cpu->b[thread] = cpu->a[thread]; - cpu->z[thread] = (cpu->b[thread] == 0); - cpu->n[thread] = (cpu->b[thread] >> 63); - break; - case TSX: - cpu->x[thread] = cpu->sp[thread] & 0xFFFF; + case TSX: cpu->x[thread] = cpu->sp[thread] & 0xFFFF; cpu->x[thread] = cpu->stk_st[thread] << 16; break; - case TBA: - cpu->a[thread] = cpu->b[thread]; - break; - case TXS: - cpu->sp[thread] = cpu->x[thread]; + case TBA: cpu->a[thread] = cpu->b[thread]; break; + case TXS: cpu->sp[thread] = cpu->x[thread]; if (prefix == 0x13 && (value == thread+1 || value > 8)) { cpu->stk_st[thread] = value & 0xFF; cpu->stk_st[thread] += value << 16; @@ -613,22 +520,20 @@ void *run(void *args) { case TYA: case TXA: case TBA: - cpu->z[thread] = (cpu->a[thread] == 0); - cpu->n[thread] = (cpu->a[thread] >> 63); + setflag(cpu->a[thread] == 0, Z); + setflag(cpu->a[thread] >> 63, N); break; case TAY: case TXY: - cpu->z[thread] = (cpu->y[thread] == 0); - cpu->n[thread] = (cpu->y[thread] >> 63); + setflag(cpu->y[thread] == 0, Z); + setflag(cpu->y[thread] >> 63, N); break; case TAX: case TYX: - cpu->z[thread] = (cpu->x[thread] == 0); - cpu->n[thread] = (cpu->x[thread] >> 63); + setflag(cpu->x[thread] == 0, Z); + setflag(cpu->x[thread] >> 63, N); break; } - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); break; case JMP: /* JMP Absolute. */ case JMP_Z: /* JMP Zero Matrix. */ @@ -642,15 +547,11 @@ void *run(void *args) { if (opcode == SAB) { value = cpu->b[thread]; } - sum = cpu->a[thread]-value-!cpu->c[thread]; - cpu->z[thread] = (sum == 0); - cpu->n[thread] = (sum >> 63); - cpu->v[thread] = ((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000); - cpu->c[thread] = (sum > value); - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); - setflag(cpu->v[thread], V); - setflag(cpu->c[thread], C); + sum = cpu->a[thread]-value-!getflag(C); + setflag(sum == 0, Z); + setflag(sum >> 63, N); + setflag(((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000), V); + setflag((sum > value), C); cpu->a[thread] = sum; break; case PLB: /* PuLl B register from stack. */ @@ -659,29 +560,25 @@ void *run(void *args) { case PLY: /* PuLl Y register from stack. */ case PLX: /* PuLl X register from stack. */ tmp = value; - if (opcode == PLB) - reg = cpu->b[thread]; - else if (opcode == PLP) - reg = cpu->ps; - else if (opcode == PLA) - reg = cpu->a[thread]; - else if (opcode == PLY) - reg = cpu->y[thread]; - else if (opcode == PLX) - reg = cpu->x[thread]; - + switch (opcode) { + case PLA: reg = cpu->a[thread]; break; + case PLB: reg = cpu->b[thread]; break; + case PLX: reg = cpu->x[thread]; break; + case PLY: reg = cpu->y[thread]; break; + case PLP: reg = cpu->ps; break; + } if (tmp > 7) tmp = 7; tmp2 = 0; - cpu->sp[thread]++;reg = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF;tmp2+=8;tmp--; + cpu->sp[thread]++;reg = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF;tmp--; switch (tmp) { - case 6: cpu->sp[thread]++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << tmp2;tmp2+=8; - case 5: cpu->sp[thread]++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << tmp2;tmp2+=8; - case 4: cpu->sp[thread]++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << tmp2;tmp2+=8; - case 3: cpu->sp[thread]++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << tmp2;tmp2+=8; - case 2: cpu->sp[thread]++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << tmp2;tmp2+=8; - case 1: cpu->sp[thread]++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << tmp2;tmp2+=8; - case 0: cpu->sp[thread]++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << tmp2;tmp2+=8; + case 6: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 5: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 4: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 3: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 2: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 1: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 0: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); } if (opcode == PLB) { cpu->b[thread] = reg; @@ -697,29 +594,22 @@ void *run(void *args) { break; case JSR_IN: /* JSR Indirect. */ case JSR: /* Jump to SubRoutine. */ - /*if (addrsize) - stksize = 24; - else - stksize = 0;*/ switch (addrsize) { - case 2: - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 40;cpu->sp[thread]--; - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 32;cpu->sp[thread]--; - case 3: - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 24;cpu->sp[thread]--; - case 1: - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 16;cpu->sp[thread]--; - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 8;cpu->sp[thread]--; - case 0: - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] & 0xFF;cpu->sp[thread]--; + case 3: stksize = 3; break; + case 2: stksize = 5; break; + case 1: stksize = 2; break; + case 0: stksize = 0; break; + } + switch (stksize) { + case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (7<<3); + case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (6<<3); + case 5: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (5<<3); + case 4: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (4<<3); + case 3: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (3<<3); + case 2: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (2<<3); + case 1: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (1<<3); + case 0: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] & 0xFF; } - /*for (int8_t i = stksize; i >= 0; i-=8) { - if (i) - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> i; - else - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] & 0xFF; - cpu->sp[thread]--; - }*/ cpu->pc[thread] = address; break; case AND: /* AND Immediate. */ @@ -730,10 +620,8 @@ void *run(void *args) { value = cpu->b[thread]; } cpu->a[thread] &= value; - cpu->z[thread] = (value == 0); - cpu->n[thread] = (value >> 63); - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); + setflag(value == 0, Z); + setflag(value >> 63, N); break; case STT: /* STart Thread. */ cpu->crt |= value; @@ -753,7 +641,7 @@ void *run(void *args) { break; case BPO: /* BPO Absolute. */ case BPO_Z: /* BPO Zero Matrix. */ - if (!cpu->n[thread]) + if (!getflag(N)) cpu->pc[thread] = address; break; case ORA: /* ORA Immediate. */ @@ -764,18 +652,15 @@ void *run(void *args) { value = cpu->b[thread]; } cpu->a[thread] |= value; - cpu->z[thread] = (value == 0); - cpu->n[thread] = (value >> 63); - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); + setflag(value == 0, Z); + setflag(value >> 63, N); break; case SEI: /* SEt Interrupt. */ - cpu->i[thread] = 1; - setflag(cpu->i[thread], I); + setflag(1, I); break; case BNG: /* BNG Absolute. */ case BNG_Z: /* BNG Zero Matrix. */ - if (cpu->n[thread]) + if (getflag(N)) cpu->pc[thread] = address; break; case XOR: /* XOR Immediate. */ @@ -786,18 +671,15 @@ void *run(void *args) { value = cpu->b[thread]; } cpu->a[thread] ^= value; - cpu->z[thread] = (value == 0); - cpu->n[thread] = (value >> 63); - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); + setflag(value == 0, Z); + setflag(value >> 63, N); break; case CLI: /* CLear Interrupt. */ - cpu->i[thread] = 0; - setflag(cpu->i[thread], I); + setflag(0, I); break; case BCS: /* BCS Absolute. */ case BCS_Z: /* BCS Zero Matrix. */ - if (cpu->c[thread]) + if (getflag(C)) cpu->pc[thread] = address; break; case LSL: /* LSL Immediate. */ @@ -808,17 +690,13 @@ void *run(void *args) { value = cpu->b[thread]; } sum = (value < 64) ? cpu->a[thread] << value : 0; - cpu->z[thread] = (sum == 0); - cpu->n[thread] = (sum >> 63); - cpu->c[thread] = cpu->a[thread] >> 64-value; + setflag(sum == 0, Z); + setflag(sum >> 63, N); + setflag(cpu->a[thread] >> 64-value, C); cpu->a[thread] = sum; - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); - setflag(cpu->c[thread], C); break; case SEC: /* SEt Carry flag.*/ - cpu->c[thread] = 1; - setflag(cpu->c[thread], C); + setflag(1, C); break; case STA: /* STA Absolute. */ case STY: /* STY Absolute. */ @@ -842,7 +720,6 @@ void *run(void *args) { case STB_IX: /* STB Indexed Indirect. */ case STA_IY: /* STA Indirect Indexed. */ case STB_IY: /* STB Indirect Indexed. */ - switch (opcode) { case STB: case STB_Z: @@ -877,9 +754,6 @@ void *run(void *args) { break; } addr[address] = value & 0xFF; - if (address == STEP_ADDR) { - step = addr[address]; - } #if IO if (address == TX_ADDR) { #if keypoll @@ -912,14 +786,16 @@ void *run(void *args) { esc = 0; break; case 'H': - if (!bcd[2] && !bcd[3]) + if (!bcd[2] && !bcd[3]) { y = 0; - else + } else { y = ((bcd[3]*10) + bcd[2]); - if (!bcd[0] && !bcd[1]) + } + if (!bcd[0] && !bcd[1]) { x = 0; - else + } else { x = ((bcd[1]*10) + bcd[0]); + } idx = 3; wmove(scr, y, x); bcd[0] = 0; @@ -967,13 +843,11 @@ void *run(void *args) { wmove(scr, y, x); } wdelch(scr); - wrefresh(scr); } else if (addr[address] == '\033') { esc = 1; } else { wmove(scr, y, x); waddch(scr, addr[address]); - wrefresh(scr); if (addr[address] == '\n') { x = 0; y+=1; @@ -1022,7 +896,7 @@ void *run(void *args) { x = ((bcd[1]*10) + bcd[0]); mvwprintw(scr, 30, 0, "x: %i, y: %i ", x, y); mvwprintw(scr, 31, 0, "bcd[3-2]: {%u, %u}, bcd[1-0]: {%u, %u}", bcd[3], bcd[2], bcd[1], bcd[0]); - wrefresh(scr); + updt = 1; idx = 3; bcd[0] = 0; bcd[1] = 0; @@ -1052,12 +926,14 @@ void *run(void *args) { } } else { if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') { + updt = 1; if (x > 0) { x--; } } else if (addr[address] == '\033') { esc = 1; } else { + updt = (!addr[0x16]); if (addr[address] == '\n') { x = 0; y+=1; @@ -1069,23 +945,22 @@ void *run(void *args) { } #endif #endif - if (regsize >= 2) { - addr[address+1] = value >> 8; - if (regsize >= 4) { - addr[address+2] = value >> 16; + switch (regsize) { + case 8: + addr[address+7] = value >> 56; + addr[address+6] = value >> 48; + addr[address+5] = value >> 40; + addr[address+4] = value >> 32; + case 4: addr[address+3] = value >> 24; - if (regsize >= 8) { - addr[address+4] = value >> 32; - addr[address+5] = value >> 40; - addr[address+6] = value >> 48; - addr[address+7] = value >> 56; - } - } + addr[address+2] = value >> 16; + case 2: + addr[address+1] = value >> 8; } break; case BCC: /* BCC Absolute. */ case BCC_Z: /* BCC Zero Matrix. */ - if (!cpu->c[thread]) + if (!getflag(C)) cpu->pc[thread] = address; break; case LSR: /* LSR Immediate. */ @@ -1096,13 +971,10 @@ void *run(void *args) { value = cpu->b[thread]; } sum = (value < 64) ? cpu->a[thread] >> value : 0; - cpu->z[thread] = (sum == 0); - cpu->n[thread] = (sum >> 63); - cpu->c[thread] = cpu->a[thread] & 1; + setflag(sum == 0, Z); + setflag(sum >> 63, N); + setflag(cpu->a[thread] & 1, C); cpu->a[thread] = sum; - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); - setflag(cpu->c[thread], C); break; case ASR: /* ASR Immediate. */ case ARB: /* Arithmetic shift Right accumulator by B. */ @@ -1112,17 +984,13 @@ void *run(void *args) { value = cpu->b[thread]; sign = cpu->a[thread] & 0x8000000000000000; sum = (value < 64) ? (cpu->a[thread] >> value) | sign : 0; - cpu->z[thread] = (sum == 0); - cpu->n[thread] = (sum >> 63); - cpu->c[thread] = cpu->a[thread] & 1; + setflag(sum == 0, Z); + setflag(sum >> 63, N); + setflag(cpu->a[thread] & 1, C); cpu->a[thread] = sum; - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); - setflag(cpu->c[thread], C); break; case CLC: /* CLear Carry flag. */ - cpu->c[thread] = 0; - setflag(cpu->c[thread], C); + setflag(0, C); break; case LDB: /* LDB Immediate. */ case LDA: /* LDA Immediate. */ @@ -1212,14 +1080,12 @@ void *run(void *args) { cpu->x[thread] = value; break; } - cpu->z[thread] = (value == 0); - cpu->n[thread] = (value >> 63); - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); + setflag(value == 0, Z); + setflag(value >> 63, N); break; case BEQ: /* BEQ Absolute. */ case BEQ_Z: /* BEQ Zero Matrix. */ - if (cpu->z[thread]) + if (getflag(Z)) cpu->pc[thread] = address; break; case ROL: /* ROL Immediate. */ @@ -1230,18 +1096,15 @@ void *run(void *args) { value = cpu->b[thread]; } sum = cpu->a[thread] << value; - sum |= cpu->c[thread]; - cpu->z[thread] = (sum == 0); - cpu->n[thread] = (sum >> 63); - cpu->c[thread] = cpu->a[thread] >> (uint64_t)64-value; + sum |= getflag(C); + setflag(sum == 0, Z); + setflag(sum >> 63, N); + setflag(cpu->a[thread] >> (uint64_t)64-value, C); cpu->a[thread] = sum; - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); - setflag(cpu->c[thread], C); break; case BNE: /* BNE Absolute. */ case BNE_Z: /* BNE Zero Matrix. */ - if (!cpu->z[thread]) + if (!getflag(Z)) cpu->pc[thread] = address; break; case ROR: /* ROR Immediate. */ @@ -1252,18 +1115,15 @@ void *run(void *args) { value = cpu->b[thread]; } sum = cpu->a[thread] >> value; - sum |= (uint64_t)cpu->c[thread] << (uint64_t)64-value; - cpu->z[thread] = (sum == 0); - cpu->n[thread] = (sum >> 63); - cpu->c[thread] = cpu->a[thread] & 1; + sum |= (uint64_t)getflag(C) << (uint64_t)64-value; + setflag(sum == 0, Z); + setflag(sum >> 63, N); + setflag(cpu->a[thread] & 1, C); cpu->a[thread] = sum; - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); - setflag(cpu->c[thread], C); break; case BVS: /* BVS Absolute. */ case BVS_Z: /* BVS Zero Matrix. */ - if (cpu->v[thread]) + if (getflag(V)) cpu->pc[thread] = address; break; case MUL: /* MUL Immediate. */ @@ -1273,20 +1133,16 @@ void *run(void *args) { if (opcode == MAB) { value = cpu->b[thread]; } - sum = cpu->a[thread]*value+cpu->c[thread]; + sum = cpu->a[thread]*value+getflag(C); cpu->a[thread] = sum; - cpu->z[thread] = (sum == 0); - cpu->n[thread] = (sum >> 63); - cpu->v[thread] = !((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000); - cpu->c[thread] = (!((cpu->a[thread]^sum) && (cpu->a[thread]^value)) && (cpu->a[thread] >= ((uint64_t)1 << 32) && value >= ((uint64_t)1 << 32))); - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); - setflag(cpu->v[thread], V); - setflag(cpu->c[thread], C); + setflag(sum == 0, Z); + setflag(sum >> 63, N); + setflag(!((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000), V); + setflag((!((cpu->a[thread]^sum) && (cpu->a[thread]^value)) && (cpu->a[thread] >= ((uint64_t)1 << 32) && value >= ((uint64_t)1 << 32))), C); break; case BVC: /* BVC Absolute. */ case BVC_Z: /* BVC Zero Matrix. */ - if (!cpu->v[thread]) + if (!getflag(V)) cpu->pc[thread] = address; break; case DIV: /* DIV Immediate. */ @@ -1301,30 +1157,27 @@ void *run(void *args) { } sum = cpu->a[thread]/value; cpu->a[thread] = sum; - cpu->z[thread] = (sum == 0); - cpu->n[thread] = (sum >> 63); - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); + setflag(sum == 0, Z); + setflag((sum >> 63), N); break; case CLV: /* CLear oVerflow flag. */ - cpu->v[thread] = 0; - setflag(cpu->v[thread], V); + setflag(0, V); break; case RTS: /* ReTurn from Subroutine. */ - /*if (addrsize) - stksize = 32; - else - stksize = 8;*/ - cpu->sp[thread]++;cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]]; + tmp2 = 0; switch (addrsize) { - case 1: - cpu->sp[thread]++;cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 8; - cpu->sp[thread]++;cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 16; - case 3: - cpu->sp[thread]++;cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 24; - case 2: - cpu->sp[thread]++;cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 32; - cpu->sp[thread]++;cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 40; + case 3: stksize = 3; break; + case 2: stksize = 5; break; + case 1: stksize = 2; break; + case 0: stksize = 0; break; + } + cpu->sp[thread]++;reg = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF;stksize--; + switch (stksize) { + case 4: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 3: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 2: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 1: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 0: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); } break; case CPB: /* CPB Immediate. */ @@ -1384,14 +1237,10 @@ void *run(void *args) { break; } sum = reg-value; - cpu->n[thread] = (sum & 0x8000000000000000); - cpu->v[thread] = ((reg^value) & 0x8000000000000000) && ((reg^sum) & 0x8000000000000000); - cpu->z[thread] = (sum == 0); - cpu->c[thread] = (reg >= value); - setflag(cpu->n[thread], N); - setflag(cpu->v[thread], V); - setflag(cpu->z[thread], Z); - setflag(cpu->c[thread], C); + setflag(sum >> 63, N); + setflag(((reg^value) & 0x8000000000000000) && ((reg^sum) & 0x8000000000000000), V); + setflag(sum == 0, Z); + setflag(reg >= value, C); break; case ENT: /* ENd Thread. */ cpu->crt &= ~value; @@ -1400,15 +1249,16 @@ void *run(void *args) { cpu->pc[i+1] = cpu->pc[0]+(i+1); break; case RTI: /* ReTurn from Interrupt routine. */ - 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[thread]++; - if (i) - cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; - else - cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]]; - } + cpu->sp[thread] += 9; + cpu->ps = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-8)] << (thread << 3); + cpu->pc[thread] = (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-7)]; + cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-6)] << 8; + cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-5)] << 16; + cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-4)] << 24; + cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-3)] << 32; + cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-2)] << 40; + cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-1)] << 48; + cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 56; break; case INC: /* INC Accumulator. */ case INB: @@ -1417,27 +1267,25 @@ void *run(void *args) { switch (opcode) { case INC: cpu->a[thread]+=1; - cpu->z[thread] = (cpu->a[thread] == 0); - cpu->n[thread] = (cpu->a[thread] >> 63); + setflag(cpu->a[thread] == 0, Z); + setflag((cpu->a[thread] >> 63), N); break; case INB: cpu->b[thread]+=1; - cpu->z[thread] = (cpu->b[thread] == 0); - cpu->n[thread] = (cpu->b[thread] >> 63); + setflag(cpu->b[thread] == 0, Z); + setflag((cpu->b[thread] >> 63), N); break; case INY: cpu->y[thread]+=1; - cpu->z[thread] = (cpu->y[thread] == 0); - cpu->n[thread] = (cpu->y[thread] >> 63); + setflag(cpu->y[thread] == 0, Z); + setflag((cpu->y[thread] >> 63), N); break; case INX: cpu->x[thread]+=1; - cpu->z[thread] = (cpu->x[thread] == 0); - cpu->n[thread] = (cpu->x[thread] >> 63); + setflag(cpu->x[thread] == 0, Z); + setflag((cpu->x[thread] >> 63), N); break; } - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); break; case DEC: /* DEC Accumulator. */ case DEB: @@ -1446,105 +1294,101 @@ void *run(void *args) { switch (opcode) { case DEC: cpu->a[thread]-=1; - cpu->z[thread] = (cpu->a[thread] == 0); - cpu->n[thread] = (cpu->a[thread] >> 63); + setflag(cpu->a[thread] == 0, Z); + setflag((cpu->a[thread] >> 63), N); break; case DEB: cpu->b[thread]-=1; - cpu->z[thread] = (cpu->b[thread] == 0); - cpu->n[thread] = (cpu->b[thread] >> 63); + setflag(cpu->b[thread] == 0, Z); + setflag((cpu->b[thread] >> 63), N); break; case DEY: cpu->y[thread]-=1; - cpu->z[thread] = (cpu->y[thread] == 0); - cpu->n[thread] = (cpu->y[thread] >> 63); + setflag(cpu->y[thread] == 0, Z); + setflag((cpu->y[thread] >> 63), N); break; case DEX: cpu->x[thread]-=1; - cpu->z[thread] = (cpu->x[thread] == 0); - cpu->n[thread] = (cpu->x[thread] >> 63); + setflag(cpu->x[thread] == 0, Z); + setflag((cpu->x[thread] >> 63), N); break; } - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); break; case JSL: /* Jump to Subroutine Long. */ switch (addrsize) { - case 3: - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 56;cpu->sp[thread]--; - case 2: - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 48;cpu->sp[thread]--; - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 40;cpu->sp[thread]--; - case 1: - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 32;cpu->sp[thread]--; - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 24;cpu->sp[thread]--; - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 16;cpu->sp[thread]--; - case 0: - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 8;cpu->sp[thread]--; - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] & 0xFF;cpu->sp[thread]--; + case 3: stksize = 7; break; + case 2: stksize = 6; break; + case 1: stksize = 4; break; + case 0: stksize = 1; break; + } + switch (stksize) { + case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (7<<3);cpu->sp[thread]--; + case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (6<<3);cpu->sp[thread]--; + case 5: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (5<<3);cpu->sp[thread]--; + case 4: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (4<<3);cpu->sp[thread]--; + case 3: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (3<<3);cpu->sp[thread]--; + case 2: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (2<<3);cpu->sp[thread]--; + case 1: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (1<<3);cpu->sp[thread]--; + case 0: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] & 0xFF; cpu->sp[thread]--; } cpu->pc[thread] = address; break; case INC_AB: /* INC Absolute. */ case INC_Z: /* INC Zero Matrix. */ addr[address]++; - cpu->z[thread] = (addr[address] == 0); - cpu->n[thread] = (addr[address] >> 7); - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); + setflag(addr[address] == 0, Z); + setflag(addr[address] >> 7, N); break; case NOP: /* No OPeration. */ break; case RTL: /* ReTurn from subroutine Long. */ - cpu->sp[thread]++;cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]]; - cpu->sp[thread]++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 8; + tmp2 = 1; switch (addrsize) { - case 1: - cpu->sp[thread]++;cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 16; - cpu->sp[thread]++;cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 24; - cpu->sp[thread]++;cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 32; - case 2: - cpu->sp[thread]++;cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 40; - cpu->sp[thread]++;cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 48; - case 3: - cpu->sp[thread]++;cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 56; + case 3: stksize = 7; break; + case 2: stksize = 6; break; + case 1: stksize = 4; break; + case 0: stksize = 0; break; } - /*for (uint8_t i = 0; i < stksize; i+=8) { - cpu->sp[thread]++; - if (i) - cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; - else - cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]]; - }*/ + cpu->sp[thread] += 2; + stksize -= 2; + cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-1)] & 0xFF; + cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 8; + switch (stksize) { + case 5: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 4: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 3: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 2: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 1: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + case 0: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3); + } + break; break; case DEC_AB: /* DEC Absolute. */ case DEC_Z: /* DEC Zero Matrix. */ addr[address]--; - cpu->z[thread] = (addr[address] == 0); - cpu->n[thread] = (addr[address] >> 7); - setflag(cpu->z[thread], Z); - setflag(cpu->n[thread], N); + setflag(addr[address] == 0, Z); + setflag(addr[address] >> 7, N); break; case BRK: /* BReaK. */ - for (int8_t i = stksize; i >= 0; i-=8) { - if (i) - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> i; - else - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] & 0xFF; - cpu->sp[thread]--; - } - addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->ps >> thread << 3; - cpu->sp[thread]--; - cpu->i[thread] = 1; - setflag(cpu->i[thread], I); - cpu->pc[thread] = (uint64_t)addr[0xFFE0] - | (uint64_t)addr[0xFFE1] << 8 - | (uint64_t)addr[0xFFE2] << 16 - | (uint64_t)addr[0xFFE3] << 24 - | (uint64_t)addr[0xFFE4] << 32 - | (uint64_t)addr[0xFFE5] << 40 - | (uint64_t)addr[0xFFE6] << 48 - | (uint64_t)addr[0xFFE7] << 56; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 56; + addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-1)] = (uint64_t)cpu->pc[thread] >> 48; + addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-2)] = (uint64_t)cpu->pc[thread] >> 40; + addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-3)] = (uint64_t)cpu->pc[thread] >> 32; + addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-4)] = (uint64_t)cpu->pc[thread] >> 24; + addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-5)] = (uint64_t)cpu->pc[thread] >> 16; + addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-6)] = (uint64_t)cpu->pc[thread] >> 8; + addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-7)] = (uint64_t)cpu->pc[thread] & 0xFF; + addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-8)] = (uint64_t)cpu->ps >> (thread << 3); + cpu->sp[thread] -= 9; + setflag(1, I); + cpu->pc[thread] = (uint64_t)addr[0xFFE0]; + cpu->pc[thread] += (uint64_t)addr[0xFFE1] << 8; + cpu->pc[thread] += (uint64_t)addr[0xFFE2] << 16; + cpu->pc[thread] += (uint64_t)addr[0xFFE3] << 24; + cpu->pc[thread] += (uint64_t)addr[0xFFE4] << 32; + cpu->pc[thread] += (uint64_t)addr[0xFFE5] << 40; + cpu->pc[thread] += (uint64_t)addr[0xFFE6] << 48; + cpu->pc[thread] += (uint64_t)addr[0xFFE7] << 56; break; case WAI: /* WAit for Interrupt. */ wai = 1; @@ -1559,6 +1403,7 @@ void *run(void *args) { break; } ins++; + step = addr[STEP_ADDR]; if (step) { pthread_mutex_lock(&main_mutex); pthread_cond_signal(&main_cond); @@ -1566,27 +1411,23 @@ void *run(void *args) { pthread_mutex_lock(&mutex); pthread_cond_wait(&cond, &mutex); pthread_mutex_unlock(&mutex); + #if debug && !bench + wrefresh(scr); + #endif } if (!addr[CTRL_ADDR]) kbd_ln = 0; else kbd_ln = 1; - /*if (kbd_ln) - usleep(16666); - usleep(500000);*/ #if debug && !bench #if keypoll pthread_mutex_lock(&mutex); #endif - /*mvwprintw(scr, getmaxy(scr)-lines, 0, "Operand: $%llx" - ", $%04llx: $%02x, $%04llx: $%02x" - ", $1000: $%02x, $1001: $%02x " - , value - , RX_ADDR, addr[RX_ADDR], TX_ADDR, addr[TX_ADDR] - , addr[0x1000], addr[0x1001]);*/ mvwprintw(scr, (6*thread)+1, 0, "Instructions executed: %llu, Clock cycles: %llu\r", ins, iclk); - wrefresh(scr); + if (!step) { + wrefresh(scr); + } #if keypoll pthread_mutex_unlock(&mutex); #endif @@ -1702,6 +1543,9 @@ int main(int argc, char **argv) { step_key = 0; addr[CTRL_ADDR] = 0; kbd_ln = 0; + #if !debug + wrefresh(scr); + #endif } } #if keypoll @@ -1727,12 +1571,12 @@ int main(int argc, char **argv) { if (kbd_rdy && c < 0x100) { addr[RX_ADDR] = (uint8_t)c; addr[CTRL_ADDR] = 1; - #if debug && !bench + #if debug && !bench wmove(scr, getmaxy(scr)-1, 0); wprintw(scr, "c: %i, x: %i, y: %i, i: %i.", c, x, y, i++); wmove(scr, y, x); wrefresh(scr); - #endif + #endif } if (c == '\n') kbd_ln = 1; diff --git a/test/asr.s b/test/asr.s index 4bc388f..c01269e 100644 --- a/test/asr.s +++ b/test/asr.s @@ -6,9 +6,10 @@ reset: cps start: - lda.q #$-FFFF - ldb.q #-1 - + lda #0 + sbc #$FFFF + ldb #0 + deb signshft: asr #1 cab @@ -18,6 +19,5 @@ signshft: .org $FFC0 .qword reset .org $0 -v done diff --git a/test/subroutine.s b/test/subroutine.s index 03447fd..65e46ca 100644 --- a/test/subroutine.s +++ b/test/subroutine.s @@ -3,7 +3,9 @@ buf: .org $0 ptr: -.qword buf +.qword $0 +ptr2: +.qword $0 .org $8000 reset: @@ -13,32 +15,34 @@ reset: start: ldy #0 ldb #0 - inb - stb $C010 - deb + tyx + lda.w #buf + sta.q ptr + adc #8 + sta.q ptr2 + ;inb + ;stb $C010 + ;deb +bench: jsl clr_buf - jmp start + jmp bench clr_buf: - lda #0 - cpy.w #$1FFF - bcs clr_buf_end - sta.q (ptr), y - tya - adc #8 - tay - tba - sta.q (ptr), y - tya - adc #8 - tay - tba - jmp clr_buf + tba ; Reset the Accumulator. + cpy.w #$1FFF ; Did we clear all of the screen buffer? + bcs clr_buf_end ; Yes, so we're done. + sta.q (ptr), y ; No, so clear eight bytes. + sta.q (ptr2), y ; Clear eight more bytes. + tya ; Copy the buffer index. + adc #$10 ; Increment the index by 16. + tay ; Update the index. + jmp clr_buf ; Keep looping. clr_buf_end: - ldy.w #0 - rtl - + tay ; Set the index back to zero. + rtl ; End of clr_buf. +;.org $C010 +;.byte $1 .org $FFC0 .qword reset done -- cgit v1.2.3-13-gbd6f