diff options
| author | mrb0nk500 <b0nk@b0nk.xyz> | 2020-01-23 13:55:00 -0500 | 
|---|---|---|
| committer | mrb0nk500 <b0nk@b0nk.xyz> | 2020-01-23 13:55:00 -0500 | 
| commit | 63d5046ecabd5fd1524d3c4bc4590176c3b8a4eb (patch) | |
| tree | 9cfc71691294d818e87bb2e0026f37b8ee8eb892 | |
| parent | 861d56e556b597115ad01b4b4cc0e5b932545ce9 (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.s | 12 | ||||
| -rw-r--r-- | programs/scr-to-buf.s | 7 | ||||
| -rw-r--r-- | sux.c | 194 | ||||
| -rw-r--r-- | test/input-2.s | 412 | ||||
| -rw-r--r-- | test/input-3.s | 522 | 
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 @@ -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 + | 
