diff options
Diffstat (limited to 'programs/subasm.s')
-rw-r--r-- | programs/subasm.s | 232 |
1 files changed, 187 insertions, 45 deletions
diff --git a/programs/subasm.s b/programs/subasm.s index 46effce..ddb7ba2 100644 --- a/programs/subasm.s +++ b/programs/subasm.s @@ -11,9 +11,18 @@ ver_txt: .byte ", version " ver_num: .byte "0.1" -x: + +scr_row: + .byte $0 +scr_col: + .byte $0 +a: + .word $0 +b: + .word $0 +c: .word $0 -y: +d: .word $0 str_buf: @@ -109,64 +118,137 @@ store_char: 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. + beq read ; We have an error, so discard it, and go back to getting user input. lda kbd ; Get the escape code. - cmp #$41 ; Did the user press the up arrow? + sta c ; Store the escape code, until we need it. + jsr isup ; Check if the user pressed up. + lda d + cmp #$0 + bne esc_end + jsr isdown ; Check if the user pressed down. + lda d + cmp #$0 + bne esc_end + lda #$0 + jsr isleft ; Check if the user pressed left. + lda d + cmp #$0 + bne esc_end + jsr 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. - cmp #$42 ; Did the user press the down arrow? +isup_done: + rts ; End of isup. + +isdown: + lda scr_row ; Start checking the y coordinate of the cursor. + cmp #$17 ; 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. - 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? +isdown_done: + rts ; End of isdown. + +isright: + lda scr_col ; Start checking the x coordinate of the cursor. + cmp #$4F ; 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: + rts ; 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: + rts ; End of isleft. up: - lda #$1B - sta scr - lda #$5B - sta scr - lda #$41 - sta scr - jmp read + dec scr_row + jsr update_pos + lda #$1 + sta d + jmp isup_done 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 + inc scr_row + jsr update_pos + lda #$1 + sta d + jmp isdown_done right: - lda #$1B - sta scr - lda #$5B - sta scr - lda #$44 - sta scr - jmp read + inc scr_col + jsr update_pos + jmp isright_end +left: + dec scr_col + jsr update_pos + lda #$1 + sta d + jmp isleft_done + +update_pos: + lda #$1B ; Print an escape character + sta scr ; to the screen. + lda #$5B ; Print '[' + sta scr ; to the screen, and start the escape sequence. + jsr getrow ; Start printing the row number to the screen. + jsr getcol ; Start printing the column number to the screen. + lda #$48 ; Print 'H' + sta scr ; to the screen. + rts ; End of update_pos. +getrow: + lda scr_row ; Get the cursor's y coordinate. + div #$A ; Divide A by 10. + adc #$30 ; Convert it to ascii, and + sta scr ; print to the screen. + tba ; Get the remainder. + adc #$30 ; Convert it to ascii, and + sta scr ; print to the screen. + rts ; End of getrow. +getcol: + lda #$3B ; Print ';' + sta scr ; to the screen. + lda scr_col ; Get the cursor's x coordinate. + div #$A ; Divide A by 10. + adc #$30 ; Convert it to ascii, and + sta scr ; print to the screen. + tba ; Get the remainder. + adc #$30 ; Convert it to ascii, and + sta scr ; print to the screen. + rts ; End of getrow. nl: sta scr ; Print newline. + inc scr_row ; Move the cursor down one line. lda #$0 ; Put a null terminator, in place of the newline. - sta buf, y ; Place it into the input buffer. + sta scr_col ; Move the cursor back to column 0. + sta str_buf, y ; Place it into the input buffer. ldy.w #$0 ; Reset y, to parse the input. - jmp parse + jsr parse ; Start parsing input. back: - jsr echo ; Print backspace. + sta scr ; Print backspace. lda #$0 ; Put a null terminator, in place of the backspace. - sta buf, y ; Place it into the input buffer. + sta str_buf, y ; Place it into the input buffer. dey ; Decrement buffer offset. + dec scr_col jmp read ; Get next character. bs: @@ -175,11 +257,55 @@ bs: 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, ' + jmp parse ; Keep printing. + jsr clr_sbuf + rts + +forg: iny ; Increment offset. - jmp result ; Keep printing. + lda str_buf, y + jsr iswhite + bcs forg ; Reset y, if we hit the null terminator. + cmp #$2E ; Is this character a '.'? + bne forg_exit ; No, so return. + sty org ; Yes, so store the origin. +forg_end: + iny ; Increment offset. + lda str_buf, y + jsr istoken + bcs forg_end + dey + sty scr_col +forg_exit: + rts ; End of forg. + +istoken: + cmp #$20 ; Is this character a space? + beq istoken_f ; Yes, so return false. + cmp #$09 ; Is this character a tab? + beq istoken_f ; Yes, so return false. + cmp #$A ; Is this character a newline? + beq istoken_f ; Yes, so return false. + cmp #$3B ; Is this character a ';'? + beq istoken_f ; Yes, so return false. + cmp #$0 ; Is this character a null terminator? + beq istoken_f ; Yes, so return false. + sec ; Return true. + rts ; End of istoken. +istoken_f + clc ; Return false. + rts ; End of istoken_f. + +iswhite: + cmp #$20 ; Is this character a space? + beq iswhite_t ; Yes, so return true. + cmp #$09 ; Is this character a tab? + beq iswhite_t ; Yes, so return true. + clc ; No, so return false. + rts ; End of iswhite. +iswhite_t: + sec ; Return true. + rts ; End of iswhite_t. rset_y: ldy.w #$0 @@ -217,7 +343,23 @@ clr_end: rts echo: + sta a + ldx scr_col + cpx #$4F + bne echo_print + cmp #$A + beq linewrap +linewrap: + inc scr_row + ldx #$0 + stx scr_col + jsr update_pos +echo_print: + lda a sta scr ; Echo typed character. + inc scr_col ; Increment the cursor's x coordinate. + sta str_buf, y ; Store typed character into the input buffer. + iny ; Increment the buffer offset. rts ; Return. .org $FFC0 |