adapted to Kick Assembler, some documentation update
This commit is contained in:
1 parent
ae23dbae7b
commit
de27124b4f
198 files changed
+4181
-3976
No files matched your search
+88
-87
@@ -1,76 +1,77 @@
|
||||
;; Pack a word using the simple compression scheme.
|
||||
;; This has to be the same implementation as in compress_text.c
|
||||
;; because we compress input lines of BASIC to do the tokenisation.
|
||||
;; This allows us to search through the compressed tokens directly
|
||||
;; using the compressed fragment of BASIC, and thus work out the
|
||||
;; token for a given piece of string.
|
||||
;; This also helps ensure that we have an implementation that is totally
|
||||
;; different to that of the original C64 BASIC, as well as likely
|
||||
;; saving a bit of space in the ROM, especially once we start implementing
|
||||
;; larger keyword vocabs for BASIC 7 or BASIC 10 compatibility, since the
|
||||
;; compression and decompression machinery is of fixed size.
|
||||
// Pack a word using the simple compression scheme.
|
||||
// This has to be the same implementation as in compress_text.c
|
||||
// because we compress input lines of BASIC to do the tokenisation.
|
||||
// This allows us to search through the compressed tokens directly
|
||||
// using the compressed fragment of BASIC, and thus work out the
|
||||
// token for a given piece of string.
|
||||
// This also helps ensure that we have an implementation that is totally
|
||||
// different to that of the original C64 BASIC, as well as likely
|
||||
// saving a bit of space in the ROM, especially once we start implementing
|
||||
// larger keyword vocabs for BASIC 7 or BASIC 10 compatibility, since the
|
||||
// compression and decompression machinery is of fixed size.
|
||||
|
||||
pack_word:
|
||||
;; Inputs:
|
||||
;; X = offset of string to pack. Address is $0200 + X
|
||||
;; tokenise_work1 = number of bytes to pack
|
||||
;; tokenise_work2 = packed length of string
|
||||
// Inputs:
|
||||
// X = offset of string to pack. Address is $0200 + X
|
||||
// tokenise_work1 = number of bytes to pack
|
||||
// tokenise_work2 = packed length of string
|
||||
|
||||
;; Outputs:
|
||||
;; Output is written to $0100 (bottom of stack).
|
||||
// Outputs:
|
||||
// Output is written to $0100 (bottom of stack).
|
||||
|
||||
;; Memory modified:
|
||||
;; tokenise_work4 = temporary storage
|
||||
;; tokenise_work3 = flag for whether we have a nybl prepared or not.
|
||||
;; (This can also be checked on exit, to know whether the last byte
|
||||
;; is incomplete, which is important for searching for abbreviated
|
||||
;; key words.)
|
||||
// Memory modified:
|
||||
// tokenise_work4 = temporary storage
|
||||
// tokenise_work3 = flag for whether we have a nybl prepared or not.
|
||||
// (This can also be checked on exit, to know whether the last byte
|
||||
// is incomplete, which is important for searching for abbreviated
|
||||
// key words.)
|
||||
|
||||
|
||||
;; Make sure we have a sane request
|
||||
// Make sure we have a sane request
|
||||
lda tokenise_work1
|
||||
bne +
|
||||
bne !+
|
||||
sec
|
||||
rts
|
||||
*
|
||||
;; Initialise internal variables
|
||||
!:
|
||||
// Initialise internal variables
|
||||
lda #$00
|
||||
sta tokenise_work2
|
||||
sta tokenise_work3
|
||||
|
||||
pack_char_loop:
|
||||
|
||||
;; Get the next char
|
||||
// Get the next char
|
||||
lda $0200,x
|
||||
|
||||
;; Work out what type of character we have, and thus
|
||||
;; how we need to pack it.
|
||||
// Work out what type of character we have, and thus
|
||||
// how we need to pack it.
|
||||
jsr get_packed_char_index
|
||||
|
||||
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
|
||||
// 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
|
||||
// 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
|
||||
lda tokenise_work1
|
||||
cmp #$01
|
||||
beq at_end
|
||||
lda #$FF
|
||||
.byte $2C
|
||||
at_end: LDA #$FE
|
||||
at_end:
|
||||
lda #$FE
|
||||
dex
|
||||
jsr write_unpacked_char
|
||||
;; Fall through
|
||||
// Fall through
|
||||
|
||||
output_exception_byte:
|
||||
lda $0200,x
|
||||
@@ -78,18 +79,18 @@ output_exception_byte:
|
||||
jmp consider_next_char
|
||||
|
||||
have_nybl_before_exception_char:
|
||||
;; Or existing byte with #$0F, and clear nybl flag
|
||||
// Or existing byte with #$0F, and clear nybl flag
|
||||
ldy tokenise_work2
|
||||
lda $0100,y
|
||||
ora #$0f
|
||||
sta $0100,y
|
||||
inc tokenise_work2
|
||||
|
||||
;; FALL THROUGH
|
||||
// FALL THROUGH
|
||||
|
||||
write_literal_and_terminate_if_required:
|
||||
|
||||
;; Clear have nybl flag
|
||||
// Clear have nybl flag
|
||||
lda #$00
|
||||
sta tokenise_work3
|
||||
|
||||
@@ -99,19 +100,19 @@ write_literal_and_terminate_if_required:
|
||||
jmp end_string_if_required
|
||||
|
||||
end_string_if_required:
|
||||
;; Check if X points to last char of string to be packed
|
||||
// Check if X points to last char of string to be packed
|
||||
inx
|
||||
lda tokenise_work1
|
||||
cmp #$01
|
||||
beq +
|
||||
beq !+
|
||||
dex
|
||||
jmp consider_next_char
|
||||
*
|
||||
!:
|
||||
dex
|
||||
;; Fall through
|
||||
// Fall through
|
||||
|
||||
end_string:
|
||||
;; Write end of string sequence if required
|
||||
// Write end of string sequence if required
|
||||
lda #$00
|
||||
jsr write_unpacked_char
|
||||
rts
|
||||
@@ -124,53 +125,53 @@ write_unpacked_char:
|
||||
rts
|
||||
|
||||
not_exception_char:
|
||||
;; It wasn't an exception char, so write the symbol out
|
||||
// It wasn't an exception char, so write the symbol out
|
||||
cmp #$10
|
||||
bcs whole_byte_symbol
|
||||
|
||||
;; Nybl encoded value: Put in upper half or lower half of a byte?
|
||||
// Nybl encoded value: Put in upper half or lower half of a byte?
|
||||
ldy tokenise_work3
|
||||
bne store_low_nybl
|
||||
|
||||
;; Store in high nybl -- so shift it into the hi 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
|
||||
bne stored_nybl // Must be taken, as A cannot be $00
|
||||
|
||||
store_low_nybl:
|
||||
;; Low nybl gets added to high nybl already stored in the byte
|
||||
// Low nybl gets added to high nybl already stored in the byte
|
||||
ldy tokenise_work2
|
||||
ora $0100,y
|
||||
sta $0100,y
|
||||
|
||||
stored_nybl:
|
||||
;; Now toggle the nybl flag
|
||||
// Now toggle the nybl flag
|
||||
lda tokenise_work3
|
||||
eor #$ff
|
||||
sta tokenise_work3
|
||||
;; And advance the offset if we filled this byte up
|
||||
bne consider_next_char ; Taken if byte has a nybl free, i.e., don't advance pointer while half byte remains free
|
||||
// And advance the offset if we filled this byte up
|
||||
bne consider_next_char // Taken if byte has a nybl free, i.e., don't advance pointer while half byte remains free
|
||||
|
||||
;; Count the filled up byte
|
||||
// Count the filled up byte
|
||||
inc tokenise_work2
|
||||
|
||||
;; Add termination byte if required
|
||||
;; (This re-writes the same byte again, which we don't care about)
|
||||
// Add termination byte if required
|
||||
// (This re-writes the same byte again, which we don't care about)
|
||||
jmp end_string_if_required
|
||||
|
||||
whole_byte_symbol:
|
||||
;; It's a $Fx symbol.
|
||||
;; But if we have a nybl to flush, then we handle it like
|
||||
;; a full exception character
|
||||
// It's a $Fx symbol.
|
||||
// But if we have a nybl to flush, then we handle it like
|
||||
// a full exception character
|
||||
|
||||
ldy tokenise_work3
|
||||
beq nothing_to_flush
|
||||
|
||||
;; Set low nybl to $F to mark next byte as literal
|
||||
// Set low nybl to $F to mark next byte as literal
|
||||
ldy tokenise_work2
|
||||
lda $0100,y
|
||||
ora #$0f
|
||||
@@ -180,30 +181,30 @@ whole_byte_symbol:
|
||||
jmp write_literal_and_terminate_if_required
|
||||
|
||||
nothing_to_flush:
|
||||
;; Write the symbol as it is, or the literal
|
||||
;; if it has been passed to us via fall-through
|
||||
// Write the symbol as it is, or the literal
|
||||
// if it has been passed to us via fall-through
|
||||
jsr write_unpacked_char
|
||||
|
||||
jmp end_string_if_required
|
||||
|
||||
consider_next_char:
|
||||
;; Pack next char
|
||||
// Pack next char
|
||||
inx
|
||||
dec tokenise_work1
|
||||
beq +
|
||||
beq !+
|
||||
jmp 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).
|
||||
!:
|
||||
// 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 +
|
||||
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)
|
||||
!:
|
||||
// Last byte was full, so we need at $00 on the end
|
||||
// (unless a $FE token was written 2 bytes ago)
|
||||
ldy tokenise_work2
|
||||
iny
|
||||
lda #$00
|
||||
@@ -213,21 +214,21 @@ consider_next_char:
|
||||
rts
|
||||
|
||||
get_packed_char_index:
|
||||
;; Find char in A in the packed char list, and return
|
||||
;; $1 - $E, $F1 - $FD if the charactar is abbreviable,
|
||||
;; or else return $00 if the character has to be stored literally.
|
||||
// Find char in A in the packed char list, and return
|
||||
// $1 - $E, $F1 - $FD if the charactar is abbreviable,
|
||||
// or else return $00 if the character has to be stored literally.
|
||||
|
||||
;; Y register and A are modified, as are processor flags.
|
||||
// Y register and A are modified, as are processor flags.
|
||||
|
||||
ldy #$00
|
||||
find_char_loop:
|
||||
cmp packed_message_chars,y
|
||||
bne not_a_match
|
||||
enumerate:
|
||||
;; Is it a nybl abbreviable char?
|
||||
// Is it a nybl abbreviable char?
|
||||
cpy #14
|
||||
bcs not_nybl_char
|
||||
;; Yes, so add 1 and return it
|
||||
// Yes, so add 1 and return it
|
||||
iny
|
||||
tya
|
||||
rts
|
||||
@@ -235,9 +236,9 @@ enumerate:
|
||||
not_nybl_char:
|
||||
cpy #27
|
||||
bcs not_a_match
|
||||
;; It's a $Fx character.
|
||||
;; Since the lowest index is $E, and it should be encoded as $F1
|
||||
;; we need to add $E3
|
||||
// It's a $Fx character.
|
||||
// Since the lowest index is $E, and it should be encoded as $F1
|
||||
// we need to add $E3
|
||||
tya
|
||||
clc
|
||||
adc #$E3
|
||||
@@ -245,10 +246,10 @@ not_nybl_char:
|
||||
|
||||
not_a_match:
|
||||
iny
|
||||
;; Loop until we find it, or we discover it isn't
|
||||
;; a character with a special encoding
|
||||
// Loop until we find it, or we discover it isn't
|
||||
// a character with a special encoding
|
||||
cpy #27
|
||||
bne find_char_loop
|
||||
;; Not a char that we can pack, so return 0
|
||||
// Not a char that we can pack, so return 0
|
||||
lda #$00
|
||||
rts
|
||||
Reference in new issue
Block a user