From 63d5046ecabd5fd1524d3c4bc4590176c3b8a4eb Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Thu, 23 Jan 2020 13:55:00 -0500 Subject: Start optimizing the emulator. I also added a new input testing program called input-3.s, which contains a mostly working editor. --- programs/pos-check.s | 12 ++ programs/scr-to-buf.s | 7 + sux.c | 194 +++++++++++-------- test/input-2.s | 412 +++++++++++++++++++++++++++++++++++++++ test/input-3.s | 522 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1063 insertions(+), 84 deletions(-) create mode 100644 programs/pos-check.s create mode 100644 programs/scr-to-buf.s create mode 100644 test/input-2.s create mode 100644 test/input-3.s diff --git a/programs/pos-check.s b/programs/pos-check.s new file mode 100644 index 0000000..315147b --- /dev/null +++ b/programs/pos-check.s @@ -0,0 +1,12 @@ +cmd_clr: + lda scr_row + cmp #23 + beq cmd_vwrap + inc scr_row + jmp cmd_clr_end +cmd_vwrap: + jsl rset_row +cmd_clr_end: + jsl update_pos + lda #0 + rtl diff --git a/programs/scr-to-buf.s b/programs/scr-to-buf.s new file mode 100644 index 0000000..1787dc3 --- /dev/null +++ b/programs/scr-to-buf.s @@ -0,0 +1,7 @@ +scr_to_buf: + tax + mul #80 + adc scr_col + tay + txa + rtl diff --git a/sux.c b/sux.c index 1fc8fe2..8cfecdb 100644 --- a/sux.c +++ b/sux.c @@ -14,18 +14,21 @@ #endif #define THREADS 1 -#define BENCH_INST 100000000*THREADS +#define BENCH_INST 100000000 << THREADS-1 #define CTRL_ADDR 0xC000 #define TX_ADDR 0xC001 #define RX_ADDR 0xC002 #define CURSES_BACKSPACE 0x7F +#define setflag(flag, bit) (flag) ? (cpu->ps |= (bit << (thread << 3))) : (cpu->ps &= ~(bit << (thread << 3))) + uint64_t clk[THREADS]; /* Per Thread Clock cycles. */ uint64_t tclk; /* Total Clock cycles. */ uint64_t inst[THREADS]; uint64_t inss; uint8_t threads_done = 0; uint8_t kbd_rdy = 0; +uint8_t kbd_ln = 0; uint8_t wai = 0; uint8_t irq = 0; #if !bench @@ -85,7 +88,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; - (cpu->i[thread]) ? (cpu->ps |= (I << 8*thread)) : (cpu->ps &= ~(I << 8*thread)); + setflag(cpu->i[thread], I); cpu->pc[thread] = (uint64_t)addr[0xFFA0] | (uint64_t)addr[0xFFA1] << 8 | (uint64_t)addr[0xFFA2] << 16 @@ -314,7 +317,15 @@ void *run(void *args) { break; } - mvwprintw(scr, 29, 0, "address: $%016llx\r", address); + mvwprintw(scr, 29, 0, "address: $%016llx, scr_row: %02u, scr_col: %02u, scr_lnst: $%04x, scr_lncnt: $%04x\r", address, addr[0], addr[1], addr[2] | (addr[3] << 8), addr[4] | (addr[5] << 8)); + mvwprintw(scr, 32, 0, "%02x %02x %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x\r" + , addr[0x4000], addr[0x4001], addr[0x4002], addr[0x4003], addr[0x4004], addr[0x4005], addr[0x4006], addr[0x4007] + , addr[0x4008], addr[0x4009], addr[0x400A], addr[0x400B], addr[0x400C], addr[0x400D], addr[0x400E], addr[0x400F]); + mvwprintw(scr, 33, 0, "%02x %02x %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x\r" + , addr[0x4010], addr[0x4011], addr[0x4012], addr[0x4013], addr[0x4014], addr[0x4015], addr[0x4016], addr[0x4017] + , addr[0x4018], addr[0x4019], addr[0x401A], addr[0x401B], addr[0x401C], addr[0x401D], addr[0x401E], addr[0x401F]); wrefresh(scr); #if keypoll pthread_mutex_unlock(&mutex); @@ -345,16 +356,17 @@ void *run(void *args) { cpu->n[thread] = (sum >> 63); cpu->v[thread] = !((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000); cpu->c[thread] = (sum < value); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); - (cpu->v[thread]) ? (cpu->ps |= (V << 8*thread)) : (cpu->ps &= ~(V << 8*thread)); - (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); + 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); break; case PHB: /* PusH B register to stack. */ tmp = addr[cpu->pc[thread]++]; if (tmp > 7) tmp = 7; - for (int8_t i = tmp*8; i >= 0; i-=8) { + for (int8_t i = tmp<<3; i >= 0; i-=8) { if (i) addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->b[thread] >> i; else @@ -366,7 +378,7 @@ void *run(void *args) { tmp = addr[cpu->pc[thread]++]; if (tmp > 7) tmp = 7; - for (int8_t i = tmp*8; i >= 0; i-=8) { + for (int8_t i = tmp<<3; i >= 0; i-=8) { if (i) addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->ps >> i; else @@ -378,7 +390,7 @@ void *run(void *args) { tmp = addr[cpu->pc[thread]++]; if (tmp > 7) tmp = 7; - for (int8_t i = tmp*8; i >= 0; i-=8) { + for (int8_t i = tmp<<3; i >= 0; i-=8) { if (i) addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->a[thread] >> i; else @@ -390,7 +402,7 @@ void *run(void *args) { tmp = addr[cpu->pc[thread]++]; if (tmp > 7) tmp = 7; - for (int8_t i = tmp*8; i >= 0; i-=8) { + for (int8_t i = tmp<<3; i >= 0; i-=8) { if (i) addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->y[thread] >> i; else @@ -451,14 +463,14 @@ void *run(void *args) { cpu->z[thread] = (cpu->x[thread] == 0); cpu->n[thread] = (cpu->x[thread] >> 63); } - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); + setflag(cpu->z[thread], Z); + setflag(cpu->n[thread], N); break; case PHX: /* PusH X register to stack. */ tmp = addr[cpu->pc[thread]++]; if (tmp > 7) tmp = 7; - for (int8_t i = tmp*8; i >= 0; i-=8) { + for (int8_t i = tmp<<3; i >= 0; i-=8) { if (i) addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->x[thread] >> i; else @@ -481,17 +493,17 @@ void *run(void *args) { cpu->n[thread] = (sum >> 63); cpu->v[thread] = ((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000); cpu->c[thread] = (sum > value); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); - (cpu->v[thread]) ? (cpu->ps |= (V << 8*thread)) : (cpu->ps &= ~(V << 8*thread)); - (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); + setflag(cpu->z[thread], Z); + setflag(cpu->n[thread], N); + setflag(cpu->v[thread], V); + setflag(cpu->c[thread], C); cpu->a[thread] = sum; break; case PLB: /* PuLl B register from stack. */ tmp = addr[cpu->pc[thread]++]; if (tmp > 7) tmp = 7; - for (uint8_t i = 0; i < (tmp+1)*8; i+=8) { + for (uint8_t i = 0; i < (tmp+1)<<3; i+=8) { cpu->sp[thread]++; if (i) cpu->b[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; @@ -503,7 +515,7 @@ void *run(void *args) { tmp = addr[cpu->pc[thread]++]; if (tmp > 7) tmp = 7; - for (uint8_t i = 0; i < (tmp+1)*8; i+=8) { + for (uint8_t i = 0; i < (tmp+1)<<3; i+=8) { cpu->sp[thread]++; if (i) cpu->ps += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; @@ -515,7 +527,7 @@ void *run(void *args) { tmp = addr[cpu->pc[thread]++]; if (tmp > 7) tmp = 7; - for (uint8_t i = 0; i < (tmp+1)*8; i+=8) { + for (uint8_t i = 0; i < (tmp+1)<<3; i+=8) { cpu->sp[thread]++; if (i) cpu->a[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; @@ -527,7 +539,7 @@ void *run(void *args) { tmp = addr[cpu->pc[thread]++]; if (tmp > 7) tmp = 7; - for (uint8_t i = 0; i < (tmp+1)*8; i+=8) { + for (uint8_t i = 0; i < (tmp+1)<<3; i+=8) { cpu->sp[thread]++; if (i) cpu->y[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; @@ -539,7 +551,7 @@ void *run(void *args) { tmp = addr[cpu->pc[thread]++]; if (tmp > 7) tmp = 7; - for (uint8_t i = 0; i < (tmp+1)*8; i+=8) { + for (uint8_t i = 0; i < (tmp+1)<<3; i+=8) { cpu->sp[thread]++; if (i) cpu->x[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i; @@ -555,7 +567,7 @@ void *run(void *args) { stksize = 24; else stksize = 0; - for (int8_t i = 24; i >= 0; i-=8) { + 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 @@ -574,21 +586,21 @@ void *run(void *args) { cpu->a[thread] &= value; cpu->z[thread] = (value == 0); cpu->n[thread] = (value >> 63); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); + setflag(cpu->z[thread], Z); + setflag(cpu->n[thread], N); break; case STT: /* STart Thread. */ cpu->crt |= value; for (uint8_t i = 0; i < 7; i++) { if ((value >> i) & 1) { - address = (uint64_t)addr[tv+(8*i)] - | (uint64_t)addr[tv+1+(8*i)] << 8 - | (uint64_t)addr[tv+2+(8*i)] << 16 - | (uint64_t)addr[tv+3+(8*i)] << 24 - | (uint64_t)addr[tv+4+(8*i)] << 32 - | (uint64_t)addr[tv+5+(8*i)] << 40 - | (uint64_t)addr[tv+6+(8*i)] << 48 - | (uint64_t)addr[tv+7+(8*i)] << 56; + address = (uint64_t)addr[tv+(i<<3)] + | (uint64_t)addr[tv+1+(i<<3)] << 8 + | (uint64_t)addr[tv+2+(i<<3)] << 16 + | (uint64_t)addr[tv+3+(i<<3)] << 24 + | (uint64_t)addr[tv+4+(i<<3)] << 32 + | (uint64_t)addr[tv+5+(i<<3)] << 40 + | (uint64_t)addr[tv+6+(i<<3)] << 48 + | (uint64_t)addr[tv+7+(i<<3)] << 56; cpu->pc[i+1] = address; } } @@ -608,12 +620,12 @@ void *run(void *args) { cpu->a[thread] |= value; cpu->z[thread] = (value == 0); cpu->n[thread] = (value >> 63); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); + setflag(cpu->z[thread], Z); + setflag(cpu->n[thread], N); break; case SEI: /* SEt Interrupt. */ cpu->i[thread] = 1; - (cpu->ps |= (I << 8*thread)); + setflag(cpu->i[thread], I); break; case BNG: /* BNG Absolute. */ case 0x74: /* BNG Zero Matrix. */ @@ -630,12 +642,12 @@ void *run(void *args) { cpu->a[thread] ^= value; cpu->z[thread] = (value == 0); cpu->n[thread] = (value >> 63); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); + setflag(cpu->z[thread], Z); + setflag(cpu->n[thread], N); break; case CLI: /* CLear Interrupt. */ cpu->i[thread] = 0; - (cpu->ps &= ~(I << 8*thread)); + setflag(cpu->i[thread], I); break; case BCS: /* BCS Absolute. */ case 0x84: /* BCS Zero Matrix. */ @@ -654,13 +666,13 @@ void *run(void *args) { cpu->n[thread] = (sum >> 63); cpu->c[thread] = cpu->a[thread] >> 64-value; cpu->a[thread] = sum; - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); - (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); + 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; - (cpu->ps |= (C << 8*thread)); + setflag(cpu->c[thread], C); break; case STA: /* STA Absolute. */ case STY: /* STY Absolute. */ @@ -760,7 +772,11 @@ void *run(void *args) { break; } } else { - if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') { + if (addr[address] == 0xC) { + x=0,y=0; + wclear(scr); + wmove(scr, y, x); + } else if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') { if (x > 0) { x--; wmove(scr, y, x); @@ -820,6 +836,7 @@ void *run(void *args) { else 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); idx = 3; bcd[0] = 0; @@ -893,9 +910,9 @@ void *run(void *args) { cpu->n[thread] = (sum >> 63); cpu->c[thread] = cpu->a[thread] & 1; cpu->a[thread] = sum; - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); - (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); + 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. */ @@ -909,13 +926,13 @@ void *run(void *args) { cpu->n[thread] = (sum >> 63); cpu->c[thread] = cpu->a[thread] & 1; cpu->a[thread] = sum; - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); - (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); + 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; - (cpu->ps &= ~(C << 8*thread)); + setflag(cpu->c[thread], C); break; case LDB: /* LDB Immediate. */ case LDA: /* LDA Immediate. */ @@ -978,8 +995,8 @@ void *run(void *args) { cpu->x[thread] = value; cpu->z[thread] = (value == 0); cpu->n[thread] = (value >> 63); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); + setflag(cpu->z[thread], Z); + setflag(cpu->n[thread], N); break; case BEQ: /* BEQ Absolute. */ case 0xA4: /* BEQ Zero Matrix. */ @@ -999,13 +1016,13 @@ void *run(void *args) { cpu->n[thread] = (sum >> 63); cpu->c[thread] = cpu->a[thread] >> (uint64_t)64-value; cpu->a[thread] = sum; - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); - (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); + setflag(cpu->z[thread], Z); + setflag(cpu->n[thread], N); + setflag(cpu->c[thread], C); break; case SSP: /* Set Stack Protection flag. */ cpu->s[thread] = 1; - (cpu->ps |= (S << 8*thread)); + setflag(cpu->s[thread], S); break; case BNE: /* BNE Absolute. */ case 0xB4: /* BNE Zero Matrix. */ @@ -1025,13 +1042,13 @@ void *run(void *args) { cpu->n[thread] = (sum >> 63); cpu->c[thread] = cpu->a[thread] & 1; cpu->a[thread] = sum; - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); - (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); + setflag(cpu->z[thread], Z); + setflag(cpu->n[thread], N); + setflag(cpu->c[thread], C); break; case CSP: /* Clear Stack Protection flag. */ cpu->s[thread] = 0; - (cpu->ps &= ~(S << 8*thread)); + setflag(cpu->s[thread], S); break; case BVS: /* BVS Absolute. */ case 0xC4: /* BVS Zero Matrix. */ @@ -1051,14 +1068,14 @@ void *run(void *args) { 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))); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); - (cpu->v[thread]) ? (cpu->ps |= (V << 8*thread)) : (cpu->ps &= ~(V << 8*thread)); - (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); + setflag(cpu->z[thread], Z); + setflag(cpu->n[thread], N); + setflag(cpu->v[thread], V); + setflag(cpu->c[thread], C); break; case SEV: /* SEt oVerflow flag. */ cpu->v[thread] = 1; - (cpu->ps |= (V << 8*thread)); + setflag(cpu->v[thread], V); break; case BVC: /* BVC Absolute. */ case 0xD4: /* BVC Zero Matrix. */ @@ -1079,12 +1096,12 @@ void *run(void *args) { cpu->a[thread] = sum; cpu->z[thread] = (sum == 0); cpu->n[thread] = (sum >> 63); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); + setflag(cpu->z[thread], Z); + setflag(cpu->n[thread], N); break; case CLV: /* CLear oVerflow flag. */ cpu->v[thread] = 0; - (cpu->ps &= ~(V << 8*thread)); + setflag(cpu->v[thread], V); break; case RTS: /* ReTurn from Subroutine. */ if (addrsize) @@ -1138,10 +1155,10 @@ void *run(void *args) { cpu->v[thread] = ((reg^value) & 0x8000000000000000) && ((reg^sum) & 0x8000000000000000); cpu->z[thread] = (sum == 0) ? 1 : 0; cpu->c[thread] = (sum > value) ? 1 : 0; - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); - (cpu->v[thread]) ? (cpu->ps |= (V << 8*thread)) : (cpu->ps &= ~(V << 8*thread)); - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread)); + setflag(cpu->n[thread], N); + setflag(cpu->v[thread], V); + setflag(cpu->z[thread], Z); + setflag(cpu->c[thread], C); break; case ENT: /* ENd Thread. */ cpu->crt &= ~value; @@ -1181,8 +1198,8 @@ void *run(void *args) { cpu->z[thread] = (cpu->x[thread] == 0); cpu->n[thread] = (cpu->x[thread] >> 63); } - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); + setflag(cpu->z[thread], Z); + setflag(cpu->n[thread], N); break; case 0x04: /* JMP Indirect. */ case 0x14: /* JMP Indexed Indirect. */ @@ -1212,8 +1229,8 @@ void *run(void *args) { cpu->z[thread] = (cpu->x[thread] == 0); cpu->n[thread] = (cpu->x[thread] >> 63); } - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); + setflag(cpu->z[thread], Z); + setflag(cpu->n[thread], N); break; case JSL: /* Jump to Subroutine Long. */ if (addrsize) @@ -1253,17 +1270,17 @@ void *run(void *args) { addr[address]--; break; case BRK: /* BReaK. */ - for (int8_t i = 56; i >= 0; i-=8) { + 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]-1 >> 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]-1 & 0xFF; + 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 >> 8*thread; + addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->ps >> thread << 3; cpu->sp[thread]--; cpu->i[thread] = 1; - (cpu->i[thread]) ? (cpu->ps |= (I << 8*thread)) : (cpu->ps &= ~(I << 8*thread)); + setflag(cpu->i[thread], I); cpu->pc[thread] = (uint64_t)addr[0xFFE0] | (uint64_t)addr[0xFFE1] << 8 | (uint64_t)addr[0xFFE2] << 16 @@ -1286,6 +1303,13 @@ void *run(void *args) { break; } ins++; + /*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); @@ -1409,6 +1433,7 @@ int main(int argc, char **argv) { curs_set(1); c = 0; addr[CTRL_ADDR] = 0; + kbd_ln = 0; } #if keypoll pthread_mutex_lock(&mutex); @@ -1426,7 +1451,8 @@ int main(int argc, char **argv) { default: addr[RX_ADDR] = (uint8_t)c; addr[CTRL_ADDR] = 1; - kbd_rdy = 1; + if (c == '\n') + kbd_ln = 1; #if !keypoll pthread_mutex_lock(&mutex); pthread_cond_signal(&cond); diff --git a/test/input-2.s b/test/input-2.s new file mode 100644 index 0000000..f5cb49e --- /dev/null +++ b/test/input-2.s @@ -0,0 +1,412 @@ +; Testing input. +; +; Writen in Sux assembly by +; mr b0nk 500 + +; Instruction mnemonics, +; and opcodes. +.org $1000 +tok: + .byte "dab" +msg: + .byte "oof, you divided a, and b on me.\n" + +; Input buffer. +.org $2000 +buffer: + +.org $2800 +cmd_buf: + +; Initalize some variables. +.org $0 +scr_row: + .byte $0 +scr_col: + .byte $0 +a: + .byte $0 +b: + .byte $0 +c: + .byte $0 +d: + .byte $0 +e: + .byte $0 +string: + .byte "Please, type something.\n" +string2: + .byte "You typed, " +end: + .byte $0 + +; String Pointer +ptr: + .qword buffer +cptr: + .qword cmd_buf +tptr: + .qword tok +mptr: + .qword msg + + +; Main program +.org $8000 +reset: + cps + ldx.w #$FFFF + txs + ldy #0 + lda #0 +clr_buf: + cpy.w #$7FF + beq start + sta (ptr), y + iny + jmp clr_buf + +start: + lda #0 + sta $C000 + tax ; Reset x. + tay ; Reset y. + jsl clr_cbuf + jmp print + +clr_cbuf: + cpy.w #$3FF + beq clr_cbuf_end + sta (cptr), y + iny + jmp clr_cbuf +clr_cbuf_end: + ldy #0 + rtl + +rset_a: + lda #1 +read: + lda $C000 ; Get control register. + beq rset_a ; Loop until we get a character. + jmp getchar ; We got a key. +sleep: + lda end + bne spin ; Are we done with getting input? + +print: + lda string, x ; Get character at offset x. + beq rset_a ; Did we find a null terminator? + sta $C001 ; Print character. + inx ; Increment offset. + cmp #$A + beq inc_row + inc scr_col + jmp print +inc_row: + lda #0 + sta scr_col + lda #$42 + sta c + jsl isdown + jmp print ; Keep printing more characters. + +getchar: + lda $C002 ; Get typed character. + cmp #$1B + beq esc + cmp #$A + beq nl ; Did the user type a newline? + cmp #8 + beq bs ; Did the user type a backspace? + cmp #$7F + beq bs ; Did the user type a backspace? +echo: + sta a + ldx scr_col + cpx #79 + bne echo_print +linewrap: + inc scr_row + ldx #0 + stx scr_col + lda scr_row + jsl update_pos +echo_print: + lda a + sta $C001 ; Echo typed character. + inc scr_col ; Increment the cursor's x coordinate. + sta (ptr), y ; Store typed character into the input buffer. + iny + jmp rset_a ; Start getting user input. + +esc: + lda $C000 ; Skip the '['. + lda $C000 ; Get the next character. + beq read ; 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. + jsl isup ; Check if the user pressed up. + lda d + bne esc_end + jsl isdown ; Check if the user pressed down. + lda d + bne esc_end + lda #0 + jsl isleft ; Check if the user pressed left. + lda d + bne esc_end + jsl isright ; Check if the user pressed right. +esc_end: + lda #0 + sta d + jmp rset_a ; Go back to getting user input. + +isup: + lda scr_row ; Is the cursor at the top of the screen? + beq isup_done ; Yes, so return. + lda c ; No, so load the escape code back into the accumulator. + cmp #$41 ; Did the user press the up arrow key? + beq up ; Yes, so move the cursor up. +isup_done: + rtl ; End of isup. + +isdown: + lda scr_row ; Start checking the y coordinate of the cursor. + cmp #23 ; Is the cursor at the bottom of the screen? + beq isdown_done ; Yes, so return. + 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. +isdown_done: + rtl ; End of isdown. + +isright: + lda scr_col ; Start checking the x coordinate of the cursor. + cmp #79 ; Is the cursor at the far right of the screen? + beq isright_end ; Yes, so return. + lda c ; No, so load the escape code back into the accumulator. + cmp #$43 ; Did the user press the right arrow key? + beq right ; Yes, so move the cursor right. +isright_end: + rtl ; End of isright. + +isleft: + lda scr_col ; Is the cursor at the far left of the screen? + beq isleft_done ; Yes, so return. + 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. +isleft_done: + rtl ; End of isleft. + +up: + dec scr_row + jsl update_pos + lda #1 + sta d + jmp isup_done +down: + inc scr_row + jsl update_pos + lda #1 + sta d + jmp isdown_done +right: + inc scr_col + jsl update_pos + jmp isright_end +left: + dec scr_col + jsl update_pos + lda #1 + sta d + jmp isleft_done + +update_pos: + lda #$1B ; Print an escape character + sta $C001 ; to the screen. + lda #$5B ; Print '[' + sta $C001 ; to the screen, and start the escape sequence. + jsl getrow ; Start printing the row number to the screen. + jsl getcol ; Start printing the column number to the screen. + lda #$48 ; Print 'H' + sta $C001 ; to the screen. + rtl ; End of update_pos. +getrow: + lda scr_row ; Get the cursor's y coordinate. + div #10 ; Divide A by 10. + adc #$30 ; Convert it to ascii, and + sta $C001 ; print to the screen. + tba ; Get the remainder. + adc #$30 ; Convert it to ascii, and + sta $C001 ; print to the screen. + rtl ; End of getrow. +getcol: + lda #$3B ; Print ';' + sta $C001 ; to the screen. + lda scr_col ; Get the cursor's x coordinate. + div #10 ; Divide A by 10. + adc #$30 ; Convert it to ascii, and + sta $C001 ; print to the screen. + tba ; Get the remainder. + adc #$30 ; Convert it to ascii, and + sta $C001 ; print to the screen. + rtl ; End of getrow. + +nl: + lda #0 + sta scr_col + sta (ptr), y ; Store said terminator into the input buffer. + lda #$42 + sta c + jsl isdown + ldy.w #0 ; Reset y, to print the result. + jsl dabbed + beq start + ldy #0 + jmp result + +back: + sta $C001 ; Print backspace. + lda #0 ; Put a null terminator, in place of the backspace. + sta (ptr), y ; Place it into the input buffer. + dey ; Decrement buffer offset. + dec scr_col + jmp read ; Get next character. + +bs: + cpy #0 ; Are we at the start of the buffer? + beq rset_a ; We are, so do not store the backspace into the buffer. + jmp back ; We are not, so add the backspace to the buffer. + +result: + ldx scr_col + cpx #79 + bne result_print +linewrap2: + inc scr_row + ldx #$0 + stx scr_col + jsl update_pos +result_print: + lda string2, y + beq rset_y ; Reset y, if we hit the null terminator. + sta $C001 ; Print 'You have typed, ' + inc scr_col ; Increment the cursor's x coordinate. + iny ; Increment offset. + jmp result ; Keep printing. + +rset_y: + ldy.w #0 ; Reset y. + ldx.w #0 ; Reset x. + lda.w #0 ; Reset a. + jmp print_buf ; Print the input buffer. +dabbed: + lda (ptr), y ; Get a character from the input buffer. + beq dab_nend ; Are we done with printing the buffer? + cmp (tptr), y + bcs dab_nend + beq chk_str + bcc dab_nend +chk_str: + iny + cpy #3 + bne dabbed + ldy #0 +pnt_msg: + ldx scr_col + cpx #79 + bne msg_pnt +linewrap3: + inc scr_row + ldx #0 + stx scr_col + jsl update_pos +msg_pnt: + lda (mptr), y ; Get a character from the input buffer. + beq dab_eqnd ; Are we done with printing the buffer? + sta $C001 ; Print said character. + inc scr_col ; Increment the cursor's x coordinate. + iny + jmp pnt_msg ; Keep printing the buffer. +dab_nend: + lda #1 + jmp dab_end +dab_eqnd: + lda #0 + jmp dab_end +dab_end: + rtl + + + +print_buf: + ldx scr_col + cpx #79 + bne buf_print +linewrap4: + inc scr_row + ldx #0 + stx scr_col + jsl update_pos +buf_print: + lda (ptr), y ; Get a character from the input buffer. + beq cmd_clr ; Are we done with printing the buffer? + sta $C001 ; Print said character. + inc scr_col ; Increment the cursor's x coordinate. + iny + jmp print_buf ; Keep printing the buffer. + +cmd_clr: + lda #0 + sta scr_col + lda #$42 + sta c + jsl isdown + jmp start + +scr_to_buf: + tax + mul #80 + adc scr_col + tay + txa + rtl + +spin: + nop + nop + nop + jmp spin + +.org $1000 +v +.org $1100 +v +.org $1200 +v +.org $8000 +v +.org $8100 +v +.org $8200 +v +.org $8300 +v +.org $FFC0 +.qword reset + +.org $FF50 +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin +.org $FF50 +v +done + diff --git a/test/input-3.s b/test/input-3.s new file mode 100644 index 0000000..a05cb9d --- /dev/null +++ b/test/input-3.s @@ -0,0 +1,522 @@ +; Testing input. +; +; Writen in Sux assembly by +; mr b0nk 500 + +; Instruction mnemonics, +; and opcodes. +.org $1000 +tok: + .byte "dab" +msg: + .byte "oof, you divided a, and b on me.\n" + +; Input buffer. +.org $2000 +buffer: + +.org $4000 +cmd_buf: + +.org $200 +bitmask: + .byte $0 +bitabl: + .qword $0 + .word $0 +bits: + .byte $0 + +; Initalize some variables. +.org $0 +scr_row: + .byte $0 +scr_col: + .byte $0 +scr_lnst: + .word $0 +scr_lncnt: + .word $0 +scr_rowst: + .byte $0 +a: + .byte $0 +b: + .byte $0 +c: + .byte $0 +d: + .byte $0 +e: + .byte $0 +string: + .byte "Please, type something.\n" +string2: + .byte "You typed, " +end: + .byte $0 + +; Pointers +ptr: + .qword buffer +cptr: + .qword cmd_buf +tptr: + .qword tok +mptr: + .qword msg +bmptr: + .qword bitmask +btptr: + .qword bitabl + +; Main program +.org $8000 +reset: + cps + ldx.w #$FFFF + txs + ldy #0 + lda #0 + jsl clr_buf + jmp start +clr_buf: + lda #0 + cpy.w #$1FFF + beq clr_buf_end + sta (ptr), y + iny + jmp clr_buf +clr_buf_end: + ldy.w #0 + rtl + +start: + lda #0 + tax + sta $C000 + phy #2 + ldy.w #0 + jsl clr_cbuf + ply #2 + lda #1 + sta $C000 + jmp print + +clr_cbuf: + cpy.w #$3FF + beq clr_cbuf_end + sta (cptr), y + iny + jmp clr_cbuf +clr_cbuf_end: + rtl + +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. +sleep: + lda end + bne spin ; Are we done with getting input? + +print: + phy #2 + txy + lda string, y ; Get character at offset x. + beq pull_y ; Did we find a null terminator? + ply #2 + inx + jsl print_char + jmp print + +getbit: + phy #2 + ldx scr_row +getbt1: + jsl bitpos + txy + ldb (btptr), y + ply #2 + aba + cmp #1 + jmp bitout + +bitpos: + stx bitmask + txa + and #7 + tax + lda bits, x + pha #1 + lda bitmask + lsr #3 + tax + pla #1 + rtl + +bitout: + ldx bitmask + rtl + +getchar: + lda $C002 ; Get typed character. + pha #1 + phy #2 + cmp #10 + beq cmd_cpy +getchar_pnt: + ply #2 + pla #1 + jsl print_char + lda a + cmp #10 + beq getchar_line + jmp getchar_char +cmd_cpy: + lda scr_row + mul #80 + tay + ldx.w #$0 +cmd_cpy_strt: + lda (ptr), y + beq getchar_pnt + phy #2 + txy + sta (cptr), y + inx + ply #2 + iny + jmp cmd_cpy_strt +getchar_line: + lda #$0 + sta scr_lncnt + jmp getchar_end +getchar_char: + lda #$1 +getchar_end: + rtl + +parse: + lda #0 + tax + jsl dabbed + beq start + lda #0 + tax + jmp result + +print_char: + sta a + cmp #$1B + beq esc + cmp #$A + beq nl ; Did the user type a newline? + cmp #$C + beq clr_scr + cmp #8 + beq bs ; Did the user type a backspace? + cmp #$7F + beq bs ; Did the user type a backspace? + sta a + ldb scr_col + cpb #79 + beq linewrap + jmp printc +linewrap: + ldb #0 + stb scr_col + lda #$42 + sta c + jsl isdown + ldb scr_row + cpb #23 + beq printc_end +printc: + lda a + inc scr_col ; Increment the cursor's x coordinate. + inc scr_lncnt + sta (ptr), y ; Store typed character into the input buffer. + iny + sta $C001 ; Echo typed character. +printc_end: + rtl + +nl: + lda #0 + sta (ptr), y ; Store said terminator into the input buffer. + sta scr_col + lda scr_row + cmp #23 + bne nl_inc + lda #1 + sta a + jmp printc_end +nl_inc: + lda #$42 + sta c + jsl isdown + sty.w scr_lnst + lda #10 + sta a + jmp printc_end + +clr_scr: + lda #0 + sta.w scr_lnst + sta scr_rowst + tay + jsl clr_buf + sta scr_col + sta scr_row + jsl update_pos + lda #$C + sta $C001 + jmp printc_end + +back: + lda #$7F + sta $C001 + dey ; Decrement buffer offset. + lda #0 ; Put a null terminator, in place of the backspace. + sta (ptr), y ; Place it into the input buffer. + lda #$44 + dec scr_col + dec scr_lncnt + jsl update_pos + jmp printc_end ; Get next character. + +bs: + lda scr_col ; Are we at the start of the buffer? + beq printc_end + jmp back ; We are not, so add the backspace to the buffer. + +esc: + lda $C000 ; Skip the '['. + lda $C000 ; Get the next character. + 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 + sta d + jsl isup ; Check if the user pressed up. + lda e + bne esc_lnst + lda d + bne esc_end + jsl isdown ; Check if the user pressed down. + lda e + bne esc_lnst + lda d + bne esc_end + lda #0 + jsl isleft ; Check if the user pressed left. + lda d + bne esc_end + jsl isright ; Check if the user pressed right. + jmp esc_end +esc_lnst: + lda scr_row + sta scr_rowst + mul #80 + sta.w scr_lnst +esc_end: + lda #0 + sta d + jmp printc_end ; Go back to getting user input. + +isup: + lda scr_row ; Is the cursor at the top of the screen? + beq isup_done ; Yes, so return. + lda c ; No, so load the escape code back into the accumulator. + cmp #$41 ; Did the user press the up arrow key? + beq up ; Yes, so move the cursor up. +isup_done: + rtl ; End of isup. + +isdown: + lda scr_row ; Start checking the y coordinate of the cursor. + cmp #23 ; Is the cursor at the bottom of the screen? + beq isdown_done ; Yes, so return. + 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. + jmp isdown_done +isdown_scrl: + 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. +isdown_done: + rtl ; End of isdown. + +isright: + lda scr_col ; Start checking the x coordinate of the cursor. + cmp #79 ; Is the cursor at the far right of the screen? + beq isright_end ; Yes, so return. + lda c ; No, so load the escape code back into the accumulator. + cmp #$43 ; Did the user press the right arrow key? + beq right ; Yes, so move the cursor right. +isright_end: + rtl ; End of isright. + +isleft: + lda scr_col ; Is the cursor at the far left of the screen? + beq isleft_done ; Yes, so return. + 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. +isleft_done: + rtl ; End of isleft. + +up: + dec scr_row + jsl update_pos + lda #1 + sta d + jmp isup_done +down: + inc scr_row + jsl update_pos + lda #1 + sta d + jmp isdown_done +right: + inc scr_col + jsl update_pos + jmp isright_end +left: + dec scr_col + jsl update_pos + lda #1 + sta d + jmp isleft_done + +update_pos: + lda scr_row + mul #80 + adc scr_col + tay + lda #$1B ; Print an escape character + sta $C001 ; to the screen. + lda #$5B ; Print '[' + sta $C001 ; to the screen, and start the escape sequence. + jsl getrow ; Start printing the row number to the screen. + jsl getcol ; Start printing the column number to the screen. + lda #$48 ; Print 'H' + sta $C001 ; to the screen. + rtl ; End of update_pos. + +getrow: + lda scr_row ; Get the cursor's y coordinate. + div #10 ; Divide A by 10. + adc #$30 ; Convert it to ascii, and + sta $C001 ; print to the screen. + tba ; Get the remainder. + adc #$30 ; Convert it to ascii, and + sta $C001 ; print to the screen. + rtl ; End of getrow. + +getcol: + lda #$3B ; Print ';' + sta $C001 ; to the screen. + lda scr_col ; Get the cursor's x coordinate. + div #10 ; Divide A by 10. + adc #$30 ; Convert it to ascii, and + sta $C001 ; print to the screen. + tba ; Get the remainder. + adc #$30 ; Convert it to ascii, and + sta $C001 ; print to the screen. + rtl ; End of getrow. + +result: + phy #2 + txy + lda string2, y + beq rset_y ; Reset y, if we hit the null terminator. + ply #2 + jsl print_char ; Print 'You have typed, ' + inx + jmp result ; Keep printing. + +rset_y: + ply #2 + lda #0 ; Reset a. + tax ; Reset y. + jmp print_buf ; Print the input buffer. + +dabbed: + phy #2 + txy + lda (cptr), y ; Get a character from the input buffer. + beq dab_pend ; Are we done with printing the buffer? + cmp (tptr), y + bcs dab_pend + beq chk_str + bcc dab_pend +chk_str: + ply #2 + inx + cpx #3 + bne dabbed + ldx #0 +pnt_msg: + phy #2 + txy + lda (mptr), y ; Get a character from the input buffer. + beq dab_peqnd ; Are we done with printing the buffer? + ply #2 + jsl print_char + inx + jmp pnt_msg ; Keep printing the buffer. +dab_pend: + ply #2 + lda #1 + jmp dab_end +dab_peqnd: + ply #2 + lda #0 + jmp dab_end +dab_end: + rtl + +print_buf: + phy #2 + txy + lda (cptr), y ; Get a character from the input buffer. + beq cmd_clr ; Are we done with printing the buffer? + ply #2 + jsl print_char + inx + jmp print_buf ; Keep printing the buffer. + +cmd_clr: + ply #2 + lda #10 + jsl print_char + jmp start + +.org $FFC0 +.qword reset + +.org $FF50 +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin +.org $FF50 +done + -- cgit v1.2.3-13-gbd6f