From 35a18609864470b3dc49f3a9a6cb6ec93e57300d Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Thu, 25 Feb 2021 12:43:11 -0500 Subject: - Implemented the multiply expression into the assembler. - Implemented support for the SIB addressing mode into the assembler. SIB is short for "Scale Index, and Base", and works much like x86's version of SIB (scale*index+base), although my version supports any scale value between 1, and 256. - Redid the line shifting routine in SuBEditor. It now uses memcpy, and memset to do that, and also supports shifting the line left, or right by any number of characters. --- programs/sub-suite/subeditor.s | 429 +++++++++++++++++++++++++++++++++-------- 1 file changed, 351 insertions(+), 78 deletions(-) (limited to 'programs/sub-suite/subeditor.s') diff --git a/programs/sub-suite/subeditor.s b/programs/sub-suite/subeditor.s index f6b647f..83fe179 100644 --- a/programs/sub-suite/subeditor.s +++ b/programs/sub-suite/subeditor.s @@ -196,11 +196,22 @@ clrbit: setbit: pha.q ; Preserve A. + phb.q ; Preserve B. + mov b, s ; Save the bit. des ; Create the stack frame. lea s, (sp+1) ; Get the address of the bitmask. jsr bitpos ; Get the bit, and byte position. ins ; Cleanup the stack frame. + cpb #1 ; Is the bit set? + bne @clear ; No, so clear the bit. +@set: or (bitabl)+a, (s) ; Set the bit of the current row number to one. + bra @end ; We are done. +@clear: + not (s) ; Invert the bitmask. + and (bitabl)+a, (s) ; Set the bit of the current row number to zero. +@end: + plb.q ; Restore B. pla.q ; Restore A. rts ; End of setbit. @@ -257,21 +268,19 @@ cmd_cpy: sta scr_trow ; Save it for later. lea d, (buffer) ; Get the screen buffer. mov s, y ; Get the cursor index. + lea f, 1 ; Set the decrement offset to the left flag. jsr find_end ; Find the end of the line. div #maxcol+1 ; Get the ending line. ldb scr_str ; Has the screen been scrolled? beq @start ; No, so don't subtract the screen's starting point from the line number. @offset: - sec ; Yes, so make sure that we don't subtract by the starting point, plus one. - sbc scr_str ; Offset the row position, back by the screen's starting point. - clc ; Clear the carry flag, so that nothing odd occurs. + sub scr_str ; Offset the row position, back by the screen's starting point. @start: sta scr_row ; Set the row position to the end of the line. sta rege ; Save it into the temporary row posiition. jsr findst ; Find the start of the line. - clc ; Clear the carry flag. lda scr_row ; Get the row position. - adc scr_str ; Add it with the screen's starting row. + add scr_str ; Add it with the screen's starting row. mul #maxcol+1 ; Multiply it with the width of the screen, plus one. tay ; Place it into the index. ldx.w #0 ; Reset the X register. @@ -338,13 +347,52 @@ findst: rts ; End of findst. +;find_end: +; mov a, s ; Set the loop counter. +;@loop: +; inc ; Increment the loop counter. +; cmp (d+a-1), #0 ; Did we hit the null terminator? +; bne @loop ; No, so keep looping. +;@end: +; rts ; End of find_end2. + + find_end: + phb.q ; Preserve B. + phx.q ; Preserve X. + phy.q ; Preserve Y. + phe.q ; Preserve E. mov a, s ; Set the loop counter. + div #maxcol+1 ; Get the row position. + tay ; Save the row position. + mov b, d ; Preserve the string pointer. + mov x, s ; Preserve the cursor position. + mov d, a ; + xor s, s ; Reset S. @loop: + inc d ; Increment the line. + mov e, d ; Save the line. + jsr getbit ; Get the linewrap bit. + mov d, e ; Get the line. + cmp #1 ; Is this the end of the line? + beq @loop ; No, so keep looping. +@loop2_1: + mov a, d ; Get the ending row position. + sub a, f ; Decrement the row position by the offset. + mul #maxcol+1 ; Get the loop counter. + cmp a, x ; Is the new loop counter less than the old loop counter? + mcc a, x ; Set the loop counter to the old loop counter if so. + mov d, b ; Restore the string pointer. + mov s, x ; Restore the cursor position. +@loop2: inc ; Increment the loop counter. cmp (d+a-1), #0 ; Did we hit the null terminator? - bne @loop ; No, so keep looping. + bne @loop2 ; No, so keep looping. @end: + ple.q ; Restore E. + ply.q ; Restore Y. + plx.q ; Restore X. + plb.q ; Restore B. rts ; End of find_end. @@ -353,6 +401,11 @@ get_endrow: div #maxcol+1 ; Get the ending row. rts ; End of get_endrow +;get_endrow2: +; jsr find_end2 ; Find the end of the line. +; div #maxcol+1 ; Get the ending row. +; rts ; End of get_endrow + print_char: phb.q ; Preserve B. @@ -392,6 +445,7 @@ printc: @update1: lea d, (buffer) ; Get the screen buffer. mov s, y ; Get the cursor index. + lea f, 1 ; Set the decrement offset to one. jsr get_endrow ; Get the ending line. mov d, a ; mov s, scr_trow ; Get the current row position. @@ -414,7 +468,8 @@ printc: ; stb regd ; lea d, (buffer) ; Get the screen buffer. mov.w s, scr_ptr; Get the cursor index. - mov f, #1 ; Set the left flag to true. + lea f, 1 ; Set the shift length to one. + lea c, 1 ; Set the left flag to true. jsr shftln ; ldb #1 ; stb regd ; @@ -454,7 +509,7 @@ printc: bra @print ; @scroll: sta scr ; Echo typed character. - clc ; +; clc ; lda #1 ; sta wrapped ; jsr scrl_down ; @@ -474,6 +529,7 @@ printc: ; tax ; mov d, scr_row ; Get the row position. add d, scr_str ; Add the row offset to the row position. + lea s, 1 ; Set the bit to one. jsr setbit ; Set the bit of that row. ; plx.w ; jsr update_pos ; @@ -560,13 +616,11 @@ bs: bne @scroll ; Yes, so scroll up. rts ; No, so we're done. @scroll: - clc ; Clear the carry flag, so that we don't get odd behaviour. jsr scrl_up ; Scroll up. inc scr_row ; Move down by one row. @wrap3: - clc ; Clear the carry flag. lda scr_row ; Add the cursor's row position, - adc scr_str ; and the screen's starting row. + add scr_str ; and the screen's starting row. tax ; Transfer that into X. @wrap4: dec scr_row ; Move up by one row. @@ -581,6 +635,7 @@ back: sta scr_trow ; lea d, (buffer) ; Get the screen buffer. mov s, y ; Get the cursor index. + lea f, 0 ; Set the decrement offset to zero. jsr get_endrow ; Get the ending line. sta scr_row ; Set our row position to the end of the line. @find_st: @@ -599,7 +654,8 @@ back: stb regd ; lea d, (buffer) ; Get the screen buffer. mov s, y ; Get the cursor index. - mov f, #0 ; Set the left flag to false. + lea f, 1 ; Set the shift length to one. + lea c, 0 ; Set the left flag to false. jsr shftln ; Shift line back by one character. lda #$7F ; Print a backspace to the screen. sta scr ; @@ -608,6 +664,7 @@ back: @find_end: lea d, (buffer) ; Get the screen buffer. mov s, y ; Get the cursor index. + lea f, 1 ; Set the decrement offset to one. jsr get_endrow ; Yes, so Get the ending line. mov d, a ; mov s, scr_trow ; Get the current row position. @@ -630,66 +687,288 @@ back: bra @shift ; Start shifting the line back. +;shftln: +; pha.q ; Preserve A. +; phb.q ; Preserve B. +; and f, f ; Is the left flag not set? +; beq @right ; Yes, so shift the line to the right. +;; txa ; Get the end of the line. +; jsr find_end ; Find the end of the line. +; dec ; Decrement the source position. +; bra @left ; No, so shift the line to the left. +;@minus: +; and #0 ; Set the source poition to 0. +; mov (d), a ; Clear the character that is in the source. +; bra @lend ; We are done. +;@left: +; cmp s, a ; Is the cursor index, at, or below the source position? +; beq @left1 ; Yes, so keep looping. +; bcs @lend ; No, so we're done. +;@left1: +; cmp #0 ; Is the source position less than 0? +; bcc @minus ; Yes, so set the source position to zero. +; mov (d+a+1), (d+a) ; No, so shift the current character to the left by one. +; mov (d+a), #0 ; Clear the current character. +; dec ; Decrement the source position. +; bra @left ; Keep looping. +;@right: +; cmp (d+s), #0 ; Is this character a null terminator? +; beq @rend ; Yes, so we're done. +; mov (d+s-1), (d+s) ; No, so shift the current character to the right by one. +; mov (d+s), #0 ; Clear the current character. +; inc s ; Increment the source position. +; bra @right ; Keep looping. +;@wrap: +; mov d, a ; Get the ending line. +; lea s, f ; Set the bit to the left flag. +; jsr setbit ; Set the wrap bit of the ending line. +; bra @end ; We are done. +;@lend: +; lea s, (a+2) ; Add 2 to the source position. +; jsr find_end ; Find the end of the line. +; dec ; Decrement the end of line position. +; div #maxcol+1 ; Get the ending line. +;@lend2: +; cmp scr_row ; Is the ending line greater than the starting line? +; beq @end ; No, so we're done. +; bcs @wrap ; Yes, so set the wrap bit. +; bra @end ; No, so we're done. +;@rend: +; lea f, 0 ; Set the decrement offset to one. +; jsr find_end ; Find the end of the line. +; dec ; Decrement the end of line position. +; div #maxcol+1 ; Get the ending line. +; cpb #0 ; Is the remainder zero? +; bne @end ; No, so we're done. +;@rend2: +; cmp scr_row ; Is the ending line greater than the starting line? +; beq @end ; No, so we're done. +; bcs @wrap ; Yes, so clear the wrap bit. +;@end: +; plb.q ; Restore B. +; pla.q ; Restore A. +; rts ; End of shftln. + + +;minmax: +; psh.q d ; Preserve D. +; psh.q s ; Preserve S. +; mov d, e ; Get the shift length. +; mov s, b ; Get the ending position. +; jsr max ; Get the largest value. +; mov f, a ; Save the largest value. +; jsr min ; Get the smallest value. +; pul.q s ; Restore S. +; pul.q d ; Restore D. +; rts ; End of minmax. + + +;shftln: +; pha.q ; Preserve A. +; phb.q ; Preserve B. +; phx.q ; Preserve X. +; phy.q ; Preserve Y. +; phe.q ; Preserve E. +; mov x, d ; Get the string pointer. +; mov y, s ; Get the cursor position. +; mov e, f ; Get the shift length. +;@find_end: +; lea f, 1 ; Set the decrement offset to the left flag. +; jsr find_end ; Find the end of the line. +; mov f, e ; Get the shift length. +; tab ; Save the end position for later. +; and #0 ; Reset A. +; dec ; Set our offset to -1. +; and c, c ; Is the left flag set? +; mne a, f ; Set our offset to the length argument if so. +;@copy: +; add a, s ; Add the cursor position with the offset. +; lea s, (d+s) ; Get the address of the string pointer, at the cursor position. +; lea d, (d+a) ; Get the address of the string pointer, at the cursor position, plus the offset. +; jsr minmax ; Get the minimum, and maximum values. +;@check_length: +; cpe #2 ; Is the shift length greater than one? +; bcc @offset0 ; No, so skip the subtraction below. +; cmp f, y ; Yes, and is the end position greater than, or equal to the the cursor position? +; bcc @offset ; No, so skip the subtraction below. +; and c, c ; Yes, and is the left flag set? +; beq @offset0 ; No, so skip the subtraction below. +;@sub: +; tya ; Set the offset to the cursor position. +; bra @offset ; Subtract the offset. +;@offset0: +; sub f, a ; Subtract the end position by the shift length. +; bra @sub ; Subtract the cursor position. +;@offset: +; sub f, a ; Subtract the offset. +;@copy2: +; jsr memcpy ; Copy the string from the cursor, to the cursor plus the offset. +;@clear: +; jsr minmax ; Get the minimum, and maximum values. +; cmp #1 ; Is the smallest value equal to one? +; bne @clear2 ; No, so skip incrementing the value. +; inc ; Increment the smallest value. +;@clear2: +; sub f, a ; Subtract the end position by the shift length. +; mov d, y ; Get the cursor position. +; and c, c ; Is the left flag set? +; meq d, f ; Get the end position, minus the shift length if so. +; lea d, (x+d) ; Get the address of the string pointer, at the offset. +; xor s, s ; Reset S. +; mov f, e ; Restore the shift length. +; jsr memset ; Clear shift length bytes of the string, from the offset. +;@neg: +; and c, c ; Is the left flag set? +; bne @get_rows ; Yes, so don't negate the shift length. +; neg f ; Negate the shift length. +;@get_rows: +; mov x, b ; Save the end position. +; lea a, (b+f) ; Add, or subtract the end position, by the shift length. +; div #maxcol+1 ; Get the new ending line. +; mov e, a ; Save the ending line. +; xor f, f ; Reset F. +; and c, c ; Is the left flag set? +; meq f, b ; Save the remainder of the ending line if not. +; tya ; Get the cursor position. +; div #maxcol+1 ; Get the cursor line. +; and c, c ; Is the left flag set? +; meq a, e ; Set the starting line to the new ending line if not. +; tay ; Save the starting line. +; txa ; Get the end position. +; div #maxcol+1 ; Get the old ending line. +; and c, c ; Is the left flag set? +; mne a, e ; Set the ending line to the new ending line if so. +; tab ; Save the ending line. +; and c, c ; Is the left flag set? +; bne @inc ; Yes, so increment the starting line. +; cmp y, b ; No, but is the starting line less than the ending line? +; bcs @loop ; No, so don't increment. +; iny ; Yes, so increment the starting line. +; bra @getbit ; Get the bit. +;@loop: +; xor s, s ; Reset S. +; cmp y, b ; Is the current line greater than the ending line? +; beq @rem ; The current line is equal to the ending line, so check the remainder. +; bcs @end ; Yes, so we're done. +; bra @getbit ; No, so get the bit. +;@rem: +; and f, f ; Is the remainder zero? +; bne @end ; No, so we're done. +;@getbit: +; mov d, y ; Get the current line. +; jsr getbit ; Get the linewrap bit of that line. +; cmp a, c ; Is the linewrap bit the opposite value of the left flag? +; beq @inc ; No, so keep looping. +;@setbit: +; mov d, y ; Get the current line. +; mov s, c ; Get the left flag. +; jsr setbit ; Set the linewrap bit to the left flag. +;@inc: +; iny ; Increment the current line. +; bra @loop ; Keep looping. +;@end: +; ple.q ; Restore E. +; ply.q ; Restore Y. +; plx.q ; Restore X. +; plb.q ; Restore B. +; pla.q ; Restore A. +; rts ; End of shftln. + + shftln: pha.q ; Preserve A. phb.q ; Preserve B. - and f, f ; Is the left flag not set? - beq @right ; Yes, so shift the line to the right. -; txa ; Get the end of the line. - jsr find_end ; Find the end of the line. - dec ; Decrement the source position. - bra @left ; No, so shift the line to the left. -@minus: - and #0 ; Set the source poition to 0. - mov (d), a ; Clear the character that is in the source. - bra @lend ; We are done. -@left: - cmp s, a ; Is the cursor index, at, or below the source position? - beq @left1 ; Yes, so keep looping. - bcs @lend ; No, so we're done. -@left1: - cmp #0 ; Is the source position less than 0? - bcc @minus ; Yes, so set the source position to zero. - mov (d+a+1), (d+a) ; No, so shift the current character to the left by one. - mov (d+a), #0 ; Clear the current character. - dec ; Decrement the source position. - bra @left ; Keep looping. -@right: - cmp (d+s), #0 ; Is this character a null terminator? - beq @rend ; Yes, so we're done. - mov (d+s-1), (d+s) ; No, so shift the current character to the right by one. - mov (d+s), #0 ; Clear the current character. - inc s ; Increment the source position. - bra @right ; Keep looping. -@wrap: - mov d, a ; Get the ending line. - jsr setbit ; Set the wrap bit of the ending line. - bra @end ; We are done. -@wrap1: - mov d, a ; Get the ending line. - jsr clrbit ; Clear the wrap bit of the ending line. - bra @end ; We are done. -@lend: - lea s, (a+2) ; Add 2 to the source position. - jsr find_end ; Find the end of the line. - dec ; Decrement the end of line position. - div #maxcol+1 ; Get the ending line. -@lend2: - cmp scr_row ; Is the ending line greater than the starting line? - beq @end ; No, so we're done. - bcs @wrap ; Yes, so set the wrap bit. - bra @end ; No, so we're done. -@rend: + phx.q ; Preserve X. + phy.q ; Preserve Y. + phe.q ; Preserve E. + psh.q bp ; Preserve BP. + mov x, d ; Get the string pointer. + mov y, s ; Get the cursor position. + mov e, f ; Get the shift length. + and c, c ; Is the left flag set? + bne @find_end ; Yes, so find the end of the line. + cmp s, f ; No, but is the cursor position greater than, or equal to the shift length? + bcc @end ; No, so we're done. +@find_end: + lea f, 1 ; Set the decrement offset to the left flag. jsr find_end ; Find the end of the line. - dec ; Decrement the end of line position. - div #maxcol+1 ; Get the ending line. - cpb #0 ; Is the remainder zero? + mov f, e ; Get the shift length. + sub a, c ; Decrement the old end position, if the left flag is set. + tab ; Save the old end position for later. + mov a, f ; Get the shift length. + neg a ; Negate the shift length. + and c, c ; Is the left flag set? + mne a, f ; Set our offset to the shift length if so. + lea bp, (b+a) ; Add the old end position, with the offset to get the new end position. +@copy: + add a, y ; Add the cursor position with the offset. + lea s, (x+y) ; Get the address of the string pointer, at the cursor position. + lea d, (x+a) ; Get the address of the string pointer, at the cursor position, plus the offset. + mov f, b ; Get the old end position. + sub f, y ; Subtract the old end position, by the cursor position. + jsr memcpy ; Copy the string from the cursor, to the cursor plus the offset. +@clear: + tya ; Get the cursor position. + and c, c ; Is the left flag set? + meq a, bp ; Set our offset to the new end position if not. + lea d, (x+a) ; Get the address of the string pointer, at the offset position. + xor s, s ; Reset S. + mov f, e ; Get the shift length. + jsr memset ; Clear shift length bytes of the string, from the offset. +@get_rows: + mov x, b ; Save the old end position. + mov a, bp ; Get the new end position. + div #maxcol+1 ; Get the new ending line. + mov e, a ; Save the ending line. + xor f, f ; Reset F. + and c, c ; Is the left flag set? + meq f, b ; Save the remainder of the ending line if not. + tya ; Get the cursor position. + div #maxcol+1 ; Get the cursor line. + mov bp, a ; Save the cursor line. + and c, c ; Is the left flag set? + meq a, e ; Set the starting line to the new ending line if not. + tay ; Save the starting line. + txa ; Get the old end position. + div #maxcol+1 ; Get the old ending line. + cmp bp, a ; Is the cursor line greater than, or equal to the old ending line? + mcs a, bp ; Get the cursor line if so. + inc ; Increment the line. + and c, c ; Is the left flag set? + mne a, e ; Set the ending line to the new ending line if so. + tab ; Save the ending line. + and c, c ; Is the left flag set? + bne @inc ; Yes, so increment the starting line. + cmp y, b ; No, but is the starting line less than the ending line? + bcs @loop ; No, so don't increment. + iny ; Yes, so increment the starting line. + bra @getbit ; Get the bit. +@loop: + xor s, s ; Reset S. + cmp y, b ; Is the current line greater than the ending line? + beq @rem ; The current line is equal to the ending line, so check the remainder. + bcs @end ; Yes, so we're done. + bra @getbit ; No, so get the bit. +@rem: + and f, f ; Is the remainder zero? bne @end ; No, so we're done. -@rend2: - cmp scr_row ; Is the ending line greater than the starting line? - beq @end ; No, so we're done. - bcs @wrap1 ; Yes, so clear the wrap bit. +@getbit: + mov d, y ; Get the current line. + jsr getbit ; Get the linewrap bit of that line. + cmp a, c ; Is the linewrap bit the opposite value of the left flag? + beq @inc ; No, so keep looping. +@setbit: + mov d, y ; Get the current line. + mov s, c ; Get the left flag. + jsr setbit ; Set the linewrap bit to the left flag. +@inc: + iny ; Increment the current line. + bra @loop ; Keep looping. @end: + pul.q bp ; Restore BP. + ple.q ; Restore E. + ply.q ; Restore Y. + plx.q ; Restore X. plb.q ; Restore B. pla.q ; Restore A. rts ; End of shftln. @@ -987,12 +1266,9 @@ bcd: 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 scr ; to the screen. - lda #'[' ; Print '[' - sta scr ; to the screen, and start the escape sequence. - lda #'T' ; Print 'T' - sta scr ; to the screen, and end the escape sequence. + mov scr, #'\e' ; Print an escape character to the screen. + mov scr, #'[' ; Print '[' to the screen, and start the escape sequence. + mov scr, #'T' ; Print 'T' to the screen, and end the escape sequence. lda scr_row ; Get the cursor's line number. pha ; Save it in the stack. lda wrapped ; Was the wrapped flag set? @@ -1022,12 +1298,9 @@ scrl_down: scrl_up: dec scr_str ; dec scr_end ; - lda #$1B ; Print an escape character - sta scr ; to the screen. - lda #'[' ; Print '[' - sta scr ; to the screen, and start the escape sequence. - lda #'S' ; Print 'S' - sta scr ; to the screen, and end the escape sequence. + mov scr, #'\e' ; Print an escape character to the screen. + mov scr, #'[' ; Print '[' to the screen, and start the escape sequence. + mov scr, #'S' ; Print 'S' to the screen, and end the escape sequence. lda scr_row ; pha ; lda scr_col ; -- cgit v1.2.3-13-gbd6f