; SuBAsm ; The Sux Bootstrapped Assembler. ; ; by mr b0nk 500 ; 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