diff options
| -rw-r--r-- | programs/subasm.s | 239 | ||||
| -rw-r--r-- | sux.c | 84 | ||||
| -rw-r--r-- | test/input.s | 92 | 
3 files changed, 367 insertions, 48 deletions
diff --git a/programs/subasm.s b/programs/subasm.s new file mode 100644 index 0000000..fe02794 --- /dev/null +++ b/programs/subasm.s @@ -0,0 +1,239 @@ +; SuBAsm +; The Sux Bootstrapped Assembler. +; +; by mr b0nk 500 <b0nk@b0nk.xyz> + +; Variables +.org $1000 +prg_name: +	.byte "SuBAsm" +ver_txt: +	.byte ", version " +ver_num: +	.byte "0.1" +x: +	.word $0 +y: +	.word $0 + +str_buf: + +; Input buffer. +.org $2000 +buf: + +; Control Register. +.org $C000 +ctrl_reg: + +; Screen. +.org $C001 +scr: + +; Keyboard. +.org $C002 +kbd: + +; Main program. +.org $0 +reset: +	cps +	ldx.w #$FFFF +	txs +	ldy #$0 +	jsr clr_buf +	ldx.w #$0	; Reset x. +	ldy #$0		; Reset y. +	jmp print_title + +read: +	lda ctrl_reg	; Is the keyboard ready? +	beq read	; Loop until the keyboard is ready. +	lda #$0		; Start resetting the control register. +	sta ctrl_reg	; Reset the control register. +	jmp getchar	; We got a key. + +rset_x: + +	ldx #$0		; Reset x. +	stx.w x +	rts + +print_title: +	lda prg_name, x +	beq print_ver	; Did we find a null terminator? +	sta		; Print character. +	inx		; Increment offset. +	inc x +	jmp print_title	; Keep printing more characters. + +print_ver +	jsr rset_x +	lda ver_txt, x +	beq print_num	; Did we find a null terminator? +	sta scr		; Print character. +	inx		; Increment offset. +	jmp print_ver	; Keep printing more characters. + +print_num: +	lda ver_num, x +	beq getline	; Did we find a null terminator? +	sta scr		; Print character. +	inx		; Increment offset. +	jmp print_num	; Keep printing more characters. +getline: +	lda #$A +	sta scr		; Print newline +	inc y +	jsr rset_x +	jmp read + +getchar: +	lda kbd		; Get typed character. +	cmp #$1B	; Did the user type an escape? +	beq esc		; Yes, so start getting the escape code. +	cmp #$A		; Did the user type a newline? +	beq nl		; Yes, so start parsing the input. +	cmp #$8		; Did the user type a backspace? +	beq bs		; Yes, so start checking the buffer. +	jsr echo	; Print character to screen. + +store_char: +	sta buf, y	; Store typed character into the input buffer. +	iny		; Increment buffer offset. +	jmp read	; Get another character. + +esc: +	lda ctrl_reg	; Skip the '['. +	lda ctrl_reg	; Get the next character. +	beq read	; We have an error, so discard it, and read the next character. +	lda kbd		; Get the escape code. +	cmp #$41	; Did the user press the up arrow? +	beq up		; Yes, so move the cursor up. +	cmp #$42	; Did the user press the down arrow? +	beq down	; Yes, so move the cursor down. +	cmp #$43	; Did the user press the left arrow? +	beq left	; Yes, so move the cursor left. +	cmp #$44	; Did the user press the right arrow? +	beq right	; Yes, so move the cursor right. + +up: +	lda #$1B +	sta scr +	lda #$5B +	sta scr +	lda #$41 +	sta scr +	jmp read +down: +	lda #$1B +	sta scr +	lda #$5B +	sta scr +	lda #$42 +	sta scr +	jmp read +left: +	lda #$1B +	sta scr +	lda #$5B +	sta scr +	lda #$43 +	sta scr +	jmp read +right: +	lda #$1B +	sta scr +	lda #$5B +	sta scr +	lda #$44 +	sta scr +	jmp read + + + +nl: +	sta scr		; Print newline. +	lda #$0		; Put a null terminator, in place of the newline. +	sta buf, y	; Place it into the input buffer. +	ldy.w #$0	; Reset y, to parse the input. +	jmp parse + +back: +	jsr echo	; Print backspace. +	lda #$0		; Put a null terminator, in place of the backspace. +	sta buf, y	; Place it into the input buffer. +	dey		; Decrement buffer offset. +	jmp read	; Get next character. + +bs: +	cpy #$0		; Are we at the start of the buffer? +	beq read	; We are, so do not store the backspace into the buffer. +	jmp back	; We are not, so add the backspace to the buffer. + +parse: +	lda buf, y +	beq clr_buf	; Reset y, if we hit the null terminator. +	sta scr		; Print 'You have typed, ' +	iny		; Increment offset. +	jmp result	; Keep printing. + +rset_y: +	ldy.w #$0 +	jmp print_buf	; Print the input buffer. + +print_buf: +	lda buf, y	; Get a character from the input buffer. +	beq fin		; Are we done with printing the buffer? +	sta scr		; Print said character. +	iny +	jmp print_buf	; Keep printing the buffer. + +spin: +	nop +	nop +	nop +	jmp spin + +clr_buf: +	lda #$0 +	cpy.w #$1000 +	beq clr_end +	sta buf, y +	iny +	jmp clr_buf +clr_sbuf: +	lda #$0 +	cpy.w #$40 +	beq clr_end +	sta str_buf, y +	iny +	jmp clr_sbuf + +clr_end: +	rts + +echo: +	sta scr		; Echo typed character. +	rts		; Return. + +.org $FFC0 +.qword reset + +.org $FF50 +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin + +.org $FFA0 +.qword irq_routine +;.org $0 +;viewmem +;.org $100 +;viewmem +;q +done @@ -44,7 +44,7 @@ void *run(void *args) {  	struct suxthr *thr = (void *)args;  	struct sux *cpu = &thr->sx;  	uint8_t thread = thr->th; -	uint64_t address; +	uint64_t address = 0;  	uint8_t prefix = 0;  	uint8_t opcode = 0;  	uint8_t end = 0; @@ -57,10 +57,12 @@ void *run(void *args) {  	uint8_t lines = (6*thread)+2;  	uint16_t tv = 0xFF50; /* Starting address of the Thread Vectors. */  	int x = 0, y = 0; +	uint8_t esc = 0;  #if bench  	gettimeofday(&str[thread], 0);  #endif  	while (!end) { +		address = 0;  		if (wai) {  			for (int8_t i = 56; i >= 0; i-=8) {  				if (i) @@ -91,7 +93,7 @@ void *run(void *args) {  			prefix = 0;  		opcode = addr[cpu->pc[thread]]; -	#if debug && !bench && keypoll +	#if debug && !bench  		#if keypoll  		pthread_mutex_lock(&mutex);  		#endif @@ -762,22 +764,53 @@ void *run(void *args) {  					#if keypoll  					pthread_mutex_lock(&mutex);  					#endif -					if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') { -						if (x > 0) { -							x--; -							wmove(scr, y, x); +					if (esc) { +						switch(addr[address]) { +							case 'A': +								if (y > 0) +									y--; +								wmove(scr, y, x); +								esc = 0; +								break; +							case 'B': +								if (y < getmaxy(scr)) +									y++; +								wmove(scr, y, x); +								esc = 0; +								break; +							case 'C': +								if (x < getmaxx(scr)) +									x++; +								wmove(scr, y, x); +								esc = 0; +								break; +							case 'D': +								if (x > 0) +									x--; +								wmove(scr, y, x); +								esc = 0; +								break;  						} -						wdelch(scr); -						wrefresh(scr);  					} else { -						wmove(scr, y, x); -						waddch(scr, addr[address]); -						wrefresh(scr); -						if (addr[address] == '\n') { -							x = 0; -							y+=1; +						if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') { +							if (x > 0) { +								x--; +								wmove(scr, y, x); +							} +							wdelch(scr); +							wrefresh(scr); +						} else if (addr[address] == '\033') { +							esc = 1;  						} else { -							x+=1; +							wmove(scr, y, x); +							waddch(scr, addr[address]); +							wrefresh(scr); +							if (addr[address] == '\n') { +								x = 0; +								y+=1; +							} else { +								x+=1; +							}  						}  					}  					#if keypoll @@ -1296,6 +1329,8 @@ void *run(void *args) {  					cpu->a[thread]+=1;  					cpu->z[thread] = (cpu->a[thread] == 0);  					cpu->n[thread] = (cpu->a[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));  				}  				if (opcode == INY || opcode == IAY) {  					cpu->y[thread]+=1; @@ -1307,8 +1342,6 @@ 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));  				break;  			case 0xD0: /* JMP Zero Matrix. */  				address =	(uint32_t)addr[cpu->pc[thread]] @@ -1329,6 +1362,8 @@ void *run(void *args) {  					cpu->a[thread]-=1;  					cpu->z[thread] = (cpu->a[thread] == 0);  					cpu->n[thread] = (cpu->a[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));  				}  				if (opcode == DEY || opcode == DAY) {  					cpu->y[thread]-=1; @@ -1340,8 +1375,6 @@ 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));  				break;  			case JSL: /* Jump to Subroutine Long. */  				address =	(uint64_t)addr[cpu->pc[thread]] @@ -1457,10 +1490,11 @@ void *run(void *args) {  				break;  		}  		ins++; -	#if debug && !bench && keypoll +	#if debug && !bench  		#if keypoll  		pthread_mutex_lock(&mutex);  		#endif +		mvwprintw(scr, getmaxy(scr)-lines, 0, "Operand: $%llx", address);  		mvwprintw(scr, (24*thread)+1, 0, "Instructions executed: %llu, Clock cycles: %llu\r", ins, iclk);  		wrefresh(scr);  		#if keypoll @@ -1507,7 +1541,7 @@ int main(int argc, char **argv) {  	crmode();  	noecho();  	nl(); -	curs_set(0); +	curs_set(1);  	werase(scr);  	scrollok(scr, 1);  	wrefresh(scr); @@ -1562,8 +1596,10 @@ int main(int argc, char **argv) {  		#if !bench  		if ((c != EOF && c !=-1)) {  			pthread_mutex_lock(&main_mutex); +			curs_set(0);  			pthread_cond_wait(&main_cond, &main_mutex);  			pthread_mutex_unlock(&main_mutex); +			curs_set(1);  			c = 0;  			addr[CTRL_ADDR] = 0;  		} @@ -1571,12 +1607,6 @@ int main(int argc, char **argv) {  		pthread_mutex_lock(&mutex);  		#endif  		getyx(scr, y, x); -		attroff(A_REVERSE); -		attron(A_BLINK); -		wprintw(scr, "_"); -		attroff(A_BLINK); -		wmove(scr, y, x); -		wrefresh(scr);  		c = wgetch(scr);  		switch (c) {  			case ERR: diff --git a/test/input.s b/test/input.s index b699dda..a2725f6 100644 --- a/test/input.s +++ b/test/input.s @@ -12,7 +12,10 @@ string2:  	.byte "You typed, "  end:  	.byte $0 - +x: +	.word $0 +tmp: +	.word $0  ; Input buffer.  .org $2000  buffer: @@ -26,7 +29,7 @@ reset:  	ldy #$0  clr_buf:  	lda #$0 -	cpy.w #$400 +	cpy.w #$1000  	beq start  	sta buffer, y  	iny @@ -47,7 +50,6 @@ sleep:  	lda end  	bne spin	; Are we done with getting input?  read: -	nop		; Sleep until we get a character.  	lda $C000	; Get control register.  	beq rset_a	; Loop until we get a character.  	lda #$0 @@ -63,17 +65,66 @@ print:  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 $C001	; Echo typed character.  	sta buffer, y	; Store typed character into the input buffer.  	iny		; Increment buffer offset. -	nop  	jmp rset_a	; We are not, so add the backspace to the buffer. +esc: +	lda $C000	; Skip the '['. +	lda $C000	; Get the next character. +	beq read	; We have an error, so discard it, and read the next character. +	lda $C002	; Get the escape code. +	cmp #$41	; Did the user press the up arrow? +	beq up		; Yes, so move the cursor up. +	cmp #$42	; Did the user press the down arrow? +	beq down	; Yes, so move the cursor down. +	cmp #$43	; Did the user press the right arrow? +	beq right	; Yes, so move the cursor right. +	cmp #$44	; Did the user press the left arrow? +	beq left	; Yes, so move the cursor left. +up: +	lda #$1B +	sta $C001 +	lda #$5B +	sta $C001 +	lda #$41 +	sta $C001 +	jmp rset_a +down: +	lda #$1B +	sta $C001 +	lda #$5B +	sta $C001 +	lda #$42 +	sta $C001 +	jmp rset_a +right: +	lda #$1B +	sta $C001 +	lda #$5B +	sta $C001 +	lda #$43 +	sta $C001 +	jmp rset_a +left: +	lda #$1B +	sta $C001 +	lda #$5B +	sta $C001 +	lda #$44 +	sta $C001 +	jmp rset_a +  nl:  	sta $C001  	lda #$0		; Replace newline with a null terminator. @@ -81,10 +132,17 @@ nl:  	ldy.w #$0	; Reset y, to print the result.  	jmp result +back: +	sta $C001	; Print backspace. +	lda #$0		; Put a null terminator, in place of the backspace. +	sta buffer, y	; Place it into the input buffer. +	dey		; Decrement buffer offset. +	jmp read	; Get next character. +  bs: -	cpy #$0 -	beq return	; Are we at the start of the buffer? -	jmp echo	; We are not, so add the backspace to the buffer. +	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:  	lda string2, y @@ -93,25 +151,18 @@ result:  	iny		; Increment offset.  	jmp result	; Keep printing. +  rset_y:  	ldy.w #$0  	jmp print_buf	; Print the input buffer.  print_buf:  	lda buffer, y	; Get a character from the input buffer. -	beq fin		; Are we done with printing the buffer? +	beq spin	; Are we done with printing the buffer?  	sta $C001	; Print said character.  	iny  	jmp print_buf	; Keep printing the buffer. -fin: -	lda #$A		; Load a newline. -	sta $C001	; Print the newline. -	lda #$1		; Tell the program that we are done. -	sta end		; We are done. -	jmp sleep - -  spin:  	nop  	nop @@ -132,10 +183,9 @@ spin:  .org $FFA0  .qword irq_routine -;.org $0 -;viewmem -;.org $100 -;viewmem +.org $8000 +viewmem +.org $8100 +viewmem  ;q  done -  | 
