;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Dictionary operations. Most of these functions are hand-compiled
;from those in jzip.
;
d_addr: defw 0 ;Address of the dictionary
toksrc: defw 0 ;Source string
tokdst: defw 0 ;Destination string
tokdct: defw 0 ;Dictionary
punct: defs 16 ;Punctuation
seps: defb 9,10,12,13,' .,?'
tokpc: defb 0 ;Punctuation count
tokcp: defw 0 ;Pointer to characters
toktp: defw 0 ;Pointer to tokens
tokmax: defb 0 ;Max tokens allowed in line
tokesz: defb 0 ;Entry size
tokdsz: defw 0 ;Dictionary size
tokchp: defw 0 ;chop
tokwi: defw 0 ;word index
tokln: defb 0 ;Token length
tokptr: defw 0 ;Token pointer
tokflg: defb 0 ;Flag
encbuf: defs 32 ;Word encoding buf
llen: defb 0 ;Length of the line
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Check if the character in C is an interpreter-defined 'separator' character
;
cksepa:
push hl
push bc
ld b,8
ld hl,seps
jr ckpn1
;
;Check if the character in C is a game-defined 'punctuation' character
;
ckpunct:
push hl
push bc
ld a,(tokpc)
or a
jr z,ckpn
ld b,a ;Count of special punctuation characters
ld hl,punct
ckpn1: ld a,(hl)
cp c
scf ;Carry set if found.
jr z,ckpn
inc hl
djnz ckpn1
xor a ;Carry reset, not found.
ckpn: pop bc
pop hl
ret
;
;next_token - based on the eponymous routine in jzip
;
;HL->string. Returns tokln = token length; tokptr -> token base
;
next_token:
;
;SET the token length to zero
;
xor a
ld (tokln),a
;
;Step through the string looking for separators
;
nt1: ld a,(llen)
or a ;End of line, reached by counting
ret z
call peek64
or a
ret z ;End of line, reached by 0-termination
ld c,a ;C = current character
;
;Look for game specific punctuation
;
call ckpunct ;Returns Carry set if C is punctuation
jr nc,nt2
;
;IF a separator is found then return the information.
;IF length has been set, then just return the word position
;
ld a,(tokln)
or a
ret nz
;
;ELSE set length and token pointer
;
inc a
ld (tokln),a
ld (tokptr),hl
inc hl
call dllen
ret
;
; Look for statically defined separators last
;
nt2: call cksepa
jr nc,nt3
;
;IF length has been set then return the word position
;
ld a,(tokln)
or a
jr z,nt99 ;<< v0.02 >> Skip it, and don't increment length
inc hl
call dllen
ret
;
;IF 1st token character then remember its position
;
nt3: ld a,(tokln)
or a
jr nz,nt4
ld (tokptr),hl
nt4: inc a
ld (tokln),a
nt99: inc hl
call dllen
jp nt1
;
;Decrement LLEN
;
dllen: push af
push hl
ld hl,llen
dec (hl)
pop hl
pop af
ret
;
;Tokenise text at Z-address HL to buffer DE. BC->dictionary
;
;Based on tokenise_line() in jzip.
;
tokenise:
ld (tokflg),a ;A = flag parameter
ld a,b
or c
jr nz,tok1
ld bc,(d_addr) ;BC = dict parameter
tok1: ld (toksrc),hl ;HL = z-address of line
ld (tokdst),de ;DE = z-address of output
ld a,255
ld (llen),a
ld a,(zver)
cp 5
jp c,tok4
inc hl
call peek64
ld (llen),a
tok4: inc hl ;HL -> words
ld (tokcp),hl
ex de,hl
call peek64
ex de,hl ;Max. tokens
ld (tokmax),a
inc de
inc de ;DE -> destination
ld (toktp),de
ld ix,0 ;IX = word count
ld h,b
ld l,c ;HL->dictionary
call peek64 ;No. of punctuation characters
push af
push hl
cp 10h
jr c,tok5
ld a,10h
tok5: ld b,a ;Punctuation count
ld (tokpc),a
inc hl
ld de,punct
tok6: call peek64 ;Read the punctuation characters
ld (de),a
inc hl
inc de
djnz tok6
xor a
ld (de),a
pop hl
pop af
inc hl
ld e,a
ld d,0
add hl,de ;HL ->entry lengtha
call peek64
ld (tokesz),a
inc hl
call peek64
ld b,a
inc hl
call peek64 ;Dictionary size
ld c,a
ld (tokdsz),bc
inc hl
ld (tokdct),hl ;Start of dictionary proper
;
;Calculate the binary chop start position
;
ld bc,(tokdsz)
srl b
rr c
ld hl,1 ;Chop value
tok7: ld a,b
or c
jr z,tok8
srl b
rr c
add hl,hl
jr tok7
;
tok8: ld (tokchp),hl
;
;Tokenise
;
tok9: ld hl,(tokcp)
call next_token
ld (tokcp),hl
push ix ;C = word count
pop bc
ld a,(tokln) ;Length=0 => EOL
or a
jp z,tok99
ld hl,(tokdst) ;Max words
call peek64
cp c ;IF C >= A, ok.
jp c,tok99
;
tok10: ld a,(tokln)
ld hl,(tokptr)
ld de,(tokchp)
call find_word ;BC := word no.
ld hl,(toktp)
ld a,(tokflg)
or a
jr z,tok11
ld a,b
or c
jr z,tok12
tok11: ld a,b
call ZXPOKE
inc hl
ld a,c
call ZXPOKE
inc hl
jr tok14
;
tok12: inc hl
inc hl
tok14:
ld a,(tokln)
call ZXPOKE
inc hl
push hl
ld hl,(tokptr)
ld de,(toksrc)
and a
sbc hl,de
ld a,l
pop hl
call ZXPOKE
inc hl
ld (toktp),hl
inc ix ;Word count
jp tok9
tok99: push ix
pop bc ;C=no. of words
ld hl,(tokdst)
inc hl
ld a,c
call ZXPOKE
;
;Diagnostic
;
scf
ret
;
fwlen: defb 0
fwchp: defw 0
fwadd: defw 0
;
;Compare encrypted words at DE and z-address HL, length 4 or 6 bytes.
;
cpenc: ld b,4 ;Returns: Zero set if words match
ld a,(zver) ;Carry set if word at DE is less than at HL.
cp 4
jr c,cpenc1
ld b,6
cpenc1: call peek64 ;Get from Z-memory
ld c,a
ld a,(de)
cp c ;
ret nz
inc hl
inc de
djnz cpenc1
xor a
ret
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
fwoffs:
;
;HL := (tokwi * tokesz) + tokdct
;
push af
push de
ld hl,(tokdct)
ld de,(tokwi)
ld a,(tokesz)
fwolp: add hl,de
dec a
jr nz,fwolp
pop de
pop af
ret
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Limit tokwi to 0 <= tokwi < abs(tokdsz)
;
limit_wi:
push hl
push de
ld hl,(tokwi)
bit 7,h
jr nz,limw1
ld de,(tokdsz)
call absde
and a
sbc hl,de
jr c,limw2
dec de
ld (tokwi),de
pop de
pop hl
ret
limw1: ld hl,0
ld (tokwi),hl
limw2: pop de
pop hl
ret
;
dtok: push af
push bc
push de
push hl
ld b,a
dtok1: call peek64
push bc
cp 20h
ld e,a
ld c,2
call nc,ZXFDOS
pop bc
inc hl
djnz dtok1
jp popd
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;From jzip's find_word()
;
find_word: ;A=token len HL=addr DE=chop
;;; call dtok
ld (fwchp),de
ld (fwadd),hl
ld (fwlen),a
ld bc,(tokdsz)
ld a,b
or c
ret z
ld a,(fwlen) ;A=length
ld b,a
call encode ;to z-string at encbuf
;
ld hl,(fwchp)
dec hl
ld (tokwi),hl
ld hl,(tokdsz)
bit 7,h ;Dictionary size negative?
jr nz,dszlt0
fww1: ld bc,(fwchp) ;while (fwchp)
ld a,b
or c
ret z ;Not found
srl b
rr c ;fwchp /= 2;
ld (fwchp),bc
call limit_wi
;
call fwoffs ;HL := offset of word tokwi
;
ld de,encbuf
push hl
call cpenc
pop bc
jr c,fww5 ;Go back
jr nz,fww4 ;Go forward
;
;We have a match!
;
ret
;
fww4: ld hl,(tokwi)
ld bc,(fwchp)
add hl,bc
ld (tokwi),hl
call limit_wi
jr fww1
;
fww5: ld hl,(tokwi)
ld bc,(fwchp)
and a
sbc hl,bc
ld (tokwi),hl
call limit_wi
jr fww1
dszlt0: call absbc ;BC = word count
ld hl,0
ld (tokwi),hl
dszlp1: ld a,b
or c
ret z
push bc
call fwoffs
ld de,encbuf
push hl
call cpenc
pop bc
jr z,dszok
ld hl,(tokwi)
inc hl
ld (tokwi),hl
pop bc
dec bc
jr dszlp1
dszok: pop de
ret