; SuBEditor. ; ; Writen in Sux assembly by ; mr b0nk 500 .org $A000 ; String Literals/Constants. tok: .byte "dab" msg: .byte "oof, you divided a, and b on me.\n" string: .byte "Please, type something.\n" string2: .byte "You typed, " ; Linewrap bitmask table. bits: .byte $80 .byte $40 .byte $20 .byte $10 .byte $08 .byte $04 .byte $02 .byte $01 ; Input buffer. .org $2000 buffer: .org $4000 cmd_buf: ; Initalize some variables. .org $0 scr_row: .byte $0 scr_col: .byte $0 scr_trow: .byte $0 scr_tcol: .byte $0 scr_ptr: .word $0 scr_ptr2: .word $0 ; Registers. a: .byte $0 b: .byte $0 c: .byte $0 d: .byte $0 e: .byte $0 f: .byte $0 ; This register is always zero. zero: .qword $0 ; End of registers. end: .byte $0 bitmask: .byte $0 bitabl: .qword $0 .qword $0 scr_str: .byte $0 scr_end: .byte $0 wrapped: .byte $0 ; Pointers ptr: .qword $0 ptr2: .qword $0 ptr3: .qword $0 ptr4: .qword $0 ptr5: .qword $0 ptr6: .qword $0 scr_ptr3: .word $0 ; Main program .org $8000 reset: cps ; Reset the processor status register. ldx.w #$FFFF ; Reset the stack pointer. txs ; ldy #0 ; Reset the Y register. tyx ; Reset the X register. lda #23 ; Set the end of the screen back to 23. sta scr_end ; lda.w #buffer ; Place the address for the screen buffer sta.q ptr5 ; into one of the pointers. lda.w #cmd_buf ; Place the address for the command buffer sta.q ptr6 ; into one of the pointers. tya ; Reset the Accumulator. sta scr_str ; Set the start of the screen back to zero. sta.q bitabl ; Reset the first half of the linewrap table. sta.q bitabl+8 ; Reset the second half of the linewrap table. jsl clr_buf ; Clear the screen buffer. jmp start ; Goto the start of the main program. clr_buf: phb #1 ; Preserve whatever was in B. ldb #0 ; Clear B. lda.w #buffer+8 ; sta.q ptr4 ; tba ; clr_buf_st: cpy.w #$1FFF ; Did we clear all of the screen buffer? bcs clr_buf_end ; Yes, so we're done. sta.q (ptr5), y ; No, so clear eight bytes. sta.q (ptr4), y ; Clear eight more bytes. tya ; Copy the buffer index. adc #$10 ; Increment the index by 16. tay ; Update the index. tba ; Reset the Accumulator. sta.q (ptr5), y ; Do this one more time, to clear 32 bytes. sta.q (ptr4), y ; tya ; adc #$10 ; tay ; tba ; jmp clr_buf_st ; Keep looping. clr_buf_end: ldy.w zero ; Set the index back to zero. plb #1 ; Get whatever was in the B register, back. rtl ; End of clr_buf. start: lda #0 ; TODO: Update this for the Super VIA. sta end ; sta $C000 ; Clear the controll register of the I/O adapter. tax ; Reset X. phy #2 ; Save the cursor index for later. tay ; Reset the cursor index. jsl clr_cbuf ; Clear the command buffer. ply #2 ; Get back the cursor index. lda.w #string ; Print the startup message. jsl print_str ; lda.w zero ; Reset the Accumulator. jmp read ; Start reading the keyboard. clr_cbuf: phb #1 ; Start of callee preservation. ldb #0 ; Reset the B register. lda.w #cmd_buf+8; sta.q ptr4 ; tba ; clr_cbuf_st: cpy.w #$3FF ; Did we clear all of the command buffer? bcs clr_cbuf_nd ; Yes, so we're done. sta.q (ptr6), y ; No, so clear eight bytes. sta.q (ptr4), y ; Clear eight more bytes. tya ; Copy the buffer index. adc #$10 ; Increment the index by 16. tay ; Update the index. tba ; Reset the Accumulator. sta.q (ptr6), y ; Do this one more time, to clear 32 bytes. sta.q (ptr4), y ; tya ; adc #$10 ; tay ; tba ; jmp clr_cbuf_st ; Keep looping. clr_cbuf_nd: plb #1 ; End of callee preservation. rtl ; End of clr_cbuf. read: lda $C000 ; Did we get a key? beq read ; No, so try again. jsl getchar ; Yes, and was it a newline? beq parse ; Yes, so start parsing the line. jmp read ; No, so keep looping. print_str: sta.q ptr ; Place the string pointer into the main pointer. ldb #0 ; Clear the B register. tba ; Clear the Accumulator. inb ; Enable replace mode. stb b ; pntstr_st: phy #2 ; Save the cursor index. txy ; Copy the string index into Y. lda (ptr), y ; Are we at the end of the string? beq pntstr_end ; Yes, so we're done. ply #2 ; No, so get the cursor index back. inx ; Increment the string index. jsl print_char ; Print the character. jmp pntstr_st ; Keep looping. pntstr_end: ply #2 ; Get the cursor index back. ldb #0 ; Enable insert mode. stb b ; rtl ; End of print_str. getbit: clc ; Clear the carry flag. lda scr_str ; Has the screen been scrolled? bne getbt0 ; Yes, so add the screen offset to the current line number. ldx scr_row ; No, so just use the current line number. jmp getbt1 ; Start getting the bit. getbt0: lda scr_row ; Get the current line number. adc scr_str ; Add the screen offset to it. tax ; Use it as the wrap index. getbt1: jsl bitpos ; Get the bit, and byte position. ldb bitabl, x ; Get one byte of the wrap table. aba ; Mask out the bit of the current line number. cmp #1 ; Set the carry flag, if true. jmp bitout ; We are done. clrbit: jsl bitpos ; Get the bit, and byte position. xor #$FF ; Invert the bitmask. ldb bitabl, x ; Get one byte of the wrap table. aba ; Clear the bit of the current line number. bitsav: sta bitabl, x ; Update the wrap table. bitout: ldx bitmask ; Return the bitmask. rtl ; We are done. setbit: jsl bitpos ; Get the bit, and byte position. ldb bitabl, x ; Get one byte of the wrap table. oab ; Set the bit of the current line number. jmp bitsav ; Save the bit. bitpos: pha #1 ; Save the parameter. lda.w #bits ; Place the address of the bitmask table, sta.q ptr3 ; in the third pointer. lda.w zero ; Clear the Accumulator. pla #1 ; Get the parameter back. stx bitmask ; Make the line number the bitmask. txa ; Copy it to the Accumulator. and #7 ; Get the bit position. phy #2 ; Save the cursor index. tay ; Use the bit position as the index. tax ; Copy it into X. lda (ptr3), y ; Get the bitmask. ply #2 ; Get back the cursor index. pha #1 ; Save the bitmask. lda bitmask ; Get the line number. lsr #3 ; Get the byte position. tax ; Copy it into X. pla #1 ; Get back the bitmask. rtl ; End of bitpos. getchar: lda $C002 ; Get typed character. ldb #0 ; stb e ; stb b ; pha #1 ; phy #2 ; cmp #10 ; beq cmd_cpy ; getchar_pnt: ply #2 ; pla #1 ; ldb e ; bne reset_row ; getchar_pt1: jsl print_char ; lda a ; cmp #10 ; beq getchar_ln ; jmp getchar_chr ; reset_row: ldb e ; cpb #23 ; beq reset_row2 ; bcs reset_row1 ; jmp reset_row2 ; reset_row1: ldb #23 ; reset_row2: stb scr_row ; jmp getchar_pt1 ; cmd_cpy: lda scr_row ; sta scr_trow ; jsl findend ; sta scr_row ; sta e ; jsl findst ; clc ; lda scr_row ; adc scr_str ; mul #80 ; tay ; ldx.w #$0 ; cmd_cpy_st: lda (ptr5), y ; beq getchar_pnt ; phy #2 ; txy ; sta (ptr6), y ; inx ; ply #2 ; iny ; jmp cmd_cpy_st ; getchar_ln: lda #0 ; jmp getchar_end ; getchar_chr: lda #1 ; getchar_end: rtl ; findst: lda #0 ; findst_lp: pha #1 ; jsl getbit ; pla #1 ; bcc findst_done ; inc ; dec scr_row ; bpo findst_lp ; dec ; inc scr_row ; findst_done: cmp #0 ; rtl ; fndend: phy #2 ; fndend_lp: lda (ptr5), y ; Are we at the end of the string? beq fndend_done ; Yes, so we're done. iny ; No, so increment the cursor index. jmp fndend_lp ; Keep looping. fndend_done: sty.w scr_ptr3 ; ply #2 ; rtl ; End of fndend. findend: jsl fndend ; lda.w scr_ptr3 ; div #80 ; 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 #19 ; beq en_step ; cmp #18 ; beq dis_step ; cmp #8 ; beq bs ; Did the user type a backspace? cmp #$7F ; beq bs ; Did the user type a backspace? sta a ; printc: lda #0 ; sta d ; lda (ptr5), y ; Are we at the end of the string? beq printc_save ; Yes, so just print the character. lda b ; No, but was the flag set? bne printc_save ; Yes, so don't shift the line. sty.w scr_ptr ; No, so save the cursor index for later. jsl fndend ; jmp prntc_movln ; prntc_updt: lda scr_col ; sta scr_tcol ; prntc_updt2: jsl findend ; sta e ; sta scr_row ; jsl findst ; lda scr_row ; prntc_updt3: sta f ; jsl rdrw_ln ; lda scr_trow ; sta scr_row ; lda scr_tcol ; sta scr_col ; jsl update_pos ; dec d ; jmp printc_sav1 ; prntc_movln: ldy.w scr_ptr3 ; inc scr_ptr3 ; tyx ; dey ; ldb #1 ; stb d ; jsl shftln ; ldb #1 ; stb d ; lda a ; sta (ptr5), y ; store typed character into the input buffer. lda scr_row ; sta scr_trow ; jmp prntc_updt ; printc_save: ldb d ; bne prntc_updt ; printc_sav1: lda a ; sta (ptr5), y ; store typed character into the input buffer. printc_inc: inc scr_col ; Increment the cursor's x coordinate. iny ; printc_2: ldb #1 ; stb f ; ldb scr_col ; cpb #80 ; bcs printc_4 ; printc_3: sta $C001 ; Echo typed character. ldb f ; beq printc_wrap ; jmp printc_end ; printc_4: ldb scr_row ; cpb #23 ; bcs printc_scrl ; printc_5: ldb #0 ; stb f ; jmp printc_3 ; printc_scrl: sta $C001 ; Echo typed character. clc ; lda #1 ; sta wrapped ; jsl scrl_down ; printc_wrap: ldb #0 ; stb scr_col ; ldb scr_row ; cpb #23 ; bcs printc_wrp2 ; printc_wrap1: inc scr_row ; printc_wrp2: phx #2 ; clc ; lda scr_row ; adc scr_str ; tax ; jsl setbit ; plx #2 ; jsl update_pos ; printc_end: rtl ; nl: lda #0 ; ldb (ptr5), y ; bne nl1 ; sta (ptr5), y ; Store said terminator into the input buffer. nl1: sta scr_col ; lda scr_row ; cmp #23 ; bcc nl_inc ; jsl scrl_down ; lda #10 ; sta a ; jmp printc_end ; nl_inc: inc scr_row ; jsl update_pos ; lda #10 ; sta a ; jmp printc_end ; clr_scr: lda #23 ; sta scr_end ; lda #0 ; sta scr_str ; sta.q bitabl ; sta.q bitabl+8 ; tay ; jsl clr_buf ; tay ; jsl clr_cbuf ; sta scr_col ; sta scr_row ; jsl update_pos ; lda #$C ; sta $C001 ; jmp printc_end ; en_step: lda $C010 ; beq step_en ; jmp printc_end ; step_en: lda #1 ; sta $C010 ; jmp printc_end ; dis_step: lda $C010 ; bne step_dis ; jmp printc_end ; step_dis: lda #0 ; sta $C010 ; jmp printc_end ; back: ldb #0 ; stb e ; stb f ; lda scr_row ; sta scr_trow ; jsl findend ; sta scr_row ; back0: jsl findst ; beq back1 ; bcs back_updt ; lda scr_trow ; sta scr_row ; back1: dey ; Decrement the buffer's offset. lda #0 ; Place a null terminator sta (ptr5), y ; into the buffer. tyx ; Copy the current cursor index to X. iny ; Increment cursor index. ldb #0 ; stb d ; jsl shftln ; Shift line back by one character. lda #$7F ; Print a backspace to the screen. sta $C001 ; lda e ; beq back3 ; back2: jsl findend ; sta e ; lda scr_col ; sta scr_tcol ; jsl rdrw_ln ; lda scr_tcol ; sta scr_col ; back3: lda scr_trow ; sta scr_row ; dec scr_col ; Move the cursor back by one column, jsl update_pos ; and update it's position. jmp printc_end ; We are done. back_updt: lda scr_row ; sta f ; inc e ; jmp back1 ; bs: lda scr_col ; Are we at the far left of the screen? beq back_wrap ; Yes, so check for a wrapped line. jmp back ; No, so add the backspace to the buffer. back_wrap: jsl getbit ; Is this line, a wrapped line? bcs back_wrap1 ; Yes, so check if the cursor is at the top. jmp printc_end ; No, so we're done. back_wrap1: lda scr_row ; Are we at the top of the screen? beq back_wrap2 ; Yes, so check if the screen is at the top of the buffer. jmp backwrp ; No, so start clearing the wrap bit. back_wrap2: lda scr_str ; Are we at the top of the buffer? bne back_scrl ; Yes, so scroll up. jmp printc_end ; No, so we're done. back_scrl: clc ; Clear the carry flag, so that we don't get odd behaviour. jsl scrl_up ; Scroll up. inc scr_row ; Move down by one row. backwrp: clc ; Clear the carry flag. lda scr_row ; Add the cursor's row position, adc scr_str ; and the screen's starting row. tax ; Transfer that into X. backwrp2: dec scr_row ; Move up by one row. ; jsl clrbit ; Clear the wrap bit for this row. ldb #80 ; Move the cursor to the absolute right of the screen. stb scr_col ; jsl update_pos ; Update the cursor's position. jmp back ; Delete the previous character. shftln: ldb d ; Is the flag not set? beq shftln_lp1 ; Yes, so shift, and decrement. ldb #0 ; Clear the B register. jmp shftln_lp0 ; No, so shift, and increment. shftln_neg: ldy.w zero ; Set the source poition to 0. stb (ptr5), y ; Clear the character that is in the source. jmp shftln_end ; We are done. shftln_lp0: sty.w scr_ptr2 ; Save the source position for later. ldy.w scr_ptr ; Get the previous cursor index. cpy.w scr_ptr2 ; Is the source position, at, or below the cursor index? beq shftln_lp01 ; Yes, so keep looping. bcs shftln_end ; No, so we're done. shftln_lp01: ldy.w scr_ptr2 ; Get the source position. lda (ptr5), y ; Get the character from the source position. phy #2 ; Save the source position for later. txy ; Set our position to the destination. sta (ptr5), y ; Place the character from the source position, to the destination position. ply #2 ; Set our position back to the source. stb (ptr5), y ; Clear the character that is in the source. bng shftln_neg ; The source underflowed, so set it back to zero, dey ; Decrement the source position. dex ; Decrement the destination position. jmp shftln_lp0 ; Keep looping. shftln_lp1: stx.w scr_ptr2 ; Save the destination position for later. lda (ptr5), y ; Is the character at the source position, a null terminator? beq shftln_end1 ; Yes, so we're done. phy #2 ; No, so save the source position for later. txy ; Set our position to the destination. sta (ptr5), y ; Place the character from the source position, to the destination position. inx ; Increment the destination position. ply #2 ; Set our position back to the source. stb (ptr5), y ; Clear the character that is in the source. iny ; Increment the source position. jmp shftln_lp1 ; Keep looping. shftln_wrap: tax ; Use the ending line as a parameter for setbit. jsl setbit ; Set the wrap bit of the ending line. jmp shftln_end2 ; We are done. shftln_wrp1: tax ; Use the ending line as a parameter for clrbit. jsl clrbit ; Clear the wrap bit of the ending line. jmp shftln_end2 ; We are done. shftln_end: lda (ptr5), y ; Is this character a null terminator? bne shftln_nd0 ; No, so just find the end of the line. lda #$20 ; Yes, so convert it to a space for now. sta (ptr5), y ; shftln_nd0: jsl findend ; Find the ending line. sta d ; Save ending line for later. lda (ptr5), y ; Is this character a space? cmp #$20 ; bne shftln_nd1 ; No, so skip the conversion. lda #0 ; Yes, so convert it back to zero. sta (ptr5), y ; shftln_nd1: lda d ; Get the ending line. cmp scr_row ; Is the ending line greater than the starting line? beq shftln_end2 ; No, so we're done. bcs shftln_wrap ; Yes, so set the wrap bit. jmp shftln_end2 ; No, so we're done. shftln_end1: jsl findend ; Find the ending line. cpb #0 ; Is the remainder zero? beq shftln_nd01 ; Yes, so check if the ending line is greater than the starting line. jmp shftln_end2 ; No, so we're done. shftln_nd01: cmp scr_row ; Is the ending line greater than the starting line? beq shftln_end2 ; No, so we're done. bcs shftln_wrp1 ; Yes, so clear the wrap bit. shftln_end2: rtl ; End of shftln. esc: lda $C000 ; Get the next character. lda $C002 ; cmp #$1B ; Is this character an escape character? beq shftesc ; Yes, so check the other set of escape routines. lda $C000 ; No, so wait for 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 ; Set the D pseudo register to zero. sta d ; jsl isup ; Check if the user pressed up. lda d ; Did the user press up? bne esc_end ; Yes, so we're done. jsl isdown ; No, so check if the user pressed down. lda d ; Did the user press down? bne esc_end ; Yes, so we're done. lda #0 ; No, so check if the user pressed left. jsl isleft ; lda d ; Did the user press left? bne esc_end ; Yes, so we're done. jsl isright ; No, so check if the user pressed right. esc_end: lda #0 ; Clear the D pseudo register. sta d ; jmp printc_end ; We are done. shftesc: 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 ; Use the D pseudo register as a skip flag. sta d ; jsl isshftup ; Check if the user pressed shift+up. lda d ; Was it successful? bne shftesc_end ; Yes, so we're done. jsl isshftdown ; No, so check if the user pressed shift+down. shftesc_end: lda #0 ; Clear the D pseudo register. sta d ; jmp printc_end ; We are done. isup: lda c ; No, so load the escape code back into the accumulator. cmp #$41 ; Did the user press the up arrow key? bne isup_done ; No, so we're done. lda scr_row ; Yes, but is the cursor at the top of the screen? beq isup_scrl ; Yes, so check if we need to scroll. isup_2: 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. jmp isup_done ; No, so we're done isup_scrl: lda scr_str ; Are we at the top of the screen buffer? beq isup_done ; Yes, so we're done. jsl scrl_up ; No, so scroll up. lda #1 ; Tell the escape routine that we were successful. sta d ; isup_done: rtl ; End of isup. isdown: lda c ; No, so load the escape code back into the accumulator. cmp #$42 ; Did the user press the down arrow key? bne isdown_done ; No, so we're done. lda scr_row ; Yes, so start checking the y coordinate of the cursor. cmp #23 ; Is the cursor at the bottom of the screen? beq isdown_scrl ; Yes, so scroll down. 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 scr_row ; Save the cursor's row number. sta scr_trow ; lda scr_col ; Save the cursor's column number. sta scr_tcol ; jsl scrl_down ; Scroll down. lda scr_trow ; Load the cursor's row number. sta scr_row ; lda scr_tcol ; Load the cursor's column number. sta scr_col ; lda #1 ; Tell the escape routine that we were successful. sta d ; isdown_done: rtl ; End of isdown. isright: lda c ; No, so load the escape code back into the accumulator. cmp #$43 ; Did the user press the right arrow key? bne isright_dne ; No, so we're done. lda scr_col ; Yes, so start checking the x coordinate of the cursor. cmp #79 ; Is the cursor at the far right of the screen? beq isright_wrp ; Yes, so check if this is a wrapped line. jmp right ; No, so move the cursor right, like normal. isright_wrp: inc scr_row ; Move down a row. jsl getbit ; Is the current line, a wrapped line? bcs wrap_inc ; Yes, so leave the cursor where it is. dec scr_row ; No, so move the cursor back up a row. jmp isright_dne ; We are done. isright_scr: lda scr_str ; Are we at the top of the screen buffer? beq isright_end ; Yes, so we're done. lda #1 ; No, so scroll down. sta wrapped ; Set the wrapped flag. jsl scrl_down ; Scroll down. jmp isright_end ; We are done. wrap_inc: lda #0 ; Set the cursor to the far left of the screen. sta scr_col ; lda scr_row ; Get the current row number. cmp #23 ; Are we at the bottom of the screen? beq isright_nd2 ; No, so we're done. bcs isright_scr ; Yes, so check if we are scrolling down. jmp isright_nd2 ; No, so we're done. isright_end: dec scr_row ; Move back up a row. isright_nd2: jsl update_pos ; Update the cursor position. isright_dne: lda #0 ; Unset the wrapped flag. sta wrapped ; rtl ; End of isright. isleft: lda c ; Get the saved character. cmp #$43 ; Did the user press right? beq isleft_done ; Yes, so we're done lda scr_col ; No, but is the cursor at the far left of the screen? beq isleft_wrp ; Yes, so start checking if this is a wrapped line. 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. jmp isleft_done ; No, so we're done. isleft_wrp: jsl getbit ; Is the current line, a wrapped line? bcs wrap_dec ; Yes, so wrap back up a line. jmp isleft_done ; No, so we're done. wrap_dec: lda scr_row ; Is the cursor at the top of the screen? beq wrap_dec1 ; Yes, so don't move up a line. lda #1 ; No, so set the wrapped flag. sta wrapped ; dec scr_row ; Move the cursor up one line. wrap_dec1: lda #79 ; Move the Cursor to the far right of the screen. sta scr_col ; lda #1 ; Tell the escape routine that we were successful. sta d ; lda scr_row ; Are we at the top of the screen? beq isleft_scrl ; Yes, so check if we need to scroll. jmp isleft_end ; No, so we're done. isleft_scrl: lda wrapped ; Was the wrapped flag set somewhere else? bne isleft_end ; Yes so we're done. lda scr_str ; No, but are we actually at the top of the screen buffer? beq isleft_done ; Yes, so we're done. jsl scrl_up ; No, so scroll up. jmp isleft_done ; We are done. isleft_end: jsl update_pos ; Update the cursor position. isleft_done: lda #0 ; Unset the wrapped flag. sta wrapped ; rtl ; End of isleft. up: dec scr_row ; Move the cursor up a line. jsl update_pos ; Update it's position. lda #1 ; Tell the escape routine that we succeded. sta d ; jmp isup_done ; We are done. down: inc scr_row ; Move the cursor down a line. jsl update_pos ; Update it's position. lda #1 ; Tell the escape routine that we succeded. sta d ; jmp isdown_done ; We are done. right: inc scr_col ; Move the cursor right by one character. jsl update_pos ; Update it's position. jmp isright_dne ; We are done. left: dec scr_col ; Move the cursor left a character. jsl update_pos ; Update it's position. lda #1 ; Tell the escape routine that we succeded. sta d ; jmp isleft_done ; We are done isshftup: lda c ; Load the escape code back into the accumulator. cmp #$41 ; Did the user press the up arrow key? bne shftup_done ; lda #1 ; sta d ; lda scr_str ; beq shftup_done ; jmp shftup ; shftup_done: rtl ; isshftdown: lda c ; Load the escape code back into the accumulator. cmp #$42 ; Did the user press the down arrow key? bne shftdn_done ; lda #1 ; sta d ; lda scr_end ; cmp #71 ; bcs shftdn_done ; jmp shftdown ; shftdn_done: rtl ; shftup: jsl scrl_up ; lda #1 ; sta d ; jmp shftup_done ; shftdown: jsl scrl_down ; lda #1 ; sta d ; jmp shftdn_done ; update_pos: ldb #1 ; Set the F pseudo register to one, to fix some bugs. stb f ; clc ; Clear the carry flag. lda scr_row ; Add the cursor's line number, adc scr_str ; with the starting line number to get the absolute line number. tay ; Place it in the Y regster for now. clc ; Clear the carry flag. lsl #6 ; Multiply the absolute line number by 64. tab ; Use it as a second operand. tya ; Place the absolute line number back into the Accumulator lsl #4 ; Multiply the absolute line number by 16. aab ; Add both the Accumulator, and the B register together, to multiply the line number by 80. clc ; Clear the carry flag. adc scr_col ; Add the cursor's column number to get the screen index. tay ; Place the index into the Y register. 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. clc adc #$30 ; Convert it to ascii, and sta $C001 ; print to the screen. tba ; Get the remainder. clc adc #$30 ; Convert it to ascii, and sta $C001 ; print to the screen. rtl ; End of getrow. scrl_down: inc scr_str ; Increment the starting line of the screen. inc scr_end ; Increment the ending line of the screen. 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. lda scr_row ; Get the cursor's line number. pha #1 ; Save it in the stack. lda wrapped ; Was the wrapped flag set? beq scrldn_save ; Yes, so save the cursor position. scrldn1: jsl rdrw_row ; Redraw this row. lda wrapped ; Was the wrapped flag set? beq scrldn_load ; Yes, so load the previous cursor position back. jmp scrldn_end ; No, so we're done. scrldn_save: lda scr_col ; Get the cursor's column number. pha #1 ; Save it in the stack. jmp scrldn1 ; Start redrawing the current row. scrldn_load: pla #1 ; Get the cursor's previous column number back. sta scr_col ; scrldn_end: pla #1 ; Get the cursor's previous line number back. sta scr_row ; jsl update_pos ; Update the cursor's position. lda #0 ; Clear the wrapped flag. sta wrapped ; scrldn_done: rtl ; End of scrl_down. scrl_up: dec scr_str ; dec scr_end ; 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 #$53 ; Print 'S' sta $C001 ; to the screen, and end the escape sequence. lda scr_row ; pha #1 ; lda scr_col ; pha #1 ; lda #0 ; sta scr_row ; jsl rdrw_row ; pla #1 ; sta scr_col ; pla #1 ; sta scr_row ; jsl update_pos ; scrlup_done: rtl ; rdrw_row: lda #0 ; sta scr_col ; jsl update_pos ; rdrow_st: lda (ptr5), y ; beq rdrow_inc ; sta $C001 ; rdrow_inc: inc scr_col ; lda (ptr5), y ; beq rdrow_skip ; rdrow_inc1: iny ; rdrow_inc2: lda scr_col ; cmp #80 ; bcs rdrow_end ; jmp rdrow_st ; rdrow_skip: lda #$20 ; sta $C001 ; to the screen. jmp rdrow_inc1 ; rdrow_end: lda #0 ; sta scr_col ; jsl update_pos ; rdrow_done: rtl ; result: lda.w #string2 ; ldx.w zero ; jsl print_str ; rset_x: lda #0 ; Reset a. tax ; Reset x. jmp print_buf ; Print the input buffer. dabbed: ldb #0 ; lda.w #tok ; sta.q ptr2 ; tba ; dab_st: phy #2 ; txy ; lda (ptr6), y ; Get a character from the input buffer. beq dab_pend ; Are we done with printing the buffer? cmp (ptr2), y ; beq chk_str ; jmp dab_pend ; chk_str: ply #2 ; inx ; cpx #3 ; bne dab_st ; ldx #0 ; pnt_msg: lda.w #msg ; ldx #0 ; stx.q ptr ; jsl print_str ; jmp dab_peqnd ; dab_pend: ply #2 ; lda #1 ; jmp dab_end ; dab_peqnd: lda #0 ; jmp dab_end ; dab_end: rtl ; print_buf: lda.w #cmd_buf ; jsl print_str ; lda.w zero ; cmd_clr: lda #10 ; jsl print_char ; jmp start ; rdrw_ln: lda scr_row ; pha #1 ; inc end ; lda f ; sta scr_row ; lda scr_col ; pha #1 ; jsl update_pos ; rdrwln_lp: lda scr_row ; cmp e ; beq rdrwln_lp1 ; bcs rdrwln_done ; rdrwln_lp1: jsl rdrw_row ; rdrwln_inc: inc scr_row ; jmp rdrwln_lp ; rdrwln_done: pla #1 ; sta scr_col ; pla #1 ; sta scr_row ; jsl update_pos ; lda #0 ; sta e ; sta f ; dec end ; rtl ; .org $FFC0 .qword reset r done