From 31cf42167fd52c8a66cead7ce3ee51c8c25d17a2 Mon Sep 17 00:00:00 2001 From: Gale Faraday Date: Sat, 11 Oct 2025 17:30:30 -0500 Subject: [PATCH] feat(buzbee): hexadecimal to byte conversion routine and skip-whitespace routine for tokenizer --- src/buzbee.s | 170 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 108 insertions(+), 62 deletions(-) diff --git a/src/buzbee.s b/src/buzbee.s index 5bfe2df..7967feb 100644 --- a/src/buzbee.s +++ b/src/buzbee.s @@ -13,15 +13,17 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -BBIN_DEPTH EQU $7F -BBTOKENS_DEPTH EQU $3F +BBIN_DEPTH EQU $80 ; Input buffer depth +BBTOKENS_DEPTH EQU $40 ; Token buffer depth SECTION BBVARS,bss tagbbvar STRUCT input rmb BBIN_DEPTH ; Input buffer +cchinput rmd 1 ; Input buffer char count tokens rmb BBTOKENS_DEPTH ; Token buffer -cbtokens rmb 2 +cbtokens rmd 1 ; Token buffer byte count +scratch rmd 1 ; Scratch word ENDSTRUCT ORG $0200 @@ -38,10 +40,10 @@ BBVAR tagbbvar EXPORT BUZBEE BUZBEE - bsr NEWLINE ; Setup the new input line and handle display. - bsr INPLOOP ; Fill input buffer. - cmpy #$0000 ; No data? - beq BUZBEE ; Try again... + lbsr NEWLINE ; Setup the new input line and handle display. + bsr INPLOOP ; Fill input buffer. + cmpy #$0000 ; No data? + beq BUZBEE ; Try again... ; TODO: Parse the input buffer into tokens lbsr RUNIF bra BUZBEE @@ -52,20 +54,6 @@ BUZBEE ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Handle new lines; prints a new prompt and then clears the input buffer -NEWLINE - PZSTR PROMPTLINE ; Print prompt line -CLRIN ; Label to just clear input buffer without newline - clra ; Init A and X - ldx #$0000 -NEXT@ - sta BBVAR.input,x ; Clear input buffer - leax 1,x - cmpx #BBIN_DEPTH - blo NEXT@ - ldy #$0000 ; Reset buffer fill pointer - rts - ; Fills input buffer with characters from the serial console. Sets Y to the ; offset in the input buffer of the last char read. INPLOOP @@ -79,13 +67,14 @@ INPLOOP cmpa #$08 ; BS? beq HBACKSPC@ ; Backup a char cmpa #$0D ; CR? - beq EXIT@ ; Then parse input buffer + beq HCR@ ; Then terminate and parse input buffer cmpy #BBIN_DEPTH ; Are we at the end of the input buffer? beq FULLBUF@ ; Handle the buffer being full ECHO@ jsr POUTCHAR ; Echo char back, this includes BS chars sta BBVAR.input,y ; Add it to the input buffer leay 1,y + ; Fall through NOCHAR@ ; Check for error condition, work based on The Serial Port release 19 bitb #(UARTF_LSR_FIFO|UARTF_LSR_BI|UARTF_LSR_FE|UARTF_LSR_PE|UARTF_LSR_OE) @@ -103,10 +92,11 @@ NOPARITY@ PZSTR EM_FRAMING NOFRAM@ bitb #UARTF_LSR_FIFO ; Check for FIFO error - beq INPLOOP + beq INPLOOP ; Loop over PZSTR EM_FIFO - bra INPLOOP -EXIT@ + bra INPLOOP ; Loop over +HCR@ + sty BBVAR.cchinput ; Store buffer length rts HESC@ lda #'^ ; Print a char that signifies that ESC was pressed @@ -121,7 +111,21 @@ HBACKSPC@ FULLBUF@ lda #$07 ; ASCII BEL jsr POUTCHAR - bra INPLOOP + lbra INPLOOP + +; Handle new lines; prints a new prompt and then clears the input buffer +NEWLINE + PZSTR PROMPTLINE ; Print prompt line +CLRIN ; Label to just clear input buffer without newline + clra ; Init A and X + ldx #$0000 +NEXT@ + sta BBVAR.input,x ; Clear input buffer + leax 1,x + cmpx #BBIN_DEPTH + blo NEXT@ + ldy #$0000 ; Reset buffer fill pointer + rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -130,7 +134,7 @@ FULLBUF@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Prints a byte in A -; @param a: byte to print +; @param A: byte to print PBYTE pshs b tfr a,b ; Transfer lower nybble into B @@ -148,24 +152,58 @@ PBYTE rts ; Converts a nybble into a valid hex digit -; @param a: nybble to convert to a char -; @return a: resulting char +; @param A: nybble to convert to a char +; @return A: resulting char NYB2HEX anda #$0F ora #'0 ; Add "0" cmpa #$3A ; ":" "9"+1 - bcc SKIP@ + blo SKIP@ adca #6 ; Add offset to "A" in ascii SKIP@ rts +; Converts a hexadecimal sequence into a byte value +; @param D: hex representation of a byte with A: MSD B: LSD +; @return A: returned byte value +; NOTE: Conversion logic credit to Wozniak. This code unrolled for speed. +HEX2BYT + eora #$B0 ; Map digits to 0-9 + cmpa #9+1 ; Is it a decimal? + blo AISDEC@ ; Yes? skip hex adjust + adca #$88 ; Map 'A'-'F' to $FA-$FF + cmpa #$FA ; Hex char? + blo BADHEX@ ; No? Print error +AISDEC@ + asla ; Shift MSD into upper nybble of A + asla + asla + asla +; Do B part + eorb #$B0 ; Map digits to 0-9 + cmpa #9+1 ; Is it a decimal? + blo BISDEC@ ; Yes? skip hex adjust + adcb #$88 ; Map 'A'-'F' to $FA-$FF + andb #$0F ; Mask high nybble + cmpb #$0A ; Hex char? + blo BADHEX@ ; No? Print error +BISDEC@ + stb BBVAR.scratch ; Store low nybble in scratch buffer + ora BBVAR.scratch ; Combine the nybbles + rts +BADHEX@ + PZSTR EM_BADHEX ; Print an error message + clrd ; Prevent RUNIF from executing + std BBVAR.cbtokens + rts + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; BUZBEE Tokenizing Routines ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Makes a hash of four chars in BBIN starting at offset X. +; Makes a hash of four chars in BBIN starting at offset X ; @param X: offset in BBIN to read the four chars from ; @return A: resulting hash MKCMDSUM @@ -180,6 +218,18 @@ NEXTC@ bne NEXTC@ ; No? loop rts +; Skips "whitespace" to the next semantic char +; @param Y: current index in text buffer +; @return Y: resulting index in text buffer +SKIPTONEXTC + lda BBVAR.input,y ; Get our char? + cmpa #$20 ; SPACE or control char? + bhi EXIT@ ; Yes? End + leay 1,y ; Iterate next char + bra SKIPTONEXTC +EXIT@ + rts + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; BUZBEE IF Handling Functions @@ -190,6 +240,9 @@ NEXTC@ ; @corrupts B ; @return X: command data table index RUNIF + clrd ; Do we have any tokens? + cmpd BBVAR.cbtokens + beq NOTOK@ ldx #0 ; Counting up from zero lda BBVAR.tokens ; Load token NEXTHASH@ @@ -198,13 +251,15 @@ NEXTHASH@ leax 1,x ; Begin considering next hash cmpx BBCHTC ; Is this the last byte? blo NEXTHASH@ ; No? try next hash, Yes? fall through - PZSTR EM_BADCMD ; Print an error message + PZSTR EM_BADHASH ; Print an error message lbra IFHELP ; Proceed to call "HELP" CALCPTR@ tfr x,d ; Swap into d to do a cheap multiply asld ; Cheaply << to get *2, pointer size tfr d,x ; Restore x from d and jump to function at index jmp [BBCMDPTRTBL,x] +NOTOK@ + rts ; IF pointer table BBCMDPTRTBL @@ -238,40 +293,25 @@ IFPEEK ldd BBVAR.cbtokens ; One 16-bit token given, single peek cmpd #3 lblo INVALIDARG ; Not enough args given - bhi SELFORBAC@ ; Select forward or backward peek + bhi SELTYPE@ ; Select forward or backward peek SINGLE@ lda [BBVAR.tokens+1] ; Get byte lbsr PBYTE ; Print peek byte rts -SELFORBAC@ +SELTYPE@ ldd BBVAR.cbtokens ; Have enough tokens? cmpd #5 lbne INVALIDARG ; No? bounce out ldd BBVAR.tokens+1 ; Are we forwards (BASE < HIGH)? cmpd BBVAR.tokens+3 beq SINGLE@ ; Gracefully handle BASE == HIGH - blo PEEKFWD - bhi PEEKBACK - -; Peek forward -PEEKFWD - ldx BBVAR.tokens+1 ; Get BASE -NEXT@ - lda ,x+ ; Get the next byte - lbsr PBYTE ; Print our byte - cmpx BBVAR.tokens+3 ; Are we at yet? - bne NEXT@ ; No? loop - rts - -; Peek backwards -PEEKBACK + bhi INVALIDARG ; Malformed if BASE > HIGH ldx BBVAR.tokens+1 ; Get BASE -PREV@ - lda 0,x ; Get current byte - leax -1,x ; Prep for next byte +NEXT@ + lda ,x+ ; Get the next byte lbsr PBYTE ; Print our byte cmpx BBVAR.tokens+3 ; Are we at yet? - bne PREV@ ; No? loop + bne NEXT@ ; No? loop rts ; Poke bytes into memory @@ -297,12 +337,12 @@ IFSREC ; Invalid argument IF tail INVALIDARG - PZSTR EM_MISSINGARG + PZSTR EM_BADARG rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; BUZBEE Strings and Tables +;; BUZBEE Strings and Fixed Data ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -327,20 +367,26 @@ PROMPTLINE fcb $0D,$0A,$25,$00 ; CR LF '%' NUL EM_OVERRUN - fcc "!!! Overrun Error !!!" + fcc "!!! UART Overrun Error !!!" fcb $0D,$0A,$00 EM_PARITY - fcc "!!! Parity Error !!!" + fcc "!!! UART Parity Error !!!" fcb $0D,$0A,$00 EM_FRAMING - fcc "!!! Framing Error !!!" + fcc "!!! UART Framing Error !!!" fcb $0D,$0A,$00 EM_FIFO - fcc "!!! FIFO Error !!!" + fcc "!!! UART FIFO Error !!!" fcb $0D,$0A,$00 -EM_BADCMD +EM_BADHASH fcc "!!! Bad Command Hash !!!" fcb $0D,$0A,$00 -EM_MISSINGARG - fcc "!!! Missing Arguments !!!" +EM_BADARG + fcc "!!! Malformed Arguments !!!" + fcb $0D,$0A,$00 +EM_TOKFAIL + fcc "!!! Tokenization Failure !!!" + fcb $0D,$0A,$00 +EM_BADHEX + fcc "!!! Maleformed Hex Value !!!" fcb $0D,$0A,$00