summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-01-23 13:55:00 -0500
committermrb0nk500 <b0nk@b0nk.xyz>2020-01-23 13:55:00 -0500
commit63d5046ecabd5fd1524d3c4bc4590176c3b8a4eb (patch)
tree9cfc71691294d818e87bb2e0026f37b8ee8eb892
parent861d56e556b597115ad01b4b4cc0e5b932545ce9 (diff)
Start optimizing the emulator.
I also added a new input testing program called input-3.s, which contains a mostly working editor.
-rw-r--r--programs/pos-check.s12
-rw-r--r--programs/scr-to-buf.s7
-rw-r--r--sux.c194
-rw-r--r--test/input-2.s412
-rw-r--r--test/input-3.s522
5 files changed, 1063 insertions, 84 deletions
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 <b0nk@b0nk.xyz>
+
+; 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 <b0nk@b0nk.xyz>
+
+; 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
+