implement more of word packer routine

This commit is contained in:
Paul Gardner-Stephen committed 2019-04-25 18:04:08 +09:30
1 parent 0995ccc976
commit 59a5145a09
1 file changed
+125 -5
+125 -5
View File
@@ -33,16 +33,136 @@ pack_word:
pack_char_loop:
;; Get the next char
* lda $0200,x
lda $0200,x
;; Work out what type of character we have, and thus
;; how we need to pack it.
jsr get_packed_char_index
sta $0100,x
cmp #$00
bne not_exception_char
;; Char is an exception char.
;; We need to either finish the previous byte with $xF,
;; Or if there is no existing nybl, then we need to output
;; either $FE or $FF, depending on whether this is the last
;; byte or not
lda tokenise_work3
bne have_nybl_before_exception_char
;; No nybl exists before the exception char, so prefix with $FE or $FF
;; based on whether we are at the end of the input string or not
inx
cpx tokenise_work1
beq at_end
lda #$FF
at_end: .byte $2C
LDA #$FE
dex
ldy tokenise_work2
sta $0100,y
inc tokenise_work2
jmp output_exception_byte
have_nybl_before_exception_char:
;; Or existing byte with #$0F, and clear nybl flag
ldy tokenise_work2
dey
lda $0100,y
ora #$0f
sta $0100,y
;; Clear have nybl flag
lda #$00
sta tokenise_work3
;; FAll through
output_exception_byte:
ldy tokenise_work2
lda $0200,x
sta $0100,y
iny
sty tokenise_work2
jmp consider_next_char
not_exception_char:
;; It wasn't an exception char, so write the symbol out
cmp #$10
bcs whole_byte_symbol
;; Nybl value
ldy tokenise_work3
bne store_low_nybl
;; Store in high nybl -- so shift it into the hi nybl
asl
asl
asl
asl
ldy tokenise_work2
sta $0100,y
bne stored_nybl ; Must be taken, as A cannot be $00
store_low_nybl:
ldy tokenise_work2
ora $0100,y
sta $0100,y
stored_nybl:
;; Now toggle the nybl flag
lda tokenise_work3
eor #$ff
sta tokenise_work3
;; And advance the offset if required
bne consider_next_char
inc tokenise_work2
jmp consider_next_char
whole_byte_symbol:
ldy tokenise_work3
beq nothing_to_flush
;; Set low nybl to $F to mark next byte as literal
ldy tokenise_work2
lda $0100,y
ora #$0f
sta $0100,y
inc tokenise_work2
;; Clear nybl flag
lda #$00
sta tokenise_work3
;; Load literal byte for storing in output
lda $0200,x
;; FALL THROUGH
nothing_to_flush:
;; Write the symbol as it is, or the literal
;; if it has been passed to us via fall-through
ldy tokenise_work2
sta $0100,y
inc tokenise_work2
;; Fall through
consider_next_char:
;; Pack next char
inx
cpx tokenise_work1
bne -
lda tokenise_work1
sta tokenise_work2
bne pack_char_loop
;; Add 1 to length if nybl waiting to be flushed
;; (but leave flag set so the caller knows if the
;; bottom nybl might be different if the string were
;; longer).
lda tokenise_work3
beq +
inc tokenise_work2
rts
*
;; Last byte was full, so we need at $00 on the end
;; (unless a $FE token was written 2 bytes ago)
ldy tokenise_work2
lda #$00
sta $0100,y
inc tokenise_work2
rts