From 4ed07ca38b99abdca750c6612c512f30965f1714 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Sun, 30 Aug 2020 12:44:21 -0400 Subject: - Did some more work on SuBAsm's lexer. - Optimized the memory read, and write functions. - Made the emulator faster, and cleaner in general. --- programs/sub-suite/declare.s | 120 +++++++++++++++++----- programs/sub-suite/lexer.s | 228 ++++++++++++++++++++++++++++++----------- programs/sub-suite/subeditor.s | 37 +++---- programs/sub-suite/subsuite.s | 1 - programs/sub-suite/utils.s | 99 ++++++++++++++---- 5 files changed, 360 insertions(+), 125 deletions(-) (limited to 'programs/sub-suite') diff --git a/programs/sub-suite/declare.s b/programs/sub-suite/declare.s index 55ccc2b..166197b 100644 --- a/programs/sub-suite/declare.s +++ b/programs/sub-suite/declare.s @@ -12,7 +12,7 @@ maxrow = 23 ; Screen's row count. maxcol = 79 ; Screen's column count. MAX_SYM = $800 ; Max symbol size. -OPNUM = 87 ; Instruction count. +OPNUM = 74 ; Instruction count. ; Directives. DIR_ORG = 0 ; Origin. @@ -34,13 +34,15 @@ TOK_STR = 6 ; String. TOK_CHAR = 7 ; Character. TOK_IND = 8 ; Indirect addressing. TOK_IMM = 9 ; Immediate data. -TOK_MNE = 10 ; Opcode/Mnemonic. -TOK_RS = 11 ; Register size prefix. -TOK_COMM = 12 ; Comment. -TOK_HEX = 13 ; Hex value. -TOK_DEC = 14 ; Decimal value. -TOK_BIN = 15 ; Binary value. -TOK_INCL = 16 ; Include file. +TOK_BREG = 10 ; B register. +TOK_MNE = 11 ; Opcode/Mnemonic. +TOK_RS = 12 ; Register size prefix. +TOK_OF = 13 ; Offset register prefix. +TOK_COMM = 14 ; Comment. +TOK_HEX = 15 ; Hex value. +TOK_DEC = 16 ; Decimal value. +TOK_BIN = 17 ; Binary value. +TOK_INCL = 18 ; Include file. ; Pre-Tokens. PTOK_DOT = 0 ; . @@ -55,19 +57,20 @@ PTOK_PIPE = 8 ; | PTOK_LBRAK = 9 ; ( PTOK_RBRAK = 10 ; ) PTOK_COMMA = 11 ; , -PTOK_X = 12 ; x -PTOK_Y = 13 ; y -PTOK_S = 14 ; s -PTOK_P = 15 ; p -PTOK_DQUOT = 16 ; " -PTOK_SQUOT = 17 ; ' -PTOK_HASH = 18 ; # -PTOK_SCOLN = 19 ; ; -PTOK_DOLR = 20 ; $ -PTOK_PRCNT = 21 ; % -PTOK_NUM = 22 ; 0-9 -PTOK_ALPH = 23 ; a-z A-Z -PTOK_OTHR = 24 ; Everything else. +PTOK_B = 12 ; b +PTOK_X = 13 ; x +PTOK_Y = 14 ; y +PTOK_S = 15 ; s +PTOK_P = 16 ; p +PTOK_DQUOT = 17 ; " +PTOK_SQUOT = 18 ; ' +PTOK_HASH = 19 ; # +PTOK_SCOLN = 20 ; ; +PTOK_DOLR = 21 ; $ +PTOK_PRCNT = 22 ; % +PTOK_NUM = 23 ; 0-9 +PTOK_ALPH = 24 ; a-z A-Z +PTOK_OTHR = 25 ; Everything else. ; Expressions. EXPR_PLUS = 0 ; Plus. @@ -201,14 +204,50 @@ valbuf: cpybuf: .res 8 -; Current token line. +; Token ID, used by make_tok. +t_id: + .res 1 + +; Token type, used by make_tok. +t_type: + .res 1 + +; Number of spaces before a token, used by make_tok. +t_space: + .res 1 + +; Number of tabs before a token, used by make_tok. +t_tab: + .res 1 + +; Token value, used by make_tok. +t_val: + .res 8 + +; Token string, used by make_tok. +t_str: + .res 8 + +; Token symbol, used by make_tok. +t_sym: + .res 8 + +; Current token. ctok: .res 2 -; Last token line. +; Last token. ltok: .res 2 +; Current line. +cline: + .res 2 + +; Last line. +lline: + .res 2 + ; Lexeme type. lex_type: .res 1 @@ -679,6 +718,38 @@ cmd_srt: .word run .word set +; Return table used by get_ctrlidx. +ct_rtb: + .byte 2 + .byte 0 + .byte 1 + .byte 0 + .byte 3 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 5 + .byte 4 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 6 + +; Jump table for print_char's control codes. +ct_jtb: + .word printc ; Everything else (print it). + .word nl ; Newline. + .word bs ; Backspace. + .word clr_scr ; Ctrl+L. + .word en_step ; Ctrl+S. + .word dis_step ; Ctrl+R. + .word esc ; Escape. ; Jump table for parsing pre-tokens. swtab: @@ -694,6 +765,7 @@ swtab: .word ptok_lbrk ; PTOK_LBRAK .word ptok_rbrk ; PTOK_RBRAK .word ptok_com ; PTOK_COMMA + .word ptok_br ; PTOK_B .word ptok_xr ; PTOK_X .word ptok_yr ; PTOK_Y .word ptok_sp ; PTOK_S @@ -715,7 +787,7 @@ hex_char: ; Compare, and return table for pre-tokens. ptok_tab: - .byte ".@:=+-><|(),xysp\"\'#;$%" + .byte ".@:=+-><|(),bxysp\"\'#;$%" ; Compare, and return table for isdelm. dtab: .byte "\n,\"\' \\" diff --git a/programs/sub-suite/lexer.s b/programs/sub-suite/lexer.s index 3a856b5..72f1db6 100644 --- a/programs/sub-suite/lexer.s +++ b/programs/sub-suite/lexer.s @@ -8,6 +8,10 @@ lex: sty.q idx0 ; Clear the first index. sty.q idx1 ; Clear the second index. sty.q idx2 ; Clear the third index. + sty.d t_id ; Clear the token ID, type, space count, and tab count. + sty.q t_val ; Clear the token value. + sty.q t_str ; Clear the token string. + sty.q t_sym ; Clear the token symbol. sty regb ; Clear the isop flag. ; lda (ptr), y ; Get a character from the line. ; pha ; Preserve the character. @@ -17,11 +21,11 @@ lex: lda #2 ; Get the third byte, of the line table address. lsl #$10 ; Shift it by 2 bytes. ldb #1 ; Set the second pointer - lda.w ltok ; to the last line. + lda.w lline ; to the last line. jsr set_ptr ; lda.w (ptr2) ; Get the next line. jsr set_ptr ; Set the second pointer to the next line. - sta.w ctok ; Make it the current line. + sta.w cline ; Make it the current line. and #0 ; Reset A. @loop: ldy.w idx0 ; Get the string index. @@ -36,7 +40,7 @@ lex: jsr isdelm ; Get the delimiter. and #$10 ; Is this character, a space, or tab? pla ; Get the character back. - beq @isstart ; No, so check for the start of the line. + beq @switch ; No, so start lexing. inc.w idx0 ; Yes, so increment the string index. cmp #' ' ; Is this character, a space? beq @incs ; Yes, so increment the starting space count. @@ -44,31 +48,66 @@ lex: beq @inct ; Yes, so increment the starting tab count. bra @spaces ; No, so Keep looping. @incs: - inc idx1 ; Increment the space count. + inc t_space ; Increment the space count. bra @spaces ; Keep looping. @inct: - inc idx1+1 ; Increment the tab count. + inc t_tab ; Increment the tab count. bra @spaces ; Keep looping. -@isstart: - pha.w ; Preserve the character. - lda.w idx1 ; Was there any whitespace? - pla.w ; Get the character back. - beq @switch ; No, so start lexing. - cpb #1 ; Yes, and are we at the start of the line? - bne @switch ; No, so start lexing. -@whtspace: - ldy #2 ; Yes, so set the line index to the starting whitespace counters. - lda.w idx1 ; Get both indecies. - sta.w (ptr2), y ; Save them in the line. - and #0 ; Reset A. - sta.w idx1 ; Reset the second index. - deb ; Set the isstart flag to false. @switch: ldy.w idx0 ; Get the string index. lda (ptr), y ; Get the character. jsr get_ptok ; Get the pre-token. + pha ; Preserve the pre-token. + jsr is_altok ; Is this one of the single letter pre-tokens? + pla ; Get the pre-token back. + bne @is_altok ; Yes, so check the rest of the pre-token. +@parse: jsr parse_ptok ; Parse the pre-token. ; beq @end ; We got to the end of the string. + lda lex_type ; Get the lexeme type. + cmp #TOK_EXPR ; Was this token, an expression? + beq @inc_idx ; Yes, so increment the index. + ldy.w idx0 ; No, so get the string index. + lda (ptr), y ; Get a character from the line. + jsr isdelm2 ; Is this not a delimiter? + beq @inc_idx ; Yes, so increment the index. + bra @loop ; No, so keep looping. +@is_altok: + sta lex_type ; Save the pre-token in the lexeme type. + iny ; Increment the offset. + cmp #PTOK_S ; Is this pre-token, PTOK_S? + bne @ptok_p ; No, so check for PTOK_P. + lda (ptr), y ; Yes, so get the next character after it. + jsr tolower ; Convert it to lowercase. + cmp #'p' ; Is the next character 'p'? + bne @ptok_p ; No, so check for PTOK_P. + bra @inc_offset ; Yes, so increment the offset. +@ptok_p: + cmp #PTOK_P ; Is this pre-token, PTOK_P? + bne @is_altok2 ; No, so skip incrementing the offset. + lda (ptr), y ; Yes, so get the next character after it. + jsr tolower ; Convert it to lowercase. + cmp #'c' ; Is the next character 'c'? + bne @is_altok2 ; No, so skip incrementing the offset. +@inc_offset: + iny ; Increment the offset. +@is_altok2: + lda (ptr), y ; Yes, so get the character, at the current offset. + jsr get_ptok ; Get the pre-token of the character. + cmp #PTOK_P ; Is this pre-token greater than PTOK_P? + bcc @ptok_num ; No, so check for PTOK_NUM. + beq @ptok_num ; + cmp #PTOK_B ; Yes, and is this pre-token greater than, or equal to PTOK_B? + bcs @ptok_al ; Yes, so set the pre-token to PTOK_ALPH. + lda lex_type ; No, so get the original pre-token back. + ldy.w idx0 ; Get the string index. + bra @parse ; Go back to parsing the pre-token. +@ptok_al: + lda #PTOK_ALPH ; Set the pre-token to PTOK_ALPH. + ldy.w idx0 ; Get the string index. + bra @parse ; Go back to parsing the pre-token. +@inc_idx: + inc.w idx0 ; Increment the string index. bra @loop ; Keep looping. @end: jsr update_ptr ; Get the screen buffer index. @@ -97,21 +136,23 @@ ptok_dot: ldb #1 ; Make init_lex increment the string index. jsr init_lex ; Initialize the lexeme buffer for copying. ldb #$11 ; Set the delimiter comparison value to whitespace. + lda #0 ; Set the isesc flag to false. + pha ; jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter. + pla ; @isop: lda regb ; Has the isop flag been set? beq @dir ; No, so check for a directive. @rs: lda #TOK_RS ; Yes, so set the lexeme type to TOK_RS. sta lex_type ; + sta t_id ; Also set the token ID to TOK_RS. ldy.w idx1 ; Get the lexeme index. dey ; Decrement the lexeme index. lda (ptr3), y ; Get the suffix character. jsr get_rs ; Get the register size. bra @end ; We are done. @dir: - lda #TOK_DIR ; Set the lexeme type to TOK_DIR. - sta lex_type ; ldb #0 ; Make the lexeme buffer, the first pointer. stb.q idx1 ; Reset the first index. jsr set_lexptr ; Set up the lexeme buffer. @@ -135,7 +176,11 @@ ptok_dot: sta.w idx2 ; Save the offset in the third index. bra @dir_loop ; Keep looping. @found: - nop ; + lda #TOK_DIR ; Set the lexeme type to TOK_DIR. + sta lex_type ; + sta t_id ; Also set the token ID to TOK_DIR. + lda idx1 ; Set the token type to the directive ID. + sta t_type ; @end: jsr make_tok ; Create the token. jsr set_cmdbuf ; Set the first pointer to the command buffer. @@ -156,7 +201,6 @@ ptok_min: lda #EXPR_MINUS ; Set the expresion type to EXPR_MINUS. bra ptok_expr ; Set up the token. ptok_gt: - lda #EXPR_LOW ; Set the expresion type to EXPR_LOW. bra ptok_expr ; Set up the token. ptok_lt: @@ -165,7 +209,9 @@ ptok_lt: ptok_pipe: lda #EXPR_OR ; Set the expresion type to EXPR_OR. ptok_expr: + sta t_type ; Set the token type to the expression type. lda #TOK_EXPR ; Set the lexeme type to TOK_EXPR. + sta t_id ; Also set the token ID to TOK_EXPR. sta lex_type ; inc.w idx0 ; ; ldb #1 ; Make init_lex increment the string index. @@ -182,6 +228,9 @@ ptok_rbrk: ptok_com: inc.w idx0 ; rts ; End of parse_ptok. +ptok_br: + inc.w idx0 ; + rts ; End of parse_ptok. ptok_xr: inc.w idx0 ; rts ; End of parse_ptok. @@ -197,16 +246,36 @@ ptok_pc: ptok_dqu: ldb #1 ; Make init_lex increment the string index. jsr init_lex ; Initialize the lexeme buffer for copying. - ldb #4 ; Set the delimiter comparison value to a double quote. + ldb #5 ; Set the delimiter comparison value to a double quote, or EOL. + lda #1 ; Set the isesc flag to true. + pha ; + and #0 ; Make delmcpy use isdelm. jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter. + pla ; + lda #TOK_DQUOT ; Set the lexeme type to TOK_DQUOT. + sta lex_type ; + sta t_id ; Also set the token ID to TOK_DQUOT. + lda.d ptr3 ; Get the address of the lexeme buffer. + sta.q t_str ; Save it in the token string. @end: + jsr make_tok ; Create the token. rts ; End of parse_ptok. ptok_squ: ldb #1 ; Make init_lex increment the string index. jsr init_lex ; Initialize the lexeme buffer for copying. - ldb #8 ; Set the delimiter comparison value to a single quote. + ldb #9 ; Set the delimiter comparison value to a single quote, or EOL. + lda #1 ; Set the isesc flag to true. + pha ; + and #0 ; Make delmcpy use isdelm. jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter. + pla ; + lda #TOK_SQUOT ; Set the lexeme type to TOK_SQUOT. + sta lex_type ; + sta t_id ; Also set the token ID to TOK_SQUOT. + lda.d ptr3 ; Get the address of the lexeme buffer. + sta.q t_str ; Save it in the token string. @end: + jsr make_tok ; Create the token. rts ; End of parse_ptok. ptok_hash: inc.w idx0 ; @@ -215,33 +284,49 @@ ptok_scol: ldb #1 ; Make init_lex increment the string index. jsr init_lex ; Initialize the lexeme buffer for copying. ldb #1 ; Set the delimiter to EOL. + lda #0 ; Set the isesc flag to false. + pha ; jsr delmcpy ; Copy the string, to the lexeme buffer, until EOL. + pla ; + lda #TOK_SCOLN ; Set the lexeme type to TOK_SCOLN. + sta lex_type ; + sta t_id ; Also set the token ID to TOK_SCOLN. + lda.d ptr3 ; Get the address of the lexeme buffer. + sta.q t_str ; Save it in the token string. @end: + jsr make_tok ; Create the token. rts ; End of parse_ptok. ptok_dolr: lda #TOK_HEX ; Set the lexeme type to TOK_HEX. sta lex_type ; + sta t_id ; Also set the token ID to TOK_HEX. lda #$10 ; Set the base to Hexadecimal. ldb #1 ; Make init_lex increment the string index. bra ptok_num2 ; Parse the value. ptok_prcn: lda #TOK_BIN ; Set the lexeme type to TOK_BIN. sta lex_type ; + sta t_id ; Also set the token ID to TOK_BIN. lda #2 ; Set the base to Binary. ldb #1 ; Make init_lex increment the string index. bra ptok_num2 ; Parse the value. ptok_num: lda #TOK_DEC ; Set the lexeme type to TOK_DEC. sta lex_type ; + sta t_id ; Also set the token ID to TOK_DEC. lda #10 ; Set the base to Decimal. ldb #0 ; Do not let init_lex increment the string index. ptok_num2: pha ; Preserve the base. jsr init_lex ; Initialize the lexeme buffer for copying. ldb #3 ; Set the delimiter to both the EOL, and a comma. + lda #0 ; Set the isesc flag to false. + pha ; jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter. + pla ; pla ; Get the base back. jsr strtoullg ; Convert the string into a numeric value. + sta.q t_val ; Set the token value to the converted value. jsr make_tok ; Create the token. jsr set_cmdbuf ; Set the first pointer to the command buffer. rts ; End of parse_ptok. @@ -249,17 +334,21 @@ ptok_alph: ldb #0 ; Do not let init_lex increment the string index. jsr init_lex ; Initialize the lexeme buffer for copying. ldb #3 ; Stop at any possible delimiter. + lda #0 ; Set the isesc flag to false. + pha ; tba ; Use isdelm2 for the comparison. jsr delmcpy ; Copy the string, to the lexeme buffer, until delimiter. + pla ; lda #0 ; Reset A. sta regb ; Clear the isop flag. @isop: ldb #0 ; Make the lexeme buffer, the first pointer. stb.q idx1 ; Reset the second index. + stb.q idx2 ; Reset the third index. jsr set_lexptr ; Set up the lexeme buffer. @isop_loop: ldb idx1 ; Get the instruction ID. - cpb #OPNUM-1 ; Have we reached the end of the mnemonic table? + cpb #OPNUM ; Have we reached the end of the mnemonic table? beq @end ; Yes, so we're done. lda.w #mne ; No, so get the start of the mnemonic table. clc ; Prepare for a non carrying add. @@ -268,7 +357,6 @@ ptok_alph: jsr strcaseg ; Is the lexeme buffer, the same as the mnemonic string? pla.q ; Get the mnemonic string pointer back. beq @found ; Yes, so create a new token. - beq @end ; Yes, so we're done. inc idx1 ; No, so increment the instruction ID. @offset: jsr strlen ; Get the string's length. @@ -280,6 +368,11 @@ ptok_alph: @found: lda #TOK_MNE ; Set the lexeme type to TOK_MNE. sta lex_type ; + sta t_id ; Also set the token ID to TOK_MNE. + lda.q idx1 ; Get the instruction ID. + sta.q t_val ; Set the token value to the instruction ID. + lda #$FF ; Set the token type to -1. + sta t_type ; inc regb ; Set the isop flag. @end: jsr make_tok ; Create the token. @@ -333,79 +426,96 @@ init_lex: delmcpy: - sta rega ; Save the delimiter check flag. - stb regc ; Save the delimiter comparison value. + pha ; Save the delimiter check flag. + phb ; Save the delimiter comparison value. + and #0 ; Reset A. + pha ; Reset the isesc flag. +; sta rega ; Save the delimiter check flag. +; stb regc ; Save the delimiter comparison value. @loop: - ldb #0 ; Reset the B register. - stb regg ; Reset the byte count. ldy.w idx0 ; Get the string index. - lda.q (ptr), y ; Get eight bytes from the current line. -@loop1: - pha.q ; Save the string buffer. - and #$FF ; Get the current byte. + lda (ptr), y ; Get a character from the line. pha ; Preserve the character. - lda rega ; Are we calling isdelm2? - pla ; Get the character back. + lda sp+4 ; Are we calling isdelm2? + pla ; Get the character back. bne @isdelm2 ; Yes, so use isdelm2. jsr isdelm ; No, so get the delimiter value from isdelm. @delmchk: - and regc ; Are both delimiter values, the same? - pla.q ; Get back the string buffer. - bne @end ; Yes, so we're done. - bra @copy ; No, so start copying the character. + and sp+2 ; Are both delimiter values, the same? + beq @copy ; No, so copy the character. +@isesc: + lda sp+1 ; Was the isesc flag true? + beq @end ; No, so we're done. + bra @copy ; Yes, so copy the character. @isdelm2: jsr isdelm2 ; Get the delimiter value from isdelm2. bra @delmchk ; Check the delimiter. @copy: + lda sp+12 ; Was the do_isesc flag set? + bne @do_isesc ; Yes, so set the isesc flag. +@copy1: + lda (ptr), y ; Get a character from the line. ldy.w idx1 ; Get the lexeme index. - sta (ptr3), y ; Copy one byte from the screen buffer, to the command buffer. + sta (ptr3), y ; Copy the character to the lexeme buffer. inc.w idx0 ; Increment the string index. inc.w idx1 ; Increment the lexeme index. - lsr #8 ; Shift in the next byte. - inc regg ; Increment the byte count. - ldb regg ; Get back the byte count. - cpb #7 ; Did we shift in eight bytes? - beq @loop ; Yes, so get eight more bytes. - bra @loop1 ; No, so keep shifting in more bytes. + bra @loop ; Keep looping. +@do_isesc: + jsr isesc ; Check if this is an escaped character. + sta sp+1 ; Save it in the isesc flag. + bra @copy1 ; Copy the character. @end: - ldb #0 ; Reset B. + pla.w ; Pull both arguments off the stack. + pla ; Pull the isesc flag off the stack. + and #0 ; Reset A. ldy.w idx1 ; Get the lexeme index. - stb (ptr3), y ; Terminate the command buffer. -@end1: + sta (ptr3), y ; Terminate the lexeme buffer. ldy.w idx0 ; Get the string index. - tba ; Reset A. rts ; End of delmcpy. ;@loop: +; ldb #0 ; Reset the B register. +; stb regg ; Reset the byte count. ; ldy.w idx0 ; Get the string index. -; lda (ptr), y ; Get a character from the line. +; lda.q (ptr), y ; Get eight bytes from the current line. +;@loop1: +; pha.q ; Save the string buffer. +; and #$FF ; Get the current byte. ; pha ; Preserve the character. ; lda rega ; Are we calling isdelm2? -; pla ; Get the character back. +; pla ; Get the character back. ; bne @isdelm2 ; Yes, so use isdelm2. ; jsr isdelm ; No, so get the delimiter value from isdelm. ;@delmchk: ; and regc ; Are both delimiter values, the same? +; pla.q ; Get back the string buffer. ; bne @end ; Yes, so we're done. ; bra @copy ; No, so start copying the character. ;@isdelm2: ; jsr isdelm2 ; Get the delimiter value from isdelm2. ; bra @delmchk ; Check the delimiter. ;@copy: -; lda (ptr), y ; Get a character from the line. ; ldy.w idx1 ; Get the lexeme index. -; sta (ptr3), y ; Copy the character to the lexeme buffer. +; sta (ptr3), y ; Copy one byte from the screen buffer, to the command buffer. ; inc.w idx0 ; Increment the string index. ; inc.w idx1 ; Increment the lexeme index. -; bra @loop ; Keep looping. +; lsr #8 ; Shift in the next byte. +; inc regg ; Increment the byte count. +; ldb regg ; Get back the byte count. +; cpb #7 ; Did we shift in eight bytes? +; beq @loop ; Yes, so get eight more bytes. +; bra @loop1 ; No, so keep shifting in more bytes. ;@end: +; ldb #0 ; Reset B. ; ldy.w idx1 ; Get the lexeme index. -; lda #0 ; Terminate the lexeme buffer. -; sta (ptr3), y ; +; stb (ptr3), y ; Terminate the command buffer. +;@end1: ; ldy.w idx0 ; Get the string index. +; tba ; Reset A. ; rts ; End of delmcpy. + get_rs: phb ; Preserve B. ldb #0 ; Set the isop flag to false. diff --git a/programs/sub-suite/subeditor.s b/programs/sub-suite/subeditor.s index e624990..aec613e 100644 --- a/programs/sub-suite/subeditor.s +++ b/programs/sub-suite/subeditor.s @@ -129,7 +129,9 @@ print_str: tay ; Save it in Y. tba ; Get the character back. inx ; Increment the string index. + phx ; Preserve the string index. jsr print_char ; Print the character. + plx ; Get the string index back. bra @loop ; Keep looping. @end: ldb #0 ; Enable insert mode. @@ -365,29 +367,23 @@ findend: print_char: - sta rega ; Save the typed character for now. + sta rega ; Preserve the character. ldb #2 ; Make sure that set_ptr sets the third pointer. lda.d #buffer ; Set the third pointer to the start of the screen buffer. jsr set_ptr ; - ldb #0 ; Set B to zero. - tba ; Set the Accumulator to zero. - lda rega ; Get back the character. - cmp #$1B ; Did the user type an escape character? - beq esc ; Yes, so go check the escape code. - cmp #'\n' ; No, but did the user type a newline? - beq nl ; Yes, so handle the newline. - cmp #$C ; No, but did the user type Ctrl+L? - beq clr_scr ; Yes, so clear the screen. - cmp #19 ; No, but did the user type Ctrl+S? - beq en_step ; Yes, so enable clock/instruction stepping. - cmp #18 ; No, but did the user type Ctrl+R? - beq dis_step ; Yes, so disable clock/instruction stepping. - cmp #'\b' ; No, but did the user type a backspace? - beq bs ; Yes, so handle the backspace. - cmp #$7F ; No, but did they type Delete? - beq bs ; Yes, so treat it as a backspace. + deb ; Set B to one. + tba ; Reset A. + lda rega ; Get the character back. + jsr get_ctrlidx ; Get the control code jump table index. + lsl #1 ; Multiply the return value by two, to get the index. + tax ; + lda.w ct_jtb, x ; Get the address of the control code handler. + jsr set_ptr ; Set the second pointer to the control code handler. + deb ; Reset B. + tba ; Reset A. + jmp (ptr2) ; Jump to the handler for that control code. printc: - lda #0 ; No, so start trying to print a character. + lda #0 ; start trying to print a character. sta regd ; lda (ptr3), y ; Are we at the end of the string? beq @save ; Yes, so just print the character. @@ -402,9 +398,6 @@ printc: @update1: jsr findend ; Find the end of the line. sta rege ; Use it for redrawing the line. -; sta scr_row ; Set the row position to to the end of the line. -; jsr findst ; Find the start of the line. -; lda scr_row ; Get the start of the line. lda scr_trow ; Get the current row position. @update2: sta regf ; Set the starting line, to the current row position. diff --git a/programs/sub-suite/subsuite.s b/programs/sub-suite/subsuite.s index d425550..d28b4f2 100644 --- a/programs/sub-suite/subsuite.s +++ b/programs/sub-suite/subsuite.s @@ -2,7 +2,6 @@ ; Include Declarations. .include "declare.s" - ; Include SuBEditor. .include "subeditor.s" ; Include SuBAsm. diff --git a/programs/sub-suite/utils.s b/programs/sub-suite/utils.s index 3ab948b..7e7469c 100644 --- a/programs/sub-suite/utils.s +++ b/programs/sub-suite/utils.s @@ -3,8 +3,9 @@ print_hi: and #0 ; Reset A. sta idx3 ; Clear the string index. + tax ; Reset X. lda #'$' ; Print the hex delimiter. - jsr charcpy ; + sta strbuf, x ; Save it in the string buffer. lda.q idx0 ; Get the masked address. ldx #$10 ; Set digit count to 16. jsr print_hex ; Print the address. @@ -14,23 +15,27 @@ print_hi: sta.q strbuf+9 ; Save it in the string buffer. ldx #$11 ; Add 16 to the index. stx idx3 ; - lda #':' ; Print a colon. - jsr charcpy ; - lda # ' ' ; Print a space. - jsr charcpy ; + lda.w #': ' ; Print a space. + sta.w strbuf, x ; Save it in the string buffer. + inc idx3 ; Increment the string index twice. + inc idx3 ; + and #0 ; Reset A. rts ; End of print_hi. + print_lo: - lda #0 ; Reset A. + and #0 ; Reset A. sta idx3 ; Clear the string index. @loop: ldx #2 ; Set digit count to 2. pha ; Preserve the nibble offset. jsr print_hex ; Print the low nibble offset. lda.w (ptr3) ; Get the two digits. - jsr charcpy ; Copy the first digit. - lsr #8 ; Copy the next digit. - jsr charcpy ; + ldx idx3 ; Get the string index. + sta.w strbuf, x ; Save it in the string buffer. + inc idx3 ; Increment the string index twice. + inc idx3 ; + ldx idx3 ; Get the string index. pla ; Get the nibble offset back. inc ; Increment the offset. cmp #$10 ; Are we at the last offset? @@ -38,11 +43,11 @@ print_lo: @loop1: pha ; No, so preserve the nibble offset. lda #' ' ; Add a space to the string buffer. - jsr charcpy ; + sta strbuf, x ; Save it in the string buffer. + inc idx3 ; Increment the string index. pla ; Get the nibble offset back. bra @loop ; Keep looping. @end: - inx ; Increment the index by one. lda #0 ; Null terminate the string buffer. sta strbuf, x ; tax ; Reset X. @@ -50,6 +55,7 @@ print_lo: jsr print_str ; rts ; End of print_lo. + print_chunk: ldx #0 ; Reset X. phy.w ; Preserve the screen buffer index. @@ -60,14 +66,17 @@ print_chunk: lda (idx0), y ; Get the byte at that address. jsr print_hex ; Print the byte. lda.w (ptr3) ; Get the two digits. - jsr charcpy ; Copy the first digit. - lsr #8 ; Copy the next digit. - jsr charcpy ; + ldx idx3 ; Get the string index. + sta.w strbuf, x ; Save it in the string buffer. + inc idx3 ; Increment the string index twice. + inc idx3 ; + ldx idx3 ; Get the string index. iny ; Increment the byte index. cpy #$10 ; Have we read 16 bytes? beq @end ; Yes, so we're done. lda #' ' ; No, so add a soace to the string buffer. - jsr charcpy ; + sta strbuf, x ; Save it in the string buffer. + inc idx3 ; Increment the string index. bra @loop ; Keep looping. @end: ply.w ; Get the screen buffer index back. @@ -202,7 +211,6 @@ isdelm2: isdelm: ldx #0 ; Reset X. - stx rega ; Reset the shift value. @loop: ldb dtab, x ; Get the compare value. beq @other ; We hit the end of the table, so check for the others. @@ -222,13 +230,47 @@ isdelm: lda #0 ; Return 0. rts ; End of isdelm. @rshft: - stx rega ; Save the shift value. - ldx #0 ; Reset X. lda #1 ; Set up the bitshift. - lsl rega ; Return 1 << X. + phx ; Push the shift value to stack. + lsl sp+1 ; Return 1 << X. + plx ; Pull the shift value off the stack. + ldx #0 ; Reset X. rts ; End of isdelm. +isesc: + ldy.w idx0 ; Get the string index. + lda (ptr), y ; Get the current character. + cmp #'\\' ; Is it a backslash? + bne @false ; No, so return false. +@dec: + dey ; Decrement the string index. + lda (ptr), y ; Get the current character. + iny ; Set the string index back. + cmp #'\\' ; Is it a backslash? + beq @false ; Yes, so return false. + lda #1 ; No, so return true. + rts ; End of isesc. +@false: + and #0 ; Return false. + rts ; End of isesc. + + +is_altok: + sec ; Do a non borrowing subtract. + sbc #12 ; Subtract 12 from the token. + and #$FF ; Make sure the value is 8 bits. + cmp #4 ; Is the token in between PTOK_B, and PTOK_P? + bcc @r1 ; Yes, so return 1. + beq @r1 ; +@r0: + lda #0 ; Return 0. + rts ; End of is_altok. +@r1: + lda #1 ; Return 1. + rts ; End of is_altok. + + get_ptok: ldx #0 ; Reset X. jsr tolower ; Conver the character to lowercase. @@ -257,3 +299,22 @@ get_ptok: @ralph: lda #PTOK_ALPH ; Return PTOK_ALPH. rts ; End of get_ptok. + + +get_ctrlidx: + cmp #$7F ; Is this a delete character? + beq @del ; Yes, so return the same value as backspace. + sec ; Do a non borrowing subtract. + sbc #8 ; Subtract 8 from the character, to get the index. + tax ; Copy the index to X. + and #0 ; Reset A. + cpx #19 ; Are we less than, or equal to the max size of the table? + bcc @get_rtval ; Yes, so get the return value from the table. + beq @get_rtval ; + rts ; End of get_ctrlidx. +@get_rtval: + lda ct_rtb, x ; Get the return value from the table. + rts ; End of get_ctrlidx. +@del: + lda #2 ; Return 2. + rts ; End of get_ctrlidx. -- cgit v1.2.3-13-gbd6f