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
+100
-100
@@ -1,18 +1,18 @@
|
||||
;; Tokenise a line of BASIC
|
||||
;; Stored at $0200
|
||||
;; Length in tokenise_work1
|
||||
// Tokenise a line of BASIC
|
||||
// Stored at $0200
|
||||
// Length in tokenise_work1
|
||||
|
||||
tokenise_line:
|
||||
|
||||
;; We need to consider each offset in the string to see if it matches
|
||||
;; a token. No BASIC keyword is > 7 bytes, so we need to start with that
|
||||
;; length (or remaining length of string) and count our way back down.
|
||||
;; This means we need separate start and end points to keep track of.
|
||||
// We need to consider each offset in the string to see if it matches
|
||||
// a token. No BASIC keyword is > 7 bytes, so we need to start with that
|
||||
// length (or remaining length of string) and count our way back down.
|
||||
// This means we need separate start and end points to keep track of.
|
||||
|
||||
;; $0110 = offset into string
|
||||
;; $0111 = number of bytes to pack
|
||||
;; $0112 = offset into tokenised output
|
||||
;; $0113 = length of raw string
|
||||
// $0110 = offset into string
|
||||
// $0111 = number of bytes to pack
|
||||
// $0112 = offset into tokenised output
|
||||
// $0113 = length of raw string
|
||||
|
||||
lda #$00
|
||||
sta $0110
|
||||
@@ -24,56 +24,56 @@ tokenise_line:
|
||||
|
||||
tokenise_char:
|
||||
|
||||
;; Check if we have reached end of the line?
|
||||
// Check if we have reached end of the line?
|
||||
lda $0110
|
||||
cmp $0113
|
||||
bne +
|
||||
bne !+
|
||||
|
||||
;; End of line reached
|
||||
// End of line reached
|
||||
|
||||
;; Finished tokenising line
|
||||
;; Update tokenise_work1 and terminate with null
|
||||
// Finished tokenising line
|
||||
// Update tokenise_work1 and terminate with null
|
||||
ldx $0112
|
||||
lda #$00
|
||||
sta $0200,x
|
||||
stx tokenise_work1
|
||||
|
||||
;; Clear quote mode flag that is also used by KERNAL for screen display
|
||||
// Clear quote mode flag that is also used by KERNAL for screen display
|
||||
lda #$00
|
||||
sta quote_mode_flag
|
||||
rts
|
||||
*
|
||||
;; More to do
|
||||
!:
|
||||
// More to do
|
||||
|
||||
;; Maximum keyword length
|
||||
// Maximum keyword length
|
||||
lda #7
|
||||
sta $0111
|
||||
|
||||
tokenise_char_loop:
|
||||
;; Pack the word from the start (start = X, raw len = tokenise_work1)
|
||||
;; Returns packed length in tokenise_work2 and writes the packed
|
||||
;; word at $0100+
|
||||
// Pack the word from the start (start = X, raw len = tokenise_work1)
|
||||
// Returns packed length in tokenise_work2 and writes the packed
|
||||
// word at $0100+
|
||||
|
||||
ldx $0110
|
||||
lda $0200,x
|
||||
cmp #$22
|
||||
bne tk_not_quote
|
||||
|
||||
;; Quote
|
||||
// Quote
|
||||
lda quote_mode_flag
|
||||
eor #$ff
|
||||
sta quote_mode_flag
|
||||
jmp tk_literal_char
|
||||
|
||||
tk_not_quote:
|
||||
;; Check for literal characters in various ranges
|
||||
;; (This just speeds the tokeniser up, by avoiding the packed token search
|
||||
;; for such characters).
|
||||
// Check for literal characters in various ranges
|
||||
// (This just speeds the tokeniser up, by avoiding the packed token search
|
||||
// for such characters).
|
||||
|
||||
;; SPACE and punctuation before +,- and *
|
||||
// SPACE and punctuation before +,- and *
|
||||
cmp #$2a
|
||||
bcc tk_literal_char
|
||||
;; Don't try to tokenise digits
|
||||
// Don't try to tokenise digits
|
||||
cmp #$30
|
||||
bcc tk_might_be_keyword
|
||||
cmp #$3a
|
||||
@@ -81,41 +81,41 @@ tk_not_quote:
|
||||
jmp tk_literal_char
|
||||
|
||||
tk_might_be_keyword:
|
||||
;; Don't tokenise in quote mode
|
||||
// Don't tokenise in quote mode
|
||||
lda quote_mode_flag
|
||||
bne tk_literal_char
|
||||
|
||||
;; Pack string
|
||||
// Pack string
|
||||
ldx $0110
|
||||
lda $0111
|
||||
sta tokenise_work1
|
||||
|
||||
;; XXX - We should implement an optimisation where we
|
||||
;; trim the last symbol of successively, instead of re-packing the word
|
||||
;; again with one less char each time.
|
||||
;; XXX - We should limit the word length to the length of interesting chars
|
||||
;; that are available.
|
||||
// XXX - We should implement an optimisation where we
|
||||
// trim the last symbol of successively, instead of re-packing the word
|
||||
// again with one less char each time.
|
||||
// XXX - We should limit the word length to the length of interesting chars
|
||||
// that are available.
|
||||
|
||||
jsr pack_word
|
||||
lda tokenise_work2
|
||||
cmp #$10
|
||||
bcc +
|
||||
;; Packed string too long
|
||||
bcc !+
|
||||
// Packed string too long
|
||||
jmp do_STRING_TOO_LONG_error
|
||||
*
|
||||
!:
|
||||
|
||||
;; Search for it in keywords
|
||||
// Search for it in keywords
|
||||
jsr keyword_search
|
||||
|
||||
;; Did we find a keyword?
|
||||
// Did we find a keyword?
|
||||
bcc found_token_in_line
|
||||
|
||||
;; Nope, so try shorter
|
||||
// Nope, so try shorter
|
||||
dec $0111
|
||||
bne tokenise_char_loop
|
||||
|
||||
tk_literal_char:
|
||||
;; Is not a token, so copy to output verbatim
|
||||
// Is not a token, so copy to output verbatim
|
||||
ldx $0110
|
||||
ldy $0112
|
||||
lda $0200,x
|
||||
@@ -123,68 +123,68 @@ tk_literal_char:
|
||||
inc $0112
|
||||
inc $0110
|
||||
|
||||
;; Tokenise next char
|
||||
// Tokenise next char
|
||||
jmp tokenise_char
|
||||
|
||||
found_token_in_line:
|
||||
|
||||
;; Got a token, so write it out
|
||||
// Got a token, so write it out
|
||||
ldx $0112
|
||||
sta $0200,x
|
||||
inx
|
||||
stx $0112
|
||||
|
||||
;; If it is REM, then lock us in quote mode to the end of the line
|
||||
// If it is REM, then lock us in quote mode to the end of the line
|
||||
cmp #$8f
|
||||
bne not_rem
|
||||
sta quote_mode_flag
|
||||
not_rem:
|
||||
|
||||
;; Now skip over the length of the token
|
||||
// Now skip over the length of the token
|
||||
lda $0110
|
||||
clc
|
||||
adc $0111
|
||||
sta $0110
|
||||
|
||||
;; See if there is more of the line left to process
|
||||
// See if there is more of the line left to process
|
||||
jmp tokenise_char
|
||||
|
||||
|
||||
|
||||
|
||||
;; Search for word in keyword list
|
||||
;; The packed form is canonical, so we can search for the keyword while
|
||||
;; it remains compressed. This also saves a little time.
|
||||
;; Algorithm is simply to find matching first bytes, and then look for
|
||||
;; the rest being a match.
|
||||
|
||||
|
||||
// Search for word in keyword list
|
||||
// The packed form is canonical, so we can search for the keyword while
|
||||
// it remains compressed. This also saves a little time.
|
||||
// Algorithm is simply to find matching first bytes, and then look for
|
||||
// the rest being a match.
|
||||
|
||||
keyword_search:
|
||||
;; Search for the compressed keyword stored at $0100 in the list
|
||||
;; of compressed keywords
|
||||
|
||||
;; tokenise_work1 = offset in line of input
|
||||
;; tokenise_work2 = length of token we are matching
|
||||
;; tokenise_work3 = offset in token list
|
||||
;; load_or_verify_or_tokenise_work5 = temporary work space
|
||||
;; X and Y registers used as temporary space.
|
||||
;; returns C=1 if no matching token, else C=0 and A=token
|
||||
// Search for the compressed keyword stored at $0100 in the list
|
||||
// of compressed keywords
|
||||
|
||||
// tokenise_work1 = offset in line of input
|
||||
// tokenise_work2 = length of token we are matching
|
||||
// tokenise_work3 = offset in token list
|
||||
// load_or_verify_or_tokenise_work5 = temporary work space
|
||||
// X and Y registers used as temporary space.
|
||||
// returns C=1 if no matching token, else C=0 and A=token
|
||||
|
||||
lda #$00
|
||||
sta tokenise_work1
|
||||
sta tokenise_work3
|
||||
next_kw_offset:
|
||||
;; Advance offset in compressed keyword list, to see if a match
|
||||
;; BEGINS here
|
||||
// Advance offset in compressed keyword list, to see if a match
|
||||
// BEGINS here
|
||||
|
||||
;; Get count of bytes to compare
|
||||
// Get count of bytes to compare
|
||||
lda tokenise_work2
|
||||
sta load_or_verify_or_tokenise_work5
|
||||
|
||||
;; Load current position
|
||||
|
||||
// Load current position
|
||||
ldy tokenise_work3
|
||||
ldx tokenise_work1
|
||||
|
||||
;; Advance offset in compressed token list, and stop at the end
|
||||
|
||||
// Advance offset in compressed token list, and stop at the end
|
||||
inc tokenise_work3
|
||||
lda tokenise_work3
|
||||
cmp #packed_keyword_table_len
|
||||
@@ -194,76 +194,76 @@ next_in_match:
|
||||
lda $0100,x
|
||||
cmp packed_keywords,y
|
||||
bne next_kw_offset
|
||||
;; Advance to next chars in source and target
|
||||
// Advance to next chars in source and target
|
||||
inx
|
||||
iny
|
||||
|
||||
dec load_or_verify_or_tokenise_work5 ; Have we compared all bytes yet?
|
||||
dec load_or_verify_or_tokenise_work5 // Have we compared all bytes yet?
|
||||
|
||||
bne next_in_match
|
||||
|
||||
;; Keyword matches!
|
||||
// Keyword matches!
|
||||
|
||||
;; Now make sure we started on a keyword boundary
|
||||
;; (we know we finished on one, because of the structure of the compressed
|
||||
;; keyword data).
|
||||
;; Offset 0
|
||||
;; previous byte is $x0
|
||||
;; two byte prior is $FE
|
||||
// Now make sure we started on a keyword boundary
|
||||
// (we know we finished on one, because of the structure of the compressed
|
||||
// keyword data).
|
||||
// Offset 0
|
||||
// previous byte is $x0
|
||||
// two byte prior is $FE
|
||||
|
||||
;; Get offset of first byte of this token
|
||||
// Get offset of first byte of this token
|
||||
ldx tokenise_work3
|
||||
dex ; pointer points one late, so rewind it
|
||||
dex // pointer points one late, so rewind it
|
||||
|
||||
;; At start of list?
|
||||
// At start of list?
|
||||
cpx #$00
|
||||
beq word_boundary
|
||||
dex
|
||||
;; Previous byte is $x0 end token?
|
||||
// Previous byte is $x0 end token?
|
||||
lda packed_keywords,x
|
||||
and #$0f
|
||||
beq word_boundary
|
||||
dex
|
||||
;; Uber-previouss byte is $FE final literal token?
|
||||
// Uber-previouss byte is $FE final literal token?
|
||||
lda packed_keywords,x
|
||||
cmp #$fe
|
||||
beq word_boundary
|
||||
|
||||
;; Not a word boundary, so ignore
|
||||
// Not a word boundary, so ignore
|
||||
jmp next_kw_offset
|
||||
|
||||
word_boundary:
|
||||
;; Found a token whose offset is in tokenise_work3
|
||||
;; Now trace back to the start of the compressed keyword list
|
||||
;; to work out what keyword number we are, so that we can return
|
||||
;; the token number.
|
||||
// Found a token whose offset is in tokenise_work3
|
||||
// Now trace back to the start of the compressed keyword list
|
||||
// to work out what keyword number we are, so that we can return
|
||||
// the token number.
|
||||
|
||||
ldy #$80
|
||||
|
||||
token_count_loop:
|
||||
lda packed_keywords,x
|
||||
cmp #$fe
|
||||
bne +
|
||||
bne !+
|
||||
iny
|
||||
*
|
||||
!:
|
||||
and #$0f
|
||||
cmp #$00
|
||||
bne +
|
||||
bne !+
|
||||
iny
|
||||
*
|
||||
!:
|
||||
cpx #$00
|
||||
beq +
|
||||
beq !+
|
||||
dex
|
||||
jmp token_count_loop
|
||||
*
|
||||
|
||||
!:
|
||||
|
||||
tya
|
||||
clc
|
||||
rts
|
||||
|
||||
|
||||
done_searching_for_token:
|
||||
;; No token found
|
||||
// No token found
|
||||
sec
|
||||
lda #$00
|
||||
rts
|
||||
|
||||
|
||||
Reference in new issue
Block a user