Source code of QTerm 4.3e added
This commit is contained in:
parent
bad966dfcf
commit
5161e84617
@ -85,6 +85,8 @@ The file [QTERM43F.LBR](qterm43f.lbr) is the original QTerm distribution file.
|
||||
|
||||
The directory [files/](files/) contains all files from the .LBR file. There, the documentation for QTerm, [QTERM.DOC](files/QTERM.DOC) can be found.
|
||||
|
||||
In the directory [source/](source/), the source code of QTerm 4.3e can be found (as files and QT43SRC.LBR library).
|
||||
|
||||
### Applying a patch
|
||||
|
||||
The patches are applied using ```ZSM``` and ```ZPATCH```, which are included in the QTerm distribution (```QTERM43F.LBR```).
|
||||
|
271
source/BAUD.Z
Normal file
271
source/BAUD.Z
Normal file
@ -0,0 +1,271 @@
|
||||
; baud.z - alter baud rate, and data word format
|
||||
|
||||
.var cmdlin 0x80
|
||||
|
||||
.macro baudtb speed
|
||||
dw speed
|
||||
dw b`speed
|
||||
.endm
|
||||
|
||||
.extern baud
|
||||
baud:
|
||||
call prompt
|
||||
db 'Baud rate? \0' ; see what is wanted
|
||||
ld hl,cmdlin - 1
|
||||
scanp: inc hl ; first look for +ch
|
||||
ld a,(hl)
|
||||
or a
|
||||
jr z,noplus ; didn't find one, on to the next bit
|
||||
xor '+'
|
||||
jr nz,scanp ; not this char, on to the next
|
||||
ld (hl),a ; replace the '+' so we have a revised end
|
||||
inc hl
|
||||
ld bc,0x0200 ; b = 2: 2 chars, c = 0 for delimiter
|
||||
ld de,cschr ; save them in cschr and cqchr
|
||||
call parst ; crunch up the string
|
||||
noplus: ld hl,cmdlin - 1
|
||||
scansl: inc hl ; then look for a -del
|
||||
ld a,(hl)
|
||||
or a
|
||||
jr z,nodel ; no '-' found: process normally
|
||||
xor '-'
|
||||
jr nz,scansl ; this was not a '-', on to the next
|
||||
ld (hl),a ; put a null in to make the '-' vanish
|
||||
call incbyp ; skip leading space
|
||||
or a ; anything there?
|
||||
jr z,nodel ; no - go crunch the rest
|
||||
cp '*' ; '*' as a place holder?
|
||||
jr z,nocsdl ; skip if no ^S delay
|
||||
ld de,1
|
||||
call scanm ; get a number, but default if none given
|
||||
ld a,e
|
||||
ld (csdely),a ; save in ^S delay
|
||||
nocsdl: call incbyp
|
||||
or a
|
||||
jr z,nodel ; exit now if nothing left
|
||||
cp '*'
|
||||
jr z,nochdl ; skip if no character delay
|
||||
sub '0'
|
||||
cp 10 ; check for a number
|
||||
ld de,ecflg
|
||||
ld (de),a ; set echo check flag
|
||||
jr nc,lcnum ; jump if not a number - this sets flag
|
||||
dec hl ; hl down to account for coming inx
|
||||
xor a ; clear acc
|
||||
ld (de),a ; and thus the echo check flag
|
||||
lcnum: inc hl
|
||||
ld de,0
|
||||
call scanm ; get another
|
||||
ld a,e
|
||||
ld (chd),a ; and save a character delay
|
||||
nochdl: call incbyp
|
||||
or a
|
||||
jr z,nodel ; exit now if nothing left
|
||||
cp '*'
|
||||
jr z,nodel ; and exit if a star
|
||||
ld de,lfecho
|
||||
ld (de),a ; set linefeed echo flag
|
||||
sub '0'
|
||||
cp 10 ; first char a digit
|
||||
jr nc,lfnum ; jump if not
|
||||
dec hl ; otherwise backstep hl
|
||||
xor a
|
||||
ld (de),a ; and clear linefeed echo flag
|
||||
lfnum: inc hl
|
||||
ld de,300
|
||||
call scanm
|
||||
ld (nld),de ; finally a newline delay
|
||||
nodel: ld hl,cmdlin
|
||||
call byp
|
||||
ld b,h
|
||||
ld c,l ; point bc at first non-white-space in line
|
||||
ld a,(bc)
|
||||
or a
|
||||
ret z ; end of line so do nothing
|
||||
cp '*' ; was a '*' skip over baud rate set
|
||||
jp z,bmode
|
||||
dec bc
|
||||
scan: inc bc ; now bypass leading zeros
|
||||
ld a,(bc)
|
||||
cp '0'
|
||||
jr z,scan
|
||||
ld hl,0 ; hl gets numeric value of rate
|
||||
ld ix,rate ; ix points to where string will live
|
||||
loop: ld a,(bc)
|
||||
sub '0'
|
||||
cp 10 ; get the next character & check it's a digit
|
||||
ld e,l
|
||||
ld d,h
|
||||
jr nc,gotit ; nope - we've finished
|
||||
add hl,hl ; * 2
|
||||
add hl,hl ; * 4
|
||||
add hl,de ; * 5
|
||||
add hl,hl ; * 10
|
||||
ld e,a
|
||||
ld d,0 ; new digit to de
|
||||
add hl,de ; add it in
|
||||
ld a,(bc) ; get the character again
|
||||
ld (ix),a ; save in string
|
||||
inc ix
|
||||
inc bc ; move both pointers
|
||||
jr loop ; and do it again
|
||||
gotit: ld a,d
|
||||
or e
|
||||
jr z,usage ; zero baud rate means we should complain
|
||||
ld a,' '
|
||||
push ix
|
||||
pop hl ; copy string save pointer to hl
|
||||
ld (hl),a
|
||||
inc hl
|
||||
ld (hl),a
|
||||
inc hl
|
||||
ld (hl),a ; add three spaces
|
||||
ld a,(bc) ; look at input char following rate
|
||||
or a
|
||||
jr z,cmdok ; zero byte is ok
|
||||
cp ' '
|
||||
jr z,cmdok ; and so is a space
|
||||
usage: call ilprt ; but we complain about anything else
|
||||
db 'Specify <rate> <mode>\r\n\0'
|
||||
ret
|
||||
cmdok: ld hl,table ; point at the table
|
||||
.dseg
|
||||
table: baudtb 38400
|
||||
baudtb 19200
|
||||
baudtb 9600
|
||||
baudtb 4800
|
||||
baudtb 2400
|
||||
baudtb 1200
|
||||
baudtb 600
|
||||
baudtb 300
|
||||
endtbl:
|
||||
|
||||
.cseg
|
||||
push bc ; save address in input string
|
||||
ld b,{endtbl - table} / 4
|
||||
scntbl: ld a,(hl)
|
||||
cp e
|
||||
inc hl ; check low byte of baud rate
|
||||
jr nz,bad2 ; skip if no match
|
||||
ld a,(hl)
|
||||
cp d ; check high byte
|
||||
jr z,gottbl ; match! - we got it
|
||||
bad2: inc hl ; this entry no good
|
||||
inc hl
|
||||
inc hl ; skip over it
|
||||
djnz scntbl ; and loop till we run out
|
||||
badbau: call ilprt ; go complain
|
||||
db 'Error: invalid baud rate\r\n\0'
|
||||
pop hl ; clean up the stack
|
||||
ret ; and exit
|
||||
gottbl: inc hl
|
||||
ld e,(hl)
|
||||
inc hl ; get address of baud value entry in
|
||||
ld d,(hl) ; configuration area
|
||||
ld a,(de) ; get the baud byte itself
|
||||
inc de
|
||||
ld b,a ; save in b
|
||||
ld a,(de) ; get the flag byte
|
||||
or a ; is it zero?
|
||||
jr z,badbau ; yes - go complain
|
||||
ld a,b
|
||||
call setbd ; go set the baud rate
|
||||
call ilprt ; and say what we did
|
||||
db 'Baud rate set to '
|
||||
|
||||
.extern rate
|
||||
rate: db ' \r\n\0'
|
||||
pop bc ; get the string address back to bc
|
||||
dec bc
|
||||
bmode: inc bc
|
||||
ld a,(bc)
|
||||
cp ' '
|
||||
jr z,bmode ; do a byp on bc
|
||||
or a
|
||||
ret z ; return now on end of string
|
||||
ld e,0 ; set e zero for mode selection
|
||||
ld ix,modsav ; point ix at save area
|
||||
ld (ix + 0),a ; save first byte in data bit count
|
||||
cp '7'
|
||||
jr z,seven ; better be '7'
|
||||
cp '8'
|
||||
jr z,eight ; or '8'
|
||||
badmod: call ilprt ; complain if it's wrong
|
||||
db 'Modes are [87][EON][12]\r\n\0'
|
||||
ret
|
||||
eight: inc e ; set bit 0 in e for 8 bit options
|
||||
seven: inc bc
|
||||
ld a,(bc) ; get the next character
|
||||
and 0x5f ; force upper case
|
||||
ld (ix + 2),a ; save it away
|
||||
cp 'N'
|
||||
jr z,nopty ; 'N' => no parity
|
||||
cp 'O'
|
||||
jr z,odd ; 'O' => odd parity
|
||||
cp 'E'
|
||||
jr nz,badmod ; 'E' => even parity: complain if no match
|
||||
set 2,e
|
||||
jr nopty ; set bit 2 to select even parity options
|
||||
odd: set 3,e ; set bit 3 to select odd parity options
|
||||
nopty: inc bc
|
||||
ld a,(bc) ; look at the last character
|
||||
ld (ix + 4),a ; and save it away
|
||||
cp '1'
|
||||
jr z,one ; better be '1'
|
||||
cp '2'
|
||||
jr nz,badmod ; or '2' - complain if it's neither
|
||||
set 1,e ; set bit 1 for 2 data bit options
|
||||
one: inc bc
|
||||
ld a,(bc)
|
||||
cp ' '
|
||||
jr z,one ; skip any trailing spaces
|
||||
or a
|
||||
jp nz,usage ; but complain if there was more junk
|
||||
ld d,0 ; extend index in e to 16 bits
|
||||
ld hl,modtab
|
||||
add hl,de ; index into table in configuration area
|
||||
ld a,(hl) ; get the byte
|
||||
call setmod ; go set the modes
|
||||
call ilprt
|
||||
db 'Mode set to '
|
||||
|
||||
.extern modsav
|
||||
modsav: db ' , , \r\n\0' ; and say what we did
|
||||
ret
|
||||
|
||||
scanm: ld a,(hl)
|
||||
sub '0'
|
||||
cp 10 ; did we get a digit?
|
||||
jr nc,donenm ; no - use default in de
|
||||
ld de,0 ; set de zero for answer
|
||||
scanlp: ld a,(hl)
|
||||
sub '0'
|
||||
cp 10 ; another digit?
|
||||
donenm: jp nc,unbyp ; exit if not - answer in de
|
||||
push hl ; save pointer
|
||||
ld h,d
|
||||
ld l,e
|
||||
add hl,hl
|
||||
add hl,hl
|
||||
add hl,de
|
||||
add hl,hl ; hl = de * 10
|
||||
ld e,a
|
||||
ld d,0
|
||||
add hl,de ; + new digit
|
||||
ex de,hl ; back to de
|
||||
pop hl
|
||||
inc hl ; look at next character
|
||||
jr scanlp
|
||||
|
||||
.dseg
|
||||
.extern csdely
|
||||
csdely: db 1
|
||||
.extern nld
|
||||
nld: dw 300
|
||||
.extern chd
|
||||
chd: db 0
|
||||
.extern cschr
|
||||
cschr: db 's' & 0x1f
|
||||
.extern cqchr
|
||||
cqchr: db 'q' & 0x1f
|
||||
|
178
source/CATCH.Z
Normal file
178
source/CATCH.Z
Normal file
@ -0,0 +1,178 @@
|
||||
; catch.z - open & close catch files, also put them on hold
|
||||
|
||||
.incl "c:vars"
|
||||
|
||||
.extern catch
|
||||
catch:
|
||||
ld a,(cflg)
|
||||
or a
|
||||
jr z,tfileo
|
||||
ld a,2
|
||||
ld (cflg),a
|
||||
|
||||
.extern hold
|
||||
hold:
|
||||
ld hl,cflg
|
||||
ld a,(hl)
|
||||
or a ; file open?
|
||||
ret z ; no - so do nothing
|
||||
xor 3
|
||||
ld (hl),a ; toggle hold mode
|
||||
push af
|
||||
call ilprt
|
||||
db '\r\nCatch file \0'
|
||||
pop af
|
||||
dec a
|
||||
jr z,reac
|
||||
call ilprt
|
||||
db 'on hold\r\n\0'
|
||||
ret
|
||||
reac: call ilprt
|
||||
db 'reactivated\r\n\0'
|
||||
ret
|
||||
|
||||
.extern cclose
|
||||
cclose:
|
||||
ld a,(cflg)
|
||||
or a
|
||||
ret z
|
||||
call doclos
|
||||
call ilprt
|
||||
db '\r\nFile closed\r\n\0'
|
||||
ret
|
||||
|
||||
tfileo: call getfcb
|
||||
ret c
|
||||
jp z,nowc
|
||||
ld a,(fcb + 2)
|
||||
cp ' '
|
||||
scf
|
||||
ret z
|
||||
call reset
|
||||
ld hl,fcb
|
||||
ld de,cfcb
|
||||
push de
|
||||
ld bc,34
|
||||
ldir
|
||||
pop de
|
||||
push de
|
||||
ld c,open
|
||||
call usrbds
|
||||
inc a
|
||||
pop de
|
||||
jr z,isok
|
||||
appndq: ld hl,10
|
||||
add hl,de
|
||||
bit 7,(hl)
|
||||
jr z,appok
|
||||
call ilprt
|
||||
db 'Can\'t append file\r\n\0'
|
||||
ret
|
||||
appok: ld c,cfsize
|
||||
push de
|
||||
call usrbds
|
||||
pop de
|
||||
ld hl,36
|
||||
add hl,de
|
||||
ld a,(hl)
|
||||
dec hl
|
||||
or (hl)
|
||||
dec hl
|
||||
or (hl)
|
||||
jr z,creok
|
||||
declp: ld a,(hl)
|
||||
dec (hl)
|
||||
inc hl
|
||||
or a
|
||||
jr z,declp
|
||||
push de
|
||||
ld de,(cbuff)
|
||||
ld c,setdma
|
||||
call bdos
|
||||
call fill1a
|
||||
pop de
|
||||
ld c,redrnd
|
||||
call usrbds
|
||||
ld hl,(cbuff)
|
||||
dec hl
|
||||
eofl: inc hl
|
||||
ld a,(hl)
|
||||
cp 0x1a
|
||||
jr nz,eofl
|
||||
ld (cptr),hl
|
||||
jr setcfo
|
||||
isok: ld c,create
|
||||
call usrbds
|
||||
inc a
|
||||
jr nz,creok
|
||||
call ilprt
|
||||
db 'Can\'t create file\r\n\0'
|
||||
ret
|
||||
creok: call fill1a
|
||||
setcfo: call ilprt
|
||||
db 'File opened\r\n\0'
|
||||
xor a
|
||||
inc a
|
||||
setcfl: ld (cflg),a
|
||||
ret
|
||||
|
||||
doclos: call flushc
|
||||
ld de,cfcb
|
||||
ld c,close
|
||||
call usrbds
|
||||
call ctlq
|
||||
xor a
|
||||
jr setcfl
|
||||
|
||||
.extern flushc ; enter here to flush any pending write of
|
||||
flushc: ; catch buffer
|
||||
ld hl,(cptr)
|
||||
ld de,(cbuff) ; point at buffer
|
||||
or a
|
||||
sbc hl,de ; how many chars in buffer
|
||||
dec hl
|
||||
add hl,hl
|
||||
inc h
|
||||
ld b,h ; converted to sector count
|
||||
ret z ; nothing to write - exit now
|
||||
push bc
|
||||
push de
|
||||
call ctls ; hold up the other end
|
||||
pop de
|
||||
pop bc
|
||||
wrtlp: push bc
|
||||
push de ; save registers
|
||||
ld c,setdma
|
||||
call bdos ; set dma for next 128 bytes
|
||||
ld de,cfcb
|
||||
ld c,write
|
||||
call usrbds ; out they go
|
||||
pop de
|
||||
ld hl,128
|
||||
add hl,de ; move dma
|
||||
ex de,hl
|
||||
pop bc
|
||||
djnz wrtlp ; loop till all done
|
||||
|
||||
fill1a: ; enter here to fill catch buffer with 0x1a's
|
||||
; and reset catch pointer
|
||||
ld hl,(cbuff)
|
||||
ld (cptr),hl ; adjust catch pointer as well
|
||||
ld d,h
|
||||
ld e,l
|
||||
inc de ; copy to de & add 1
|
||||
ld bc,(cbfsiz) ; get buffer size
|
||||
ld (hl),0x1a ; first one
|
||||
ldir ; and the rest
|
||||
ret
|
||||
|
||||
.dseg
|
||||
.extern cflg
|
||||
cflg: db 0
|
||||
|
||||
.useg
|
||||
.extern cptr
|
||||
cptr: ds 2 ; pointer to next save address
|
||||
.extern cfcb
|
||||
cfcb: ds 37 ; fcb for catching
|
||||
|
859
source/CF.Z
Normal file
859
source/CF.Z
Normal file
@ -0,0 +1,859 @@
|
||||
; cf.z - creeping featurism (i.e. file operations in chat scripts)
|
||||
; plus stuff to look after numbers in chat scripts
|
||||
|
||||
.incl "c:vars"
|
||||
|
||||
; stest - compare two strings !% = .s1.s2. `label jump if equal
|
||||
; !% _ .s1.s2. `label jump if equal case insens.
|
||||
; !% # .s1.s2. `label jump if not equal
|
||||
|
||||
.extern stest
|
||||
stest: xor a
|
||||
ld (casefl),a
|
||||
call areabp
|
||||
cp '#'
|
||||
jr z,ckseq ; '#' for inequality
|
||||
xor '='
|
||||
jr z,ckseq ; '=' for equality
|
||||
ld (casefl),a ; set case flag true
|
||||
xor '_' ^ '=' ; '_' for equality case insensitive
|
||||
ret nz
|
||||
ckseq: or a ; z equality, nz inequality
|
||||
push af ; save test value
|
||||
call incbyp ; step up to strings
|
||||
push hl
|
||||
ld hl,work2
|
||||
ld de,work2 + 1
|
||||
ld bc,255
|
||||
ld (hl),b
|
||||
ldir ; clear space where strings will live
|
||||
pop hl
|
||||
or a
|
||||
jr z,testzz
|
||||
ld de,work2 + 1
|
||||
ld b,2
|
||||
seqslp: push bc
|
||||
call scanst ; scan a string
|
||||
inc de
|
||||
pop bc
|
||||
jr c,testzz ; exit if end of input
|
||||
djnz seqslp ; otherwise loop till both read
|
||||
inc hl ; skip trailing terminator
|
||||
push hl ; save input pointer
|
||||
ld hl,work2 + 1
|
||||
ld de,work2 + 42 ; get the two strings
|
||||
csl: ld b,0x7f
|
||||
call cmptst ; check a characters
|
||||
jr nz,phltz ; different, so finish test operation
|
||||
ld a,(hl)
|
||||
or a ; end of string?
|
||||
jr z,phltz ; yes - finish test this way too
|
||||
inc hl
|
||||
inc de ; next chars .....
|
||||
jr csl
|
||||
|
||||
; the !~ creeping featurism entry
|
||||
|
||||
.extern cf
|
||||
cf:
|
||||
call areabu ; what's wanted?
|
||||
inc hl
|
||||
cp '-'
|
||||
jr z,cf_era ; '-' erases
|
||||
cp '='
|
||||
jr z,cf_ren
|
||||
cp '+'
|
||||
jr z,cf_copy ; '+' copies
|
||||
cp 'Y'
|
||||
jr z,cf_filq ; 'Y' file query: jump if file exists
|
||||
xor 'N'
|
||||
ret nz ; 'N' file query: jump if file doesn't exist
|
||||
|
||||
; fall into file query routine
|
||||
|
||||
; file query: check see if a file exists or not, and then jump to a label if
|
||||
; it does.
|
||||
|
||||
cf_filq:
|
||||
or a ; z for 'N', nz for 'Y'
|
||||
push af
|
||||
call scnfcb ; get a fcb
|
||||
ld de,fcb
|
||||
ld c,open ; try to open it - note that this will also
|
||||
; work with wildcards
|
||||
push hl
|
||||
call usrbds ; open
|
||||
inc a
|
||||
phltz: pop hl
|
||||
testzz: jr z,nofil ; not there - do test one way round
|
||||
pop af ; 'Y' / 'N' result back
|
||||
ret z ; 'N' and file exists => no skip
|
||||
jr dskp1 ; 'Y' and file => skip
|
||||
nofil: pop af ; no file .....
|
||||
ret nz ; 'Y' and no file => no skip
|
||||
dskp1: jp doskip ; go skip to the new line
|
||||
|
||||
; rename: du: is taken from the first name - a1:x = b7:y will rename a1:y
|
||||
|
||||
cf_ren: call gettwo
|
||||
ret c ; exit on an error
|
||||
ld hl,(auxfcb)
|
||||
ld (fcb),hl ; xfer drive / user info
|
||||
ld de,fcb
|
||||
ld c,open
|
||||
call usrbds ; open
|
||||
inc a
|
||||
ret z ; not there - exit
|
||||
ld a,(fcb + 10)
|
||||
add a,a
|
||||
ret c ; if it's R/O stop now
|
||||
ld de,auxfcb
|
||||
ld c,open
|
||||
call usrbds ; open
|
||||
inc a
|
||||
ret nz ; replacement _IS_ there - so exit
|
||||
ld hl,auxfcb + 1
|
||||
ld de,fcb + 17
|
||||
ld bc,16
|
||||
ldir ; shift stuff for rename
|
||||
ld de,fcb
|
||||
ld c,rename
|
||||
jp usrbds ; go do it
|
||||
|
||||
; erase subroutine: no wildcards, single file erase
|
||||
|
||||
cf_era: call scnfcb
|
||||
ret z ; no wildcards allowed
|
||||
ld de,fcb
|
||||
ld c,open
|
||||
call usrbds ; open the file
|
||||
ld a,(fcb + 10)
|
||||
add a,a
|
||||
ret c ; if it's R/O stop now
|
||||
ld de,fcb
|
||||
ld c,erase
|
||||
jp usrbds ; otherwise erase it
|
||||
|
||||
; copy file routine
|
||||
|
||||
cf_copy:
|
||||
call gettwo ; get two fcb's - one to fcb, one to auxfcb
|
||||
ret c ; exit on an error
|
||||
ld de,fcb
|
||||
ld c,open
|
||||
call usrbds ; open file1
|
||||
inc a
|
||||
ret z ; not there: exit
|
||||
ld de,auxfcb
|
||||
ld c,open
|
||||
call usrbds ; open file2
|
||||
inc a
|
||||
ret nz ; is there: exit
|
||||
ld de,auxfcb
|
||||
ld c,create
|
||||
call usrbds ; create file2
|
||||
inc a
|
||||
ret z ; create failed: exit
|
||||
ld de,xbuff
|
||||
ld c,setdma
|
||||
call bdos ; set dma address
|
||||
cplp: ld de,fcb
|
||||
ld c,read
|
||||
call usrbds ; read a sector
|
||||
or a
|
||||
jr nz,copied ; all done
|
||||
ld de,auxfcb
|
||||
ld c,write
|
||||
call usrbds ; write it back
|
||||
or a
|
||||
jr z,cplp ; exit if write failed
|
||||
copied: ld de,auxfcb
|
||||
ld c,close
|
||||
jp usrbds ; close output file
|
||||
|
||||
; parse two filenames, separated by an '=' sign
|
||||
|
||||
gettwo: call scnfcb ; get one
|
||||
scf
|
||||
ret z ; exit w/ carry if wildcards
|
||||
call byp
|
||||
cp '=' ; need an '='
|
||||
scf
|
||||
ret nz ; not there: exit
|
||||
push hl
|
||||
call xferax ; shift it to auxfcb
|
||||
pop hl
|
||||
inc hl
|
||||
call scnfcb ; get a second
|
||||
scf
|
||||
ret z ; exit with carry on an error
|
||||
or a
|
||||
ret ; else clear carry for OK
|
||||
|
||||
; !@ evaluation subroutine
|
||||
|
||||
.extern eval
|
||||
eval:
|
||||
call areabu ; set to read the string
|
||||
sub 'A' ; get the variable number
|
||||
cp 26
|
||||
jr nc,eerr0 ; not legal, exit now
|
||||
call ivar
|
||||
push de ; save it's address
|
||||
inc hl
|
||||
call scan ; scan a term
|
||||
jr c,eerr1 ; no good - exit
|
||||
push af ; save the value
|
||||
call byp
|
||||
cp '-'
|
||||
jr z,opok
|
||||
xor '+' ; check the operator
|
||||
jr nz,eerr2
|
||||
opok: push af ; save the operator (zero for '+', nz for '-')
|
||||
inc hl
|
||||
call scan ; get a second term
|
||||
jr nc,s2ok ; all OK, go set the variable
|
||||
pop de
|
||||
eerr2: pop de
|
||||
eerr1: pop de ; clean up the stack
|
||||
eerr0: call ilprt
|
||||
db 'Bad expression: \0'
|
||||
call dim ; tell the user
|
||||
ld hl,0x80
|
||||
call prtslp
|
||||
jp crlf ; and return
|
||||
s2ok: ld l,a ; second term to l
|
||||
pop bc ; operator to b
|
||||
pop af ; first term to a
|
||||
dec b
|
||||
inc b ; zero => '+'
|
||||
jr z,addem ; go do it
|
||||
sub l
|
||||
sub l ; setup for subtraction
|
||||
addem: add a,l ; do the addition
|
||||
pop hl ; restore variable address
|
||||
ld (hl),a ; save result
|
||||
ret
|
||||
|
||||
; !# test routine: compare variables with other variables or numbers
|
||||
|
||||
.extern test
|
||||
test:
|
||||
call areabu
|
||||
sub 'A' ; get the variable
|
||||
cp 26
|
||||
jr nc,eerr0 ; exit on an error
|
||||
call ivar
|
||||
ld a,(de) ; get te value
|
||||
push af ; save it
|
||||
call incbyp ; get the operator
|
||||
cp '<'
|
||||
jr z,cmpok
|
||||
cp '>'
|
||||
jr z,cmpok
|
||||
cp '#'
|
||||
jr z,cmpok
|
||||
xor '='
|
||||
jr nz,eerr1 ; exit if it's no good
|
||||
cmpok: push af ; save the operator
|
||||
inc hl
|
||||
call scan ; get the term
|
||||
jr c,eerr2 ; something wrong, exit
|
||||
ld e,a ; term to e
|
||||
pop af ; restore the operator
|
||||
or a
|
||||
jr nz,nocpe ; z => '=' => equality
|
||||
pop af
|
||||
cp e ; test for equality
|
||||
ret nz ; exit if no good
|
||||
jr doskip ; go do the goto
|
||||
|
||||
; this is here for jr length reasons
|
||||
|
||||
cplt: pop af
|
||||
cp e ; compare
|
||||
skipnc: ret nc ; if it failed exit now
|
||||
|
||||
; jump to a line number
|
||||
|
||||
doskip: call scnnum ; get the number to go to
|
||||
pop hl ; get return address back
|
||||
pop de ; get the next line
|
||||
dec a ; save it away (needs to be -1)
|
||||
push af ; save the new line away
|
||||
jp (hl) ; jump to return address
|
||||
|
||||
nocpe: cp '#' ; '#' => inequality
|
||||
jr nz,nocpne
|
||||
pop af ; restore variable value
|
||||
cp e
|
||||
ret z ; exit if test failed
|
||||
jr doskip ; else do the goto
|
||||
nocpne: cp '>'
|
||||
jr nz,cplt ; '>' => greater than
|
||||
pop af ; var to a
|
||||
ld d,a ; and to d
|
||||
ld a,e ; term to e
|
||||
cp d ; and compare
|
||||
jr skipnc ; go check the result
|
||||
|
||||
; initch - do odd bits and pieces of setup for chat operation
|
||||
|
||||
.extern initch
|
||||
initch: ld a,1
|
||||
ld (opentr),a ; clear number of open tries
|
||||
|
||||
.extern clrvar
|
||||
clrvar:
|
||||
ld a,'A'
|
||||
ld (_check_),a
|
||||
ld hl,vars ; nuke all variables to zero
|
||||
ld de,vars + 1
|
||||
ld bc,26 + 9 + 26 ; 26 numbers, plus 35 strings 0 - 9 & a - z
|
||||
ld (hl),b ; start with a zero from b
|
||||
ldir
|
||||
dec b ; b comes out of the ldir w/ zero: dec to -1
|
||||
ld (hl),b ; -1 byte to end strings
|
||||
ld bc,512 - 9 - 27
|
||||
ldir ; fill remaining space with -1's
|
||||
ret
|
||||
|
||||
ivar: push hl ; save hl
|
||||
ld l,a
|
||||
ld h,0 ; offset in a to hl
|
||||
ld de,vars
|
||||
add hl,de ; index into table
|
||||
ex de,hl ; swap to de
|
||||
pop hl ; restore hl
|
||||
ret
|
||||
|
||||
scan: call byp
|
||||
or 0x20
|
||||
sub 'a' ; was it a letter?
|
||||
cp 26
|
||||
jr nc,scnnum ; no, go see about a number
|
||||
inc hl ; step over it
|
||||
call ivar ; index into array
|
||||
ld a,(de) ; get the value
|
||||
ret ; and return - carry cleared by ivar
|
||||
|
||||
scnnum: ld e,0
|
||||
call byp ; find the number
|
||||
snlp: ld a,(hl) ; get char back
|
||||
sub '0'
|
||||
cp 10 ; number?
|
||||
ccf
|
||||
ret c ; return if not
|
||||
ld d,a ; save in d
|
||||
ld a,e
|
||||
add a,a
|
||||
add a,a
|
||||
add a,e
|
||||
add a,a ; a = e * 10
|
||||
add a,d ; + d
|
||||
ld e,a
|
||||
inc hl
|
||||
ld a,(hl) ; next letter
|
||||
cp '-'
|
||||
jr z,rete
|
||||
cp '+'
|
||||
jr z,rete ; + and - are legal delimiters
|
||||
or ' '
|
||||
xor ' ' ; so are ' ' and null
|
||||
rete: ld a,e ; get value from e
|
||||
jr nz,snlp
|
||||
ret ; return, carry clear from compare
|
||||
|
||||
; mattog - handle !& toggles: 'm' & 'l' for matches, 'o' for modem output echo
|
||||
|
||||
.extern mattog
|
||||
mattog: call areabu ; get command letter and upper case it
|
||||
cp 'O'
|
||||
ld c,op_bit ; 'O' - do output bit
|
||||
jr z,dotog
|
||||
cp 'L'
|
||||
ld c,lf_bit ; 'L' - do looking for message bit
|
||||
jr z,dotog
|
||||
cp 'M' ; 'M' - do match bit
|
||||
ret nz
|
||||
ld c,mat_bit
|
||||
dotog: call incbyp ; now look for a char to say what to do
|
||||
ld hl,mode ; point hl at mode byte
|
||||
or a
|
||||
jr z,xorit ; nothing: toggle the bit
|
||||
cp '0'
|
||||
jr nz,clrit ; not '0': clear the bit to enable
|
||||
ld a,(hl)
|
||||
or c ; otherwise set it
|
||||
jr smret
|
||||
clrit: ld a,c
|
||||
cpl ; toggle bit in c
|
||||
and (hl) ; clear the bit in questin
|
||||
jr smret
|
||||
xorit: ld a,(hl)
|
||||
xor c ; flip the bit
|
||||
smret: ld (hl),a ; save and we're done
|
||||
ret
|
||||
|
||||
; messag - process a !> printout
|
||||
|
||||
.extern messag
|
||||
messag: call areabp ; point at first non-white
|
||||
ld de,packet ; somewhere to put it
|
||||
push de
|
||||
ld bc,128 << 8 ; 128 chars max, and eoln is the delimiter
|
||||
call parst ; crunch up the string
|
||||
pop hl
|
||||
jp prtslp ; and dump it out
|
||||
|
||||
; fileio - process !( r/w commands to read / write variables from the file
|
||||
|
||||
.extern fileio
|
||||
fileio:
|
||||
call areabu ; get R or W
|
||||
cp 'R'
|
||||
jr z,setrd
|
||||
cp 'W'
|
||||
ret nz
|
||||
ld a,34 ; write random
|
||||
db 0x11 ; ld de,XXXX - kills ld a below
|
||||
setrd: ld a,33 ; read random
|
||||
ld (hibit),a ; save it away for later
|
||||
call incbyp
|
||||
or 0x20
|
||||
sub 'a'
|
||||
cp 26
|
||||
ret nc ; check valid string name
|
||||
push af ; save string index
|
||||
call incbyp
|
||||
sub '0' ; number zero to nine for file record
|
||||
|
||||
ld hl,lbrs ; get /QTERM.LBR as a filename
|
||||
push af
|
||||
call scnfcb ; parse into 0x5b
|
||||
pop af
|
||||
ld hl,['T' << 8] + 'S'
|
||||
ld (0x65),hl ; convert extent from LBR to STR
|
||||
ld hl,(chtusr)
|
||||
inc h
|
||||
ld (0x5b),hl ; set drive / user
|
||||
ld hl,0x68 ; point hl / de at nulls
|
||||
ld de,0x69
|
||||
ld bc,0xff - 0x68 ; clear to end of name
|
||||
ldir
|
||||
ld (0x7d),a ; save record number now
|
||||
|
||||
ld de,0x5b
|
||||
ld c,15
|
||||
call usrbds ; open it
|
||||
pop de
|
||||
inc a
|
||||
ret z ; exit if no good
|
||||
ld a,d
|
||||
add a,9
|
||||
call fparam ; point at string
|
||||
ld de,0x80
|
||||
push de ; save string address to read from
|
||||
push hl ; save string address in table
|
||||
push de ; and read address again
|
||||
ld b,d
|
||||
ld c,0x7f
|
||||
ldir ; shift the string
|
||||
pop de ; address to de
|
||||
ld c,26
|
||||
call bdos ; set dma
|
||||
ld bc,(hibit) ; r/w BDOS opcode to c
|
||||
ld de,0x5b
|
||||
push de
|
||||
call usrbds ; do the operation
|
||||
pop de
|
||||
ld c,16
|
||||
call usrbds ; close the file
|
||||
pop hl
|
||||
jr repstr ; replace string in table
|
||||
|
||||
; sinput - handle two cases of input processing for !<
|
||||
|
||||
.extern sinput
|
||||
sinput: call areabp ; get the command character
|
||||
ld d,a ; command char to d
|
||||
call incbyp ; get variable / string letter
|
||||
call ucsa ; upper case it
|
||||
sub 'A'
|
||||
cp 26 ; is it valid?
|
||||
ret nc ; nope
|
||||
ld e,a ; letter code to e
|
||||
ld a,d ; command char back from d
|
||||
xor '-'
|
||||
jr z,strin ; '-' for string input
|
||||
xor '.' ^ '-'
|
||||
ret nz ; '.' for hot key input
|
||||
ld d,a ; make code in e fill de
|
||||
push de ; save
|
||||
call kbdin ; go get a character
|
||||
pop de
|
||||
ld hl,vars
|
||||
add hl,de ; index into variables
|
||||
ld (hl),a ; save the letter
|
||||
ret
|
||||
|
||||
strin: ld d,e
|
||||
push de
|
||||
ld de,work2 ; point at input area
|
||||
ld a,40
|
||||
ld (de),a ; 40 chars maximum
|
||||
ld c,10
|
||||
call bdos ; go get them
|
||||
call crlf ; throw a new line just for the hell of it
|
||||
ld hl,work2 + 1
|
||||
ld e,(hl) ; get the length
|
||||
inc hl ; point at real text
|
||||
pop af
|
||||
push hl
|
||||
ld d,0 ; extend length to de
|
||||
add hl,de ; point at end of string
|
||||
ld (hl),d ; add a null terminating byte
|
||||
savstr: add a,9 ; get string index to a
|
||||
call fparam ; point at string
|
||||
repstr: call kilstr ; kill it
|
||||
xor a
|
||||
pop de
|
||||
jp insstr ; and replace it
|
||||
|
||||
; now starts the middle of the "read string variable from modem" code - this
|
||||
; is kinda cut to shreds for jr length reasons - we enter at the bottom and
|
||||
; leave via savstr above
|
||||
|
||||
; the very end - we've read the string, now it's time to save it
|
||||
|
||||
gotit: inc de ; point back to start
|
||||
push de ; save this point for later
|
||||
ld h,d
|
||||
ld l,e ; copy to hl
|
||||
kcclp: ld a,(hl) ; get a char
|
||||
and 0x7f ; nuke bit 7
|
||||
ld (de),a ; save it
|
||||
inc hl ; bump read ptr
|
||||
or a
|
||||
jr z,hsav ; exit on a null
|
||||
cp ' '
|
||||
jr c,kcclp ; ditch control chars
|
||||
cp 0x7f
|
||||
jr z,kcclp ; and deletes
|
||||
inc de ; otherwise step up to allow saved character
|
||||
jr kcclp
|
||||
|
||||
hsav: ld a,(hibit) ; get string number
|
||||
jr savstr ; go and save it
|
||||
|
||||
; now the loop to find the start
|
||||
|
||||
stlp: call redsch ; check a character
|
||||
jr z,wasec ; check for end character
|
||||
ld a,(de) ; no - we'll want to save original char back
|
||||
wasec: ld c,a ; save char to save
|
||||
push hl
|
||||
ld h,l ; load start char into h
|
||||
call chksch ; did we find it?
|
||||
pop hl
|
||||
ld a,c
|
||||
ld (de),a ; drop terminator in
|
||||
jr z,gotit ; yes - go save it away
|
||||
djnz stlp ; count chars
|
||||
ret ; return when we run out chars
|
||||
|
||||
; ![ ^ a c1c2
|
||||
;
|
||||
; After ![ - and ![ : and normal lines have left text in w2 (a la stufw2),
|
||||
; parse a string starting with c1 (but not including it), and ending with c2
|
||||
; (again not including it) - save in string a. If c1 (or c2) are a null
|
||||
; then the string becomes any whitespace delimited string: whitespace is
|
||||
; taken as ' ', tab, cr, lf. Note also that all control characters are
|
||||
; thrown away.
|
||||
|
||||
ipstr: call ucsahl
|
||||
sub 'A' ; convert .....
|
||||
cp 26 ; and test string index
|
||||
ret nc
|
||||
ld (hibit),a ; save it
|
||||
call incbyp ; step up to delimiter chars
|
||||
push hl
|
||||
ld hl,work2 + 257
|
||||
ld de,packet
|
||||
ld bc,66
|
||||
ldir
|
||||
pop hl
|
||||
ld de,pack + 1 ; save them in pack
|
||||
ld b,2 ; two, null terminates
|
||||
xor a
|
||||
ld (de),a ; preload chars with two nulls
|
||||
dec de
|
||||
ld (de),a
|
||||
call parst ; crunch up the string
|
||||
ld hl,(pack) ; load delimiters from where parst put them
|
||||
ld bc,64 << 8 ; max of 64 chars to look at / c == 0
|
||||
ld de,packet + 65 ; point de at saved text
|
||||
|
||||
; now loop looking for the end
|
||||
|
||||
endlp: call redsch ; check a character
|
||||
jr nz,noend ; check for end character
|
||||
inc c ; flag we saw an end char
|
||||
ld (de),a ; add a zero to terminate
|
||||
jr cntend ; jump to count
|
||||
noend: dec c
|
||||
inc c
|
||||
jr nz,stlp ; we've seen an end - go do it
|
||||
cntend: djnz endlp ; count chars
|
||||
ret ; return when we run out chars
|
||||
|
||||
; handle ![ multiple choice thingies from the modem
|
||||
|
||||
.extern multi
|
||||
multi:
|
||||
call areabp ; what's wanted?
|
||||
ld c,a ; save the second character
|
||||
call incbyp ; strip spaces
|
||||
xor a
|
||||
ld (casefl),a
|
||||
ld a,c
|
||||
cp '^'
|
||||
jr z,ipstr
|
||||
cp ':'
|
||||
jp z,silnce
|
||||
cp '-' ; '-' input ......
|
||||
jr z,minput
|
||||
xor '+' ; '+' for 8 bit string compare
|
||||
jr z,str8b
|
||||
cp '=' ^ '+' ; '=' for 7 bit
|
||||
jr z,str7b
|
||||
cp '_' ^ '+' ; '_' for 7 bit and case insensitive
|
||||
ret nz ; oops - don't grok it.
|
||||
ld (casefl),a ; set case flag
|
||||
str7b: ld a,0x7f ; set 7 bit flag
|
||||
db 0x06 ; makes the next byte the operand of a ld b,xx
|
||||
str8b: dec a ; really ld a,0xff since a == 0:
|
||||
; set all 8 bits
|
||||
push af ; save comparison mask
|
||||
ld de,packet ; somewhere to put match string
|
||||
ld bc,[40 << 8] + ' ' ; 40 chars max, space is the delimiter
|
||||
call parst ; crunch up the string
|
||||
pop bc ; comparison mask back to b
|
||||
ret c ; oops - bad string
|
||||
push hl
|
||||
ld hl,work2 + 322 ; point at stuff we read ..... (don't ask why
|
||||
mclp: dec hl ; it's there :-)
|
||||
ld a,(hl) ; end of string yet?
|
||||
or a
|
||||
pop de ; keep stack safe
|
||||
ret z ; end of string: exit
|
||||
push de ; save word back on stack
|
||||
ld de,packet
|
||||
call cmptst ; do we have a match??
|
||||
jr nz,mclp ; skip if no good
|
||||
push hl
|
||||
cmplp: ld a,(de)
|
||||
or a ; end of string we're searching for?
|
||||
jr nz,mtchmo ; yes - we got a hit
|
||||
pop hl
|
||||
pop hl ; get string pointer back to hl
|
||||
doskp1: jp doskip
|
||||
mtchmo: call cmptst
|
||||
jr nz,mchbad ; oops - didn't match, so exit now
|
||||
inc hl
|
||||
inc de
|
||||
jr cmplp ; and back for more
|
||||
mchbad: pop hl ; restore pointer
|
||||
jr mclp ; and back for more
|
||||
|
||||
minput: call scnnum ; get a time
|
||||
or a
|
||||
jr nz,timok
|
||||
ld a,15 ; none given, default to 15 seconds
|
||||
timok: push af
|
||||
push hl
|
||||
ld hl,work2
|
||||
ld de,work2 + 1
|
||||
ld bc,512
|
||||
ld (hl),c
|
||||
ldir ; clear space where strings will live
|
||||
pop hl
|
||||
call byp
|
||||
or a
|
||||
jr z,nostr ; no strings, all done
|
||||
ld de,work2 + 1
|
||||
ld b,4
|
||||
sslp: push bc
|
||||
call scanst ; scan a string
|
||||
inc de
|
||||
pop bc
|
||||
jr c,nostr ; exit if end of input
|
||||
djnz sslp ; otherwise loop till 4 read
|
||||
nostr: ld hl,work2 + 1
|
||||
call finstr ; get address of it's end
|
||||
ld (work2 + 240),hl ; and save it
|
||||
ld hl,work2 + 42
|
||||
call finstr
|
||||
ld (work2 + 242),hl ; and for string 2
|
||||
ld hl,work2 + 83
|
||||
call finstr
|
||||
ld (work2 + 244),hl ; and 3
|
||||
ld hl,work2 + 124
|
||||
call finstr
|
||||
ld (work2 + 246),hl ; and 4
|
||||
pop af ; get time back
|
||||
ld c,a ; save it
|
||||
second: dec c
|
||||
ret z ; all out of time - exit
|
||||
ld de,600
|
||||
call setspd ; set the speed
|
||||
qrtrms: ld b,96 ; hang loose a while
|
||||
qmslp: djnz qmslp
|
||||
push hl
|
||||
push bc
|
||||
call procch
|
||||
jr c,nochar
|
||||
call stufw2 ; save the char
|
||||
inc de
|
||||
ld hl,(work2 + 240)
|
||||
call chkbak ; did we get string1
|
||||
jr z,gotone ; exit if so
|
||||
ld hl,(work2 + 242)
|
||||
call chkbak ; string 2?
|
||||
jr z,gotone ; exit if so
|
||||
ld hl,(work2 + 244)
|
||||
call chkbak ; string 3
|
||||
jr z,gotone ; exit if so
|
||||
ld hl,(work2 + 246)
|
||||
call chkbak ; and lastly check string 4
|
||||
jr z,gotone
|
||||
nochar: pop bc
|
||||
pop hl
|
||||
dec hl ; count down second timer
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,qrtrms
|
||||
jr second ; loop back
|
||||
|
||||
gotone: pop bc
|
||||
pop hl
|
||||
ret
|
||||
|
||||
.extern stufw2
|
||||
stufw2: ld hl,work2 + 258
|
||||
ld de,work2 + 257
|
||||
ld bc,64
|
||||
ldir
|
||||
ld (de),a ; save the character
|
||||
ret
|
||||
|
||||
.extern clerw2
|
||||
clerw2: ld hl,work2 + 256
|
||||
ld de,work2 + 257
|
||||
ld bc,70
|
||||
ld (hl),b
|
||||
ldir
|
||||
ret
|
||||
|
||||
finstr: ld a,(hl)
|
||||
or a
|
||||
ret z
|
||||
inc hl
|
||||
jr finstr
|
||||
|
||||
chkbak: dec hl
|
||||
ld a,(hl)
|
||||
inc hl
|
||||
or a
|
||||
jr nz,isastr
|
||||
inc a
|
||||
ret
|
||||
isastr: push de
|
||||
cklp: dec de
|
||||
dec hl
|
||||
ld a,(hl)
|
||||
or a
|
||||
jr z,pdret
|
||||
ld a,(de)
|
||||
xor (hl)
|
||||
and 0x7f
|
||||
jr z,cklp
|
||||
pdret: pop de
|
||||
ret
|
||||
|
||||
cmptst: ld a,(casefl)
|
||||
or a ; case insensitive?
|
||||
push af ; save z flag
|
||||
ld a,(de)
|
||||
jr z,noucs1 ; nope - use the character as is
|
||||
and 0x7f
|
||||
call ucsa ; force upper case
|
||||
noucs1: ld c,a
|
||||
pop af ; get z flag back for case insensitive
|
||||
ld a,(hl)
|
||||
jr z,noucs2
|
||||
and 0x7f
|
||||
call ucsa ; mask and force upper case
|
||||
noucs2: xor c ; get in the rest of it
|
||||
and b ; mask as necessary
|
||||
ret
|
||||
|
||||
silnce: call scnnum ; get a time
|
||||
or a
|
||||
jr nz,stimok
|
||||
ld a,15 ; none given, default to 15 seconds
|
||||
stimok: call clerw2
|
||||
ld b,a
|
||||
inc b
|
||||
setsil: ld c,b
|
||||
xsecnd: dec c
|
||||
ret z
|
||||
push bc
|
||||
ld de,600
|
||||
call setspd ; set the speed
|
||||
xrtrms: ld b,96 ; hang loose a while
|
||||
xmslp: djnz xmslp
|
||||
push hl
|
||||
call procch
|
||||
pop hl
|
||||
jr c,xnchar
|
||||
call stufw2
|
||||
pop bc
|
||||
jr setsil
|
||||
xnchar: dec hl ; cound down second
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,xrtrms
|
||||
pop bc
|
||||
jr xsecnd ; loop back
|
||||
|
||||
; read a char, and see if it matches the delimiter in c
|
||||
|
||||
redsch: dec de
|
||||
chksch: ld a,(de)
|
||||
and 0x7f ; nuke parity
|
||||
inc h
|
||||
dec h ; is h zero?
|
||||
jr nz,nowsp ; no - don't do white space check
|
||||
call iswa ; is it white space?
|
||||
scf
|
||||
ccf ; clear carry
|
||||
ret nz ; return nz if not (no match)
|
||||
xor a ; clear a so 'cp h' below forces zero
|
||||
nowsp: xor h ; see if char matches delimiter
|
||||
ret
|
||||
|
||||
.dseg
|
||||
.extern mode
|
||||
mode: db lf_bit
|
||||
|
||||
.useg
|
||||
casefl: ds 1 ; case insensitive string match?
|
||||
.extern vars
|
||||
vars: ds 26 ; space for 'a' through 'z'
|
||||
.extern strngs
|
||||
strngs: ds 512 ; space for 35 strings
|
||||
.extern _check_
|
||||
_check_:
|
||||
ds 1 ; check space
|
||||
|
993
source/CHAT.Z
Normal file
993
source/CHAT.Z
Normal file
@ -0,0 +1,993 @@
|
||||
; chat.z - handle send/receive chat scripts
|
||||
|
||||
.incl "c:vars"
|
||||
|
||||
.var _sends 0 ; send string
|
||||
.var _expect 40 ; expect string
|
||||
.var _explen 80 ; length of expect string
|
||||
.var _sndlen 81 ; length of send string
|
||||
.var _time 82 ; time in seconds to try
|
||||
.var _tries 83 ; number of times to try before failing
|
||||
.var _yes 84 ; new state if success
|
||||
.var _no 85 ; new state if failure
|
||||
.var _slow 86 ; should we slow down outgoing string
|
||||
.var _curtry 87 ; current try at this one
|
||||
|
||||
.useg
|
||||
.extern area
|
||||
area: ; area where parsed line lives
|
||||
sends: ds 40 ; send string
|
||||
expect: ds 40 ; expect string
|
||||
explen: ds 1 ; length of expect string
|
||||
sndlen: ds 1 ; length of send string
|
||||
time: ds 1 ; time in seconds to try
|
||||
tries: ds 1 ; number of times to try before failing
|
||||
yes: ds 1 ; new state if success
|
||||
no: ds 1 ; new state if failure
|
||||
.extern slow ; externed for hangup
|
||||
slow: ds 1 ; should we slow down outgoing string
|
||||
curtry: ds 1 ; current try at this one
|
||||
|
||||
.cseg
|
||||
|
||||
.macro table byte,addr
|
||||
dw addr
|
||||
db byte
|
||||
.endm
|
||||
|
||||
pchat:
|
||||
pop hl ; needed for chaining
|
||||
pop hl
|
||||
jr ncchat ; don't clear vars when we chain
|
||||
|
||||
.extern chat
|
||||
chat:
|
||||
call initch ; set up
|
||||
ncchat: ld a,1
|
||||
ld (opentr),a ; clear number of open tries
|
||||
ld hl,scning
|
||||
dec (hl)
|
||||
call gofil ; get and open a file
|
||||
ld hl,scning
|
||||
inc (hl)
|
||||
jr nc,dochat ; open OK, go do it
|
||||
ld hl,cmdlin
|
||||
call byp ; look at first char on command line
|
||||
or a ; no line - give up right now
|
||||
ret z
|
||||
retryo: ld hl,(chtusr)
|
||||
inc h ; turn to a fcb type drive
|
||||
ld (auxfcb),hl ; replace drive / user in fcb
|
||||
jr tryaux ; try it again
|
||||
|
||||
.extern ichat ; enter here with command tail at 80: this
|
||||
ichat: ; is used to handle files given to qterm when
|
||||
; initially invoked
|
||||
call initch
|
||||
ld hl,buffer + 1
|
||||
call scnfcb ; go parse an fcb
|
||||
call byp
|
||||
ld (ppp),hl ; save base of parameter strings
|
||||
call xferax ; stuff it in auxfcb
|
||||
tryaux: ld a,(opentr)
|
||||
neg
|
||||
ld (scning),a
|
||||
call opnaux ; and open it
|
||||
ld hl,scning
|
||||
ld (hl),0 ; reset scanning flag
|
||||
inc hl ; how many tries
|
||||
dec (hl) ; second time - must be the .LBR failing
|
||||
jr nc,dochat ; opened OK, go use it
|
||||
ret nz ; give up if open failed
|
||||
inc hl
|
||||
call scnfcb
|
||||
ld hl,fcb
|
||||
ld de,auxfcb ; set pointers to fcbs
|
||||
ld b,34 ; 34 bytes to shift
|
||||
swplp: ld a,(de)
|
||||
ld c,a
|
||||
ld a,(hl)
|
||||
ld (de),a
|
||||
ld (hl),c ; swap bytes at hl and de
|
||||
inc hl
|
||||
inc de ; move pointers
|
||||
djnz swplp ; loop till done
|
||||
jr retryo ; and retry the open
|
||||
dochat: call nz,setlbr ; if .LBR file open, then set to read it
|
||||
jp c,fnferr ; file not found - complain & exit
|
||||
ld hl,(ppp)
|
||||
ld de,0x80 ; move the parameters to 0x80
|
||||
ld b,d
|
||||
ld c,e ; also 0x80 bytes to move
|
||||
ldir ; shift them down
|
||||
call prepclv ; prepare the command line variables
|
||||
ld hl,script
|
||||
ld (ppp),hl ; save address where lines will go
|
||||
ld de,script + 1
|
||||
ld bc,4096 + 1536 - 1
|
||||
xor a
|
||||
ld (hl),a
|
||||
ldir ; clear out the script and work areas
|
||||
ld a,0x7f
|
||||
ld (b7flag),a ; flag to zap bit 7
|
||||
loop: push bc ; save line number in bc
|
||||
call getlin ; get a line
|
||||
pop bc
|
||||
jr c,cnvrt ; eof - now convert labels and parameters
|
||||
ld hl,auxlin
|
||||
ld a,(hl)
|
||||
or a
|
||||
jr z,loop ; ditch blank lines
|
||||
inc hl
|
||||
cp '!' ; first char a '!'
|
||||
jr nz,nobang ; no - so process normally
|
||||
ld e,(hl)
|
||||
call incbyp
|
||||
ld a,e
|
||||
cp ';' ; comment??
|
||||
jr z,loop ; yes - throw it away _RIGHT_NOW_
|
||||
cp ':' ; label??
|
||||
push af
|
||||
call z,label ; yes - save it away
|
||||
pop af
|
||||
ld hl,auxlin + 1
|
||||
cp '$' ; parameter default?
|
||||
jr nz,nodolr
|
||||
ld a,0x81 ; illegal value - not normally seen
|
||||
ld (hl),a ; set so we don't change
|
||||
nodolr: cp '@'
|
||||
jr nz,nobang
|
||||
ld a,0x82 ; ditto
|
||||
ld (hl),a
|
||||
nobang: ld de,auxlin ; where the line is
|
||||
ld hl,(ppp) ; where we want it to go
|
||||
xferlp: ld a,(de)
|
||||
ld (hl),a ; move a byte
|
||||
inc hl
|
||||
inc de ; bong the pointers
|
||||
or a
|
||||
jr nz,xferlp ; loop till whole line is moved
|
||||
ld (ppp),hl
|
||||
inc c
|
||||
ld de,work - 4
|
||||
sbc hl,de ; did we overflow?
|
||||
jr c,loop ; no - back for more
|
||||
toobig: call ilprt
|
||||
db 'Script is too large (4K maximum)\r\n\0'
|
||||
ret
|
||||
|
||||
; come here when script has been read, labels noted and parameters set
|
||||
|
||||
cnvrt: xor a
|
||||
ld hl,(ppp)
|
||||
ld (hl),a ; add an empty line to terminate
|
||||
dec a
|
||||
ld (lbrcnt),a ; disable library count
|
||||
jr doscr
|
||||
|
||||
perr: call ilprt ; print an error msg
|
||||
db 'Bad line in file\r\n\0'
|
||||
call dim ; set dim mode
|
||||
ld hl,auxlin ; point hl at string
|
||||
erplp: ld a,(hl) ; get a character
|
||||
or a
|
||||
jr z,doneer ; exit if done
|
||||
push hl
|
||||
ld c,a
|
||||
call scrout ; send it
|
||||
pop hl
|
||||
inc hl
|
||||
jr erplp
|
||||
doneer: call crlf ; print a newline
|
||||
jp main ; and exit to terminal mode
|
||||
|
||||
doscr: ld a,0xff
|
||||
ld (b7flag),a ; clear bit 7 zap flag
|
||||
ld (cvtp),a
|
||||
ld a,1 ; initially state 1
|
||||
scrlp: or a
|
||||
jr nz,moresc
|
||||
push bc
|
||||
finisp: pop bc
|
||||
finis: call ilprt ; state zero means we're done
|
||||
db '\r\nDone\r\n\0'
|
||||
jp main ; straight to main to avoid a second redraw
|
||||
moresc: ld c,a ; save state in c for command recovery
|
||||
dec a
|
||||
ld b,a
|
||||
ld hl,script ; point at script
|
||||
jr z,rps ; if line 1, we're all set
|
||||
srlp: ld a,(hl)
|
||||
inc hl
|
||||
or a
|
||||
jr nz,srlp ; loop till we hit a null
|
||||
djnz srlp
|
||||
rps: ld (redptr),hl ; set up read pointer
|
||||
push bc ; save line number in c
|
||||
call getwl
|
||||
jr c,finisp ; all out of script, exit
|
||||
call parse ; chop it up
|
||||
jr c,perr ; drop on an error
|
||||
pop bc ; line number back to c
|
||||
xor a
|
||||
ld (curtry),a ; zero out current try
|
||||
retry: ld ix,area
|
||||
ld a,(sndlen)
|
||||
ld b,a
|
||||
or (ix + _explen) ; if both strings are empty
|
||||
jr z,finis ; we fell off end of script: return
|
||||
jp m,commnd ; explen == -1 => command type line: go do it
|
||||
push ix
|
||||
pop hl ; address to hl == address of send string
|
||||
ld a,b
|
||||
or a ; zero length?
|
||||
call nz,sendcs
|
||||
ld a,(ix + _explen) ; get expect length
|
||||
or a
|
||||
jr z,expok ; not expecting anything, match by default.
|
||||
call clerw2 ; clear the work buffer for incoming chars
|
||||
ld a,(mode)
|
||||
and lf_bit
|
||||
jr nz,scanex
|
||||
push ix
|
||||
call pexstr
|
||||
db '\r\nLooking for: \0'
|
||||
pop ix
|
||||
scanex: ld c,(ix + _time) ; get time to c
|
||||
second: ld de,600
|
||||
call setspd ; set the speed
|
||||
qrtrms: ld b,96 ; hang loose a while
|
||||
qmslp: djnz qmslp
|
||||
push hl
|
||||
push bc
|
||||
call procch ; ok, see what characters are waiting
|
||||
jr c,nochar ; nothing waiting - bypass all this mess
|
||||
call stufw2 ; and save in the other buffer
|
||||
ld hl,work2 + 257 + 64 + 1
|
||||
ld c,(ix + _explen)
|
||||
or a
|
||||
sbc hl,bc ; get that point in buffer
|
||||
ld de,expect ; expect string address to de
|
||||
chekxp: ld a,(de)
|
||||
cp (hl) ; did we match a byte?
|
||||
jr nz,nochar ; no - skip and try again
|
||||
ldi ; move pointers, adjust and test bc
|
||||
jp pe,chekxp ; not done: check some more
|
||||
gotit: pop bc ; got a match!
|
||||
pop de ; clean up stack first
|
||||
expok: ld a,(yes) ; get success state transition
|
||||
push af
|
||||
ld a,(explen) ; see if we actually had anything to match
|
||||
or a
|
||||
jr z,pjs ; nope, so skip all of this
|
||||
ld a,(mode)
|
||||
and mat_bit
|
||||
jr nz,pjs ; don't print if match disabled
|
||||
call pexstr
|
||||
db '\r\nMatch: \0' ; tell that we matched
|
||||
pjs: pop af ; restore success state
|
||||
jp scrlp
|
||||
nochar: pop bc
|
||||
pop hl
|
||||
dec hl ; count down second timer
|
||||
ld a,h
|
||||
or l
|
||||
jp nz,qrtrms
|
||||
dec c ; second timeout done?
|
||||
jp nz,second ; loop back if not
|
||||
ld a,(mode)
|
||||
and mat_bit
|
||||
jr nz,nopf ; don't print if match disabled
|
||||
push ix
|
||||
call ilprt
|
||||
db '\r\nFail\0' ; failed
|
||||
pop ix
|
||||
nopf: inc (ix + _curtry) ; bump try count
|
||||
ld a,(curtry)
|
||||
cp (ix + _tries) ; did we exceed allowed tries?
|
||||
jr nc,failed ; yes - complete fail - do state transition
|
||||
ld a,(mode)
|
||||
and mat_bit
|
||||
jr nz,jrt ; don't print if match disabled
|
||||
push ix
|
||||
call ilprt
|
||||
db ', retry\r\n\0'
|
||||
pop ix
|
||||
jrt: jp retry
|
||||
failed: ld a,(no) ; get fail state transition
|
||||
push af
|
||||
call crlf ; throw a new line
|
||||
jr pjs
|
||||
|
||||
.extern canscr
|
||||
canscr: call ilprt ; quit if so
|
||||
db '\r\nCancelled\r\n\0'
|
||||
jp main ; long jump to main since we don't know what
|
||||
; state the stack is in
|
||||
|
||||
commnd: ld a,c ; restore line number from c
|
||||
ld (prmpfl),a ; use non-zero value to set prompt flag
|
||||
push af ; save line number
|
||||
ld hl,cmdret
|
||||
push hl ; push a return address to get back here
|
||||
ld a,(time) ; get the command letter
|
||||
call ucsa ; force upper case
|
||||
ld hl,chttbl
|
||||
.dseg
|
||||
chttbl: table '.',break
|
||||
table 0x2c,hangup ; we'd like to say ',',hangup but ZSM barfs
|
||||
table 0x82,eval ; was @, but converted during readin to avoid
|
||||
; getwl substitute problems
|
||||
table 0x81,setstr ; was $, changed for the same reason.
|
||||
table '#',test
|
||||
table '%',stest
|
||||
table '&',mattog
|
||||
table '<',sinput
|
||||
table '>',messag
|
||||
table '~',cf
|
||||
table '[',multi
|
||||
table '(',fileio
|
||||
table 'B',baud
|
||||
table 'C',catch
|
||||
table 'E',echo
|
||||
table 'H',hdxtog
|
||||
table 'J',jctog
|
||||
table 'K',ldfnk
|
||||
table 'L',lftog
|
||||
table 'M',msbtog
|
||||
table 'N',newdsk
|
||||
table 'O',optog
|
||||
table 'P',print
|
||||
table 'Q',quit
|
||||
table 'R',recv
|
||||
table 'S',send
|
||||
table 'U',0x0276
|
||||
table 'V',vttog
|
||||
table 'W',witog
|
||||
table 'X',pchat
|
||||
table 'Y',hold
|
||||
table 'Z',cclose
|
||||
endctb:
|
||||
.cseg
|
||||
ld b,{endctb - chttbl} / 3
|
||||
tbllp: ld e,(hl)
|
||||
inc hl
|
||||
ld d,(hl) ; get next table entry to de
|
||||
inc hl
|
||||
cp (hl) ; check byte in a vs. table letter
|
||||
inc hl
|
||||
push de ; push entry point
|
||||
ret z ; if we matched this takes us to the code
|
||||
pop de ; restore stack
|
||||
djnz tbllp ; loop till we run out of table
|
||||
pop hl ; clean up stack
|
||||
cmdret: xor a
|
||||
ld (prmpfl),a ; clear prompt flag
|
||||
pop af ; get line number back
|
||||
inc a ; bump by one: commands always succeed
|
||||
jp scrlp ; loop back for more
|
||||
|
||||
.extern sendcs
|
||||
sendcs:
|
||||
inc b ; clear the zero flag, and account for an
|
||||
; extra djnz
|
||||
push bc
|
||||
push hl ; stack these for later popping
|
||||
jr sendi ; and jump to where we delay a bit
|
||||
|
||||
sendcl: push bc
|
||||
ld a,(hl) ; get next character
|
||||
inc hl ; bump
|
||||
push hl ; and save pointer
|
||||
cp 0xff ; was it a -1?
|
||||
jr nz,nosbrk ; no - check for -2
|
||||
call break ; send a break
|
||||
jr chrsnt
|
||||
nosbrk: cp 0xfe ; check for -2
|
||||
jr nz,mdmchr ; no - send char normally
|
||||
ld de,1200 ; set for a 1 second delay
|
||||
call msip ; 1000 1/1000th of a second == 1 second
|
||||
jr chrsnt ; and check for incoming chars
|
||||
mdmchr: push af
|
||||
call modop ; send the character
|
||||
pop af ; restore back to a
|
||||
chrsnt: call lstmod ; keep tabs on incoming chars
|
||||
call lstmod
|
||||
ld a,(slow)
|
||||
or a ; do we need to slow it down
|
||||
sendi: call nz,tenth ; wait a while if so
|
||||
pop hl
|
||||
pop bc
|
||||
djnz sendcl ; and keep on sending
|
||||
ret
|
||||
|
||||
parse: ld hl,area ; point de at this record
|
||||
push hl
|
||||
ld de,area + 1
|
||||
ld bc,_curtry
|
||||
ld (hl),b
|
||||
ldir ; nuke parse area
|
||||
pop de ; restore input pointer to de
|
||||
ld hl,auxlin
|
||||
ld a,(hl)
|
||||
cp '!' ; bang?
|
||||
jr nz,nopb ; nope - parse as usual
|
||||
inc hl
|
||||
ld a,(hl) ; get command letter
|
||||
inc hl
|
||||
ld bc,_explen ; move enough stuff to fill to explen
|
||||
ldir
|
||||
ex de,hl
|
||||
ld (hl),b ; null terminate just in case
|
||||
inc hl
|
||||
ld (hl),-1 ; set -1 in sndlen as a flag
|
||||
inc hl
|
||||
ld (hl),a ; and save the letter
|
||||
ret
|
||||
nopb: ld hl,slow
|
||||
ld (hl),b
|
||||
ld a,(auxlin) ; get delimiter
|
||||
cp 'z' + 1 ; greater than 'z'?
|
||||
jr c,noslow ; skip if not
|
||||
ld (hl),a ; else set slow flag
|
||||
noslow: ld hl,auxlin ; point hl at incoming line
|
||||
call scanst ; scan send string
|
||||
ret c
|
||||
ld (sndlen),a ; save length
|
||||
call scanst ; scan expect string
|
||||
ld (explen),a
|
||||
ret c ; exit if error
|
||||
xor a
|
||||
call rednum ; parse time
|
||||
ret c
|
||||
or a
|
||||
jr nz,gottim
|
||||
ld a,15 ; if no time or zero, default to 15
|
||||
gottim: ld de,time
|
||||
ld (de),a ; save the time
|
||||
inc de
|
||||
xor a
|
||||
call rednum ; scan tries
|
||||
ret c
|
||||
or a
|
||||
jr nz,gottry
|
||||
inc a ; if none or zero set to 1
|
||||
gottry: ld (de),a
|
||||
inc de
|
||||
pop bc
|
||||
ex (sp),hl
|
||||
ld a,l ; get cur line num to a
|
||||
ex (sp),hl
|
||||
push bc
|
||||
inc a ; add one to get default yes
|
||||
call rednum ; read success
|
||||
ret c
|
||||
ld (de),a
|
||||
inc de
|
||||
xor a
|
||||
call rednum ; and finally the fail value
|
||||
ret c
|
||||
ld (de),a
|
||||
inc a
|
||||
ret
|
||||
|
||||
.extern scanst
|
||||
scanst: ld b,40 ; count max of 40 chars
|
||||
ld a,(hl) ; get the delimiter to a
|
||||
ld (de),a
|
||||
or a
|
||||
ret z ; return with z to show empty line
|
||||
ld c,a ; copy to c
|
||||
inc hl ; point to next char
|
||||
|
||||
.extern scnstp
|
||||
scnstp: call parst ; chomp up the string
|
||||
ret c
|
||||
donest: ld a,40
|
||||
sub b ; get length to a
|
||||
dec b
|
||||
inc b ; test b for zero
|
||||
jr z,bzero ; if b not zero
|
||||
setde: inc de ; bump de
|
||||
djnz setde ; till b runs out
|
||||
bzero: or a ; clear the carry
|
||||
ret
|
||||
|
||||
.extern parst
|
||||
parst:
|
||||
xor a
|
||||
ld (de),a ; add a trailing null
|
||||
ld a,(hl) ; get next char
|
||||
cp c ; delimiter?
|
||||
ret z ; yes - all done on this string
|
||||
or a
|
||||
ccf
|
||||
ret z ; handle error
|
||||
inc hl
|
||||
cp '\\' ; backslash gets special treatment
|
||||
call z,backsl ; parse the backslash escape
|
||||
inc b
|
||||
dec b ; any space left?
|
||||
jr z,parst ; no - just get end of line
|
||||
dec b
|
||||
ld (de),a ; save the char away
|
||||
inc de
|
||||
jr parst
|
||||
|
||||
.extern backsl
|
||||
backsl: ld a,(hl) ; get char after backslash
|
||||
inc hl
|
||||
or a ; end of string?
|
||||
scf ; flip carry to true
|
||||
ret z ; return on zero w/ error
|
||||
cp 'k'
|
||||
jr nz,nobrk
|
||||
ld a,0xff
|
||||
ret
|
||||
nobrk: cp 'd'
|
||||
jr nz,nodel
|
||||
ld a,0xfe
|
||||
ret
|
||||
nodel: cp 'f'
|
||||
jr nz,noff
|
||||
ld a,'\f'
|
||||
ret
|
||||
noff: cp 'b'
|
||||
jr nz,nobksp
|
||||
ld a,'\b'
|
||||
ret
|
||||
nobksp: cp 't'
|
||||
jr nz,notab
|
||||
ld a,'\t'
|
||||
ret
|
||||
notab: cp 'n'
|
||||
jr nz,nonl
|
||||
ld a,'\n'
|
||||
ret
|
||||
nonl: cp 'r'
|
||||
jr nz,nocr
|
||||
ld a,'\r'
|
||||
ret
|
||||
nocr: cp 'e'
|
||||
jr nz,noesc
|
||||
ld a,'\e'
|
||||
ret
|
||||
noesc: cp 'x'
|
||||
jr nz,nohex
|
||||
push bc
|
||||
ld bc,0x0200
|
||||
gethex: ld a,(hl)
|
||||
sub '0'
|
||||
cp 10
|
||||
jr c,hexok ; valid digit - use it
|
||||
sub 'A' - '0'
|
||||
cp 6
|
||||
jr c,hexlok ; valid A-F
|
||||
sub 'a' - 'A'
|
||||
cp 6
|
||||
jr c,hexlok ; valid a-f
|
||||
ld a,b
|
||||
add a,0xfe ; check if b was still 2
|
||||
jr endoct
|
||||
hexlok: add a,10 ; letter values need 10 added
|
||||
hexok: inc hl ; bump pointer
|
||||
sla c
|
||||
sla c
|
||||
sla c
|
||||
sla c ; c *= 16
|
||||
or c ; a += c
|
||||
ld c,a
|
||||
djnz gethex
|
||||
jr endoct
|
||||
nohex: sub '0' ; check for octal digit
|
||||
cp 8
|
||||
jr c,octal ; got one - handle it
|
||||
add a,'0' ; restore character
|
||||
or a ; clear carry
|
||||
ret
|
||||
octal: push bc
|
||||
ld b,2 ; 2 more chars to get
|
||||
ld c,a ; save current value in c
|
||||
getoct: ld a,(hl) ; get another char
|
||||
sub '0'
|
||||
cp 8 ; convert and test
|
||||
jr nc,endoct ; no good - skip
|
||||
inc hl ; now we move the pointer
|
||||
sla c
|
||||
sla c
|
||||
sla c ; c *= 8
|
||||
or c ; a += c (and clear the carry)
|
||||
ld c,a ; back to c
|
||||
djnz getoct ; loop till three chars done
|
||||
endoct: ld a,c ; char back from c
|
||||
pop bc
|
||||
ret
|
||||
|
||||
rednum: ex af,af' ; save default value in a'
|
||||
ld a,(hl)
|
||||
or a ; get and test a delimiter
|
||||
jr z,usedef ; end of string - use default
|
||||
inc hl
|
||||
ld c,a ; save it away
|
||||
ld a,(hl)
|
||||
cp c ; check see if anything in field
|
||||
jr nz,isnum ; yes - go parse it
|
||||
usedef: ex af,af'
|
||||
ret
|
||||
isnum: ld b,0
|
||||
scnnum: ld a,(hl)
|
||||
or a
|
||||
jr z,usedef ; end of string: exit
|
||||
cp c
|
||||
jr z,gotnum ; found delimiter: exit
|
||||
inc hl
|
||||
sub '0'
|
||||
cp 10 ; did we find a digit?
|
||||
ccf ; flip carry: set => error
|
||||
ret c ; so return
|
||||
push af ; save converted digit
|
||||
ld a,b
|
||||
add a,a
|
||||
add a,a
|
||||
add a,b
|
||||
add a,a
|
||||
ld b,a ; b *= 10
|
||||
pop af
|
||||
add a,b
|
||||
ld b,a ; b += new digit
|
||||
jr scnnum
|
||||
gotnum: ld a,b
|
||||
ret
|
||||
|
||||
; label saves a label / line number pair in the symbol table
|
||||
|
||||
label: push hl ; save input pointer
|
||||
ld hl,work + 1016 ; look in symbol table
|
||||
ld de,8 ; step 8 at a time
|
||||
findlb: add hl,de ; move to next
|
||||
ld a,(hl)
|
||||
or a ; end of table?
|
||||
jr nz,findlb ; no - look at next one
|
||||
pop de ; input pointer back to de
|
||||
ld b,7 ; 7 bytes of label
|
||||
scanit: ld a,(de) ; get an input byte
|
||||
or a
|
||||
jr z,elbl ; null
|
||||
cp ' '
|
||||
jr z,elbl ; or space terminates it
|
||||
ld (hl),a
|
||||
inc de
|
||||
inc hl
|
||||
djnz scanit ; loop till 7 bytes moved
|
||||
jr addnum ; go add the line number
|
||||
elbl: ld (hl),0
|
||||
inc hl ; zero fill
|
||||
djnz elbl
|
||||
addnum: ld (hl),c ; save the line number
|
||||
xor a
|
||||
inc hl
|
||||
ld (hl),a ; zero fill end of symtab
|
||||
ld (work + 1528),a ; prevent overflow
|
||||
ret
|
||||
|
||||
; flabel - find a label / line number pair in the symbol table
|
||||
|
||||
flabel: ex de,hl ; label pointer to de
|
||||
ld hl,work + 1016 ; look in symbol table
|
||||
flblp: ld bc,8 ; step 8 at a time
|
||||
add hl,bc ; move to next
|
||||
ld a,(hl)
|
||||
or a ; end of table?
|
||||
jr z,exdert ; yes - undefined labels do odd things
|
||||
ld a,(de)
|
||||
cp (hl) ; check first char
|
||||
jr nz,flblp ; nope - try again
|
||||
push hl
|
||||
push de ; save pointers
|
||||
ld b,7 ; 7 bytes of label
|
||||
fscnit: ld a,(de) ; get an input byte
|
||||
or a
|
||||
jr z,nomtch ; end of input
|
||||
cp (hl)
|
||||
jr nz,nomtch ; no match, but it may be end of label
|
||||
inc de ; bump pointers
|
||||
endok: inc hl
|
||||
djnz fscnit ; all 7 bytes done: we got it
|
||||
ld a,(hl) ; get line number to a
|
||||
pop hl
|
||||
pop hl ; clean stack
|
||||
exdert: ex de,hl ; input pointer back to hl
|
||||
ret ; and home we go
|
||||
nomtch: ld a,(hl)
|
||||
or a
|
||||
jr z,endok ; aha - end of entry in symtab, fake it
|
||||
pop de
|
||||
pop hl ; no good, restore pointers
|
||||
jr flblp ; back to look at the next one
|
||||
|
||||
; fparam - find parameter from array at 0x80 whose number is in a
|
||||
|
||||
.extern fparam
|
||||
fparam: ld hl,strngs ; point at strings
|
||||
fplp: or a ; finished?
|
||||
ret z ; return if so - hl points to string
|
||||
ld e,a ; save a
|
||||
byppl: ld a,(hl) ; step over non-null characters
|
||||
inc hl
|
||||
or a
|
||||
jr nz,byppl
|
||||
ld a,e ; get string number back
|
||||
dec a ; one more done
|
||||
jr fplp
|
||||
|
||||
; kilstr - kill string parameter hl points to
|
||||
|
||||
.extern kilstr
|
||||
kilstr: ld a,(hl)
|
||||
or a
|
||||
ret z ; if it's already empty, we're done
|
||||
push hl ; save hl for later
|
||||
ld e,l
|
||||
ld d,h
|
||||
ksel: inc hl ; loop to find end of old string
|
||||
ld a,(hl)
|
||||
or a
|
||||
jr nz,ksel
|
||||
shftlp: ld a,(hl) ; by now hl points to end, de to string
|
||||
ldi ; move another byte
|
||||
inc a ; test for end of data
|
||||
jr nz,shftlp ; loop till all done
|
||||
ex de,hl
|
||||
xfill: ld (hl),0xff ; replace all the 0xffs
|
||||
inc hl
|
||||
ld a,(hl)
|
||||
cp 'A' ; we've got an 'A' at the end as a stopper
|
||||
jr nz,xfill
|
||||
pop hl ; restore pointer to string
|
||||
ret ; all done
|
||||
|
||||
; setstr - set a string variable
|
||||
|
||||
setstr: call areabu ; point hl at command tail
|
||||
call pnum
|
||||
ret nc
|
||||
inc hl ; skip over letter
|
||||
push hl ; and save address of source
|
||||
push af ; save parm number
|
||||
call fparam ; get ...
|
||||
pop af
|
||||
cp 9
|
||||
jr nc,repl ; 9 or above is letter string - force replace
|
||||
ld a,(hl)
|
||||
or a ; anything there yet?
|
||||
jr nz,pbcret ; yes - do nothing
|
||||
repl: call kilstr ; and kill current string
|
||||
ex (sp),hl ; save target, restore source
|
||||
call byp ; strip white space
|
||||
ex de,hl ; source to de
|
||||
pop hl ; dest back to hl
|
||||
xor a ; want this null terminated
|
||||
; and fall into insstr to put it in place
|
||||
|
||||
; insstr - shift string addressed by de to string var at hl, use char in
|
||||
; a (or null) to terminate string at de
|
||||
|
||||
.extern insstr
|
||||
insstr: push bc ; save bc
|
||||
ld b,a ; term char to b
|
||||
ld c,0 ; count in c
|
||||
push de ; save source in de
|
||||
fslen: ld a,(de)
|
||||
or a ; null
|
||||
jr z,estr1 ; ends the string
|
||||
cp b ; term char?
|
||||
jr z,estr ; yup end of string as well
|
||||
inc c ; count
|
||||
inc de ; and move pointer
|
||||
jr fslen
|
||||
estr: xor a
|
||||
estr1: ld b,a ; set len to word in bc
|
||||
cp c
|
||||
jr z,pop2r
|
||||
push hl ; save target in hl
|
||||
push bc ; and length as well
|
||||
inc bc
|
||||
ld hl,strngs + 511 ; start from very top of string space
|
||||
cpdr ; look for 0 on end of last string
|
||||
pop bc
|
||||
jr nz,isok ; nz means we didn't find it which is OK
|
||||
pop hl ; get hl back
|
||||
pop2r: pop bc
|
||||
pop bc ; clean up stack, de points to end already
|
||||
ret ; exit right now
|
||||
isok: pop de ; target back to de
|
||||
inc hl
|
||||
push hl ; source of lddr on stack
|
||||
sbc hl,de ; hl contains count to move up
|
||||
push bc ; length back on stack
|
||||
ld b,h
|
||||
ld c,l ; count to move to bc
|
||||
pop hl ; length back to hl
|
||||
ex (sp),hl ; resave length, get lower move point
|
||||
push de ; target back on stack
|
||||
ld de,strngs + 511
|
||||
inc bc ; why in the name of H*LL we have to inc this
|
||||
inc bc ; twice, I don't know. However, it works.
|
||||
lddr ; shift it all up to make the hole
|
||||
pop de ; target back
|
||||
pop bc ; length of string back
|
||||
pop hl ; source
|
||||
push de ; save target
|
||||
ldir ; move string into place
|
||||
ex de,hl ; updated source pointer back to de
|
||||
pop hl ; original hl back
|
||||
pbcret: pop bc ; restore bc
|
||||
ret
|
||||
|
||||
pnum:; call ucsa
|
||||
sub '1'
|
||||
cp 9 ; is it valid
|
||||
ret c ; default param
|
||||
sub 'A' - '1'
|
||||
cp 26 ; valid letter?
|
||||
ret nc ; return if not
|
||||
add a,9 ; convert above parameters
|
||||
scf ; set carry to show it's OK
|
||||
ret
|
||||
|
||||
; prepclv - convert command line args to $1 through $9
|
||||
|
||||
prepclv:
|
||||
ld de,0x80 ; point at command line params
|
||||
ld b,0 ; set counter to zero
|
||||
pcvlp: push de
|
||||
ld a,b
|
||||
call fparam ; address this parameter
|
||||
call kilstr ; get rid of the old
|
||||
pop de
|
||||
ex de,hl
|
||||
call byp ; find text
|
||||
ex de,hl
|
||||
ld a,' '
|
||||
call insstr ; drop the string in place
|
||||
inc b
|
||||
ld a,b
|
||||
cp 9 ; loop till nine are done
|
||||
jr nz,pcvlp
|
||||
ret
|
||||
|
||||
; get a line from wherever we're reading, stuff it in auxlin
|
||||
|
||||
getwl: ld hl,(redptr) ; pick up read pointer
|
||||
ld a,(hl)
|
||||
or a ; first byte zero?
|
||||
scf
|
||||
ret z ; return carry to show end of input
|
||||
ld de,auxlin ; auxlin is where we'll put it
|
||||
gwlp: ld a,(hl) ; get a byte
|
||||
cp '$'
|
||||
jr z,gwstr ; substitute strings,
|
||||
cp '@'
|
||||
jr z,gwnum ; numbers
|
||||
cp '`'
|
||||
jr z,gwlbl ; and labels
|
||||
nullt: ld a,(hl)
|
||||
ldi ; otherwise just transfer
|
||||
or a ; and test the byte
|
||||
jr nz,gwlp ; loop if more
|
||||
ld (redptr),hl ; save updated read pointer
|
||||
ret
|
||||
|
||||
gwstr: inc hl ; point at letter code for string wanted
|
||||
call ucsahl
|
||||
; ld a,(hl) ; get it
|
||||
call pnum ; see if it's a valid string number
|
||||
jr nc,nullt ; if not just copy the character as is
|
||||
inc hl
|
||||
push hl ; save string we're reading from
|
||||
push de
|
||||
call fparam ; get the string
|
||||
pop de
|
||||
scp: ld a,(hl)
|
||||
or a
|
||||
jr z,phlgwl
|
||||
ldi
|
||||
jr scp
|
||||
phlgwl: pop hl
|
||||
jr gwlp
|
||||
|
||||
gwnum: inc hl ; point at variable letter
|
||||
call ucsahl ; convert to upper case
|
||||
sub 'A' ; make it into an index
|
||||
cp 26 ; in range?
|
||||
jr nc,nullt ; nope - convert as a straight letter
|
||||
inc hl ; skip over the variable number
|
||||
push hl ; save source
|
||||
push de ; and target
|
||||
ld e,a
|
||||
ld d,0
|
||||
ld hl,vars
|
||||
add hl,de
|
||||
ld a,(hl) ; fetch the value
|
||||
pop hl ; restore target to hl
|
||||
jr dumpa
|
||||
|
||||
gwlbl: inc hl
|
||||
push de ; save target
|
||||
call flabel ; find the label
|
||||
inc a
|
||||
ex (sp),hl ; restore target, save source
|
||||
|
||||
dumpa: ld (hl),'0' - 1 ; put in hundreds digit
|
||||
ld e,0
|
||||
hundlp: inc (hl)
|
||||
sub 100
|
||||
jr nc,hundlp
|
||||
add a,100
|
||||
call cinc
|
||||
ld (hl),'0' - 1
|
||||
tenlp: inc (hl)
|
||||
sub 10
|
||||
jr nc,tenlp
|
||||
call cinc
|
||||
add a,'0' + 10
|
||||
ld (hl),a
|
||||
inc hl
|
||||
ex de,hl ; target back to de
|
||||
pop hl ; source to hl
|
||||
jr gwlp ; and we're done
|
||||
|
||||
; cinc - inc hl only if (hl) != 0: used to format numbers
|
||||
|
||||
cinc: dec e
|
||||
inc e ; test e
|
||||
jr nz,docinc ; already set, force a save
|
||||
ld c,a ; save a
|
||||
ld a,(hl)
|
||||
cp '0' ; pointing at a zero?
|
||||
ld a,c ; restore a
|
||||
ret z ; return if so,
|
||||
docinc: inc hl ; otherwise bump hl
|
||||
inc e ; and set e
|
||||
ret
|
||||
|
||||
; print expect string, but ignore control characters
|
||||
|
||||
pexstr: call dim ; dim mode
|
||||
pop hl
|
||||
call prtslp ; print inline string
|
||||
push hl ; resave return address
|
||||
ld hl,expect
|
||||
ld bc,(explen - 1) ; get explen to b
|
||||
prtncc: ld a,(hl) ; get a character
|
||||
cp ' '
|
||||
jr c,nopcc ; less than space, don't print
|
||||
cp 0x7f ; check >= delete
|
||||
push bc
|
||||
push hl
|
||||
ld c,a ; char to c for printout
|
||||
call c,scrout ; out it goes if legal
|
||||
pop hl
|
||||
pop bc
|
||||
nopcc: inc hl ; move pointer
|
||||
djnz prtncc ; loop till all done
|
||||
jp crlf
|
||||
|
||||
.dseg
|
||||
.extern scning
|
||||
scning: db 0
|
||||
.extern opentr
|
||||
opentr: db 0 ; should be useg, but need to bump hl for lbrs
|
||||
.extern lbrs
|
||||
lbrs: db '/QTERM.LBR\0' ; name of qterm script library
|
||||
|
||||
.useg
|
||||
redptr: ds 2
|
||||
.extern ppp
|
||||
ppp: ds 2 ; parameter pointer
|
||||
.extern chtusr
|
||||
chtusr: ds 1 ; extra drive / user to try for chat scripts
|
||||
.extern chtdrv
|
||||
chtdrv: ds 1
|
||||
cvtp: ds 1 ; do we convert params and numbers in getwl
|
||||
|
144
source/DIR.Z
Normal file
144
source/DIR.Z
Normal file
@ -0,0 +1,144 @@
|
||||
; dir.z - print directories for qterm
|
||||
|
||||
.incl "c:vars"
|
||||
|
||||
.extern dir
|
||||
dir:
|
||||
call gauxfc ; get a fcb into auxfcb
|
||||
ld hl,auxfcb + 2
|
||||
ld a,(hl) ; get first actual character of filename
|
||||
cp ' '
|
||||
jr nz,isfil ; not a space - there was something
|
||||
ld de,auxfcb + 3
|
||||
ld bc,10
|
||||
ld (hl),'?' ; else fill with '?'s to do *.*
|
||||
ldir
|
||||
isfil: ld c,26
|
||||
ld de,auxlin
|
||||
call bdos
|
||||
call dim ; set dim mode
|
||||
call clrpsp ; set up to page output
|
||||
ld c,17
|
||||
xor a
|
||||
ld (nlp),a
|
||||
push af
|
||||
dslp: ld de,auxfcb
|
||||
call usrbds
|
||||
inc a
|
||||
jr z,dirxit
|
||||
push af
|
||||
ld a,(auxfcb + 1) ; get the drive code
|
||||
add a,'@' ; convert to a letter
|
||||
call tabexp ; and print it
|
||||
ld hl,(auxfcb) ; get the user number
|
||||
call decob ; print it too
|
||||
ld a,':'
|
||||
call tabexp ; and a colon
|
||||
pop af
|
||||
rrca
|
||||
rrca
|
||||
rrca
|
||||
ld hl,auxlin - 31
|
||||
ld e,a
|
||||
ld d,0
|
||||
add hl,de
|
||||
ld b,8 ; 8 chars filename
|
||||
call pdir ; print filename
|
||||
ld a,'.'
|
||||
push hl ; save fcb address
|
||||
call tabexp ; print a period
|
||||
pop hl
|
||||
ld b,3
|
||||
call pdir ; and print the extension
|
||||
dec hl
|
||||
dec hl
|
||||
ld a,(hl) ; let's see about R/O files
|
||||
add a,a
|
||||
dec hl
|
||||
ld a,(hl)
|
||||
adc a,a
|
||||
adc a,a ; get r/o and sys bits to bottom
|
||||
ld hl,rostr ; look at characters we have
|
||||
.dseg
|
||||
rostr: db ' -+*'
|
||||
.cseg
|
||||
and 3 ; get just the bits we want
|
||||
ld e,a
|
||||
ld d,0
|
||||
add hl,de ; index into characters
|
||||
ld a,(hl) ; get one
|
||||
call tabexp ; and print it
|
||||
pop af
|
||||
inc a
|
||||
push af
|
||||
and 3
|
||||
ld hl,sstr
|
||||
.dseg
|
||||
sstr: db ' \0' ; 3 spaces to separate
|
||||
.cseg
|
||||
jr nz,sepspc
|
||||
ld hl,crlfm
|
||||
sepspc: call prtsl1
|
||||
; for ^X to can a directory, add a 'jr c,dirxit' here
|
||||
ds18: ld c,18
|
||||
jr dslp
|
||||
|
||||
dirxit: pop af ; restore file count
|
||||
or a
|
||||
jr z,nfm
|
||||
and 3
|
||||
call nz,crlf ; print newline if needed
|
||||
jp bright ; otherwise restore bright mode
|
||||
nfm: call ilprt
|
||||
db 'No files'
|
||||
crlfm: db '\r\n\0' ; complain if no files
|
||||
ret
|
||||
|
||||
; pdir - print chars from hl, count in b
|
||||
|
||||
pdir: ld a,(hl) ; get next char
|
||||
inc hl
|
||||
and 0x7f ; get rid of top bit
|
||||
push hl ; save regs
|
||||
push bc
|
||||
call tabexp ; print it
|
||||
pop bc
|
||||
pop hl
|
||||
djnz pdir ; loop till all done
|
||||
ret
|
||||
|
||||
; nxtnam - get next name from work to fcb, return z if no files left
|
||||
|
||||
.extern nxtnam
|
||||
nxtnam:
|
||||
ld hl,(fnbspt) ; get last address saved to
|
||||
ld de,(fnbrpt) ; current read address
|
||||
or a
|
||||
sbc hl,de ; test them
|
||||
ret z ; return z if equal
|
||||
ex de,hl ; read address to hl
|
||||
ld de,fcb ; fcb address to de
|
||||
ld bc,16 ; 16 chars to go
|
||||
ldir ; move them
|
||||
ld (fnbrpt),hl ; and save read pointer
|
||||
ld a,(fcb) ; get lead byte
|
||||
cp 0xe5 ; check for erasure
|
||||
jr z,nxtnam ; loop back if gone
|
||||
ld a,b
|
||||
ld (fcb + 13),a
|
||||
ld (fcb + 33),a ; zero out extent and block numbers
|
||||
ret ; ret with no z flag
|
||||
|
||||
; data area
|
||||
|
||||
.useg
|
||||
.extern newusr
|
||||
newusr: ds 1 ; new user for dir command
|
||||
.extern newdrv
|
||||
newdrv: ds 1 ; new drive for dir command
|
||||
nlp: ds 1 ; number of lines on current page
|
||||
.extern fnbspt
|
||||
fnbspt: ds 2 ; fnbuff save pointer
|
||||
.extern fnbrpt
|
||||
fnbrpt: ds 2 ; fnbuff read pointer
|
||||
|
434
source/FILE.Z
Normal file
434
source/FILE.Z
Normal file
@ -0,0 +1,434 @@
|
||||
; file.z - file handling odds and ends
|
||||
|
||||
.incl "c:vars"
|
||||
|
||||
.extern gofil ; get a filename, and open into auxfcb
|
||||
gofil:
|
||||
call gauxfc ; get a filename, parse in aux fcb
|
||||
ret c ; esc - exit now
|
||||
jr z,nowc ; no wildcards
|
||||
|
||||
.extern opnaux
|
||||
opnaux:
|
||||
xor a
|
||||
call clrw2 ; set pointers for read
|
||||
ld de,auxfcb
|
||||
ld c,open ; open the file
|
||||
call usrbds
|
||||
add a,1
|
||||
ret nc ; return now if open ok
|
||||
ld a,(scning)
|
||||
add a,a
|
||||
ret c
|
||||
|
||||
.extern fnferr
|
||||
fnferr: call ilprt ; beef and complain about file not found
|
||||
db 'File not found\r\n\0'
|
||||
scf
|
||||
ret
|
||||
|
||||
.extern nowc
|
||||
nowc:
|
||||
.extern nowcp
|
||||
nowcp:
|
||||
call ilprt
|
||||
db 'Can\'t handle wildcards\r\n\0'
|
||||
scf
|
||||
ret
|
||||
|
||||
.extern gauxfc
|
||||
gauxfc:
|
||||
call getfcb ; get a filename to fcb at 0x5b
|
||||
push af ; save return status in carry
|
||||
call byp
|
||||
ld (ppp),hl ; save pointer for chat
|
||||
pop af ; restore carry
|
||||
|
||||
.extern xferax
|
||||
xferax: ; transfer fcb at fbc to auxfcb
|
||||
ld bc,34 ; load the registers
|
||||
|
||||
.extern xferaz
|
||||
xferaz:
|
||||
ld hl,fcb
|
||||
ld de,auxfcb
|
||||
ldir ; and copy to auxfcb
|
||||
ret
|
||||
|
||||
.extern getfcb
|
||||
getfcb:
|
||||
call prompt
|
||||
db 'Filename? \0' ; prompt and input
|
||||
ld a,(ipbuf)
|
||||
cp '\e' ; carry?
|
||||
scf
|
||||
ret z ; return now with carry if so
|
||||
ld hl,ipbuf
|
||||
|
||||
.extern scnfcb ; parse a fcb at hl to 0x5b
|
||||
scnfcb:
|
||||
call byp ; step over any spaces
|
||||
push hl
|
||||
ld hl,fcb
|
||||
ld de,fcb + 1
|
||||
ld bc,33
|
||||
ld (hl),b
|
||||
ldir ; fill fcb with zeros
|
||||
ld bc,(curusr)
|
||||
inc b ; bump logged drive for fcb
|
||||
ld (fcb),bc ; drop in user and drive now
|
||||
pop hl ; get input pointer to hl
|
||||
push hl ; but save it again
|
||||
call ucsahl ; get (possible) drive spec to a
|
||||
cp 'A'
|
||||
jr c,trynum
|
||||
cp 'P' + 1 ; valid drive letter?
|
||||
jr nc,respar
|
||||
sub '@'
|
||||
ld b,a ; save the drive in b
|
||||
inc hl
|
||||
ld a,(hl) ; get the next letter
|
||||
cp ':' ; is it a ':'?
|
||||
jr z,usebc ; yes, only drive was given: use what we have
|
||||
trynum: sub '0'
|
||||
cp 10 ; do we have a valid digit?
|
||||
jr nc,respar ; no - reset and ignore whole mess
|
||||
scnusr: ld c,a ; save in c
|
||||
inc hl
|
||||
ld a,(hl) ; get the next letter
|
||||
cp ':' ; is it a ':'?
|
||||
jr z,usebc ; yes - we got a user: go process it all
|
||||
sub '0'
|
||||
cp 10
|
||||
jr nc,respar ; oops - not a number: reset and ignore
|
||||
ld e,a ; current digit to e
|
||||
ld a,c
|
||||
add a,a
|
||||
add a,a
|
||||
add a,c
|
||||
add a,a ; a = c * 10
|
||||
add a,e ; + e
|
||||
and 0x1f ; and 0x1f gives updated user number
|
||||
jr scnusr ; loop back for another go
|
||||
usebc: inc hl ; point at char after ':'
|
||||
ex (sp),hl ; save on stack
|
||||
ld (fcb),bc ; save new drive / user codes away
|
||||
respar: pop hl ; hl points at filename
|
||||
ld de,fcb + 2 ; point de at name area
|
||||
ld b,8
|
||||
call scanfn ; parse the filenane
|
||||
ld a,(hl)
|
||||
cp '.' ; '.' => extension
|
||||
jr nz,nodot
|
||||
inc hl ; step over it
|
||||
nodot: ld b,3
|
||||
call scanfn ; parse it
|
||||
push hl ; save pointer to text
|
||||
ld hl,fcb + 2
|
||||
ld a,'?' ; check for '?'s in the fcb (wildcards)
|
||||
ld bc,11
|
||||
cpir
|
||||
pop hl ; restore text pointer
|
||||
ret ; with z flag set for a match
|
||||
|
||||
scanfn: call ucsahl ; get a char
|
||||
or a ; exit on a zero byte
|
||||
jr z,gotnam
|
||||
cp '.' ; or a '.'
|
||||
jr z,gotnam
|
||||
cp ' ' ; or a ' '
|
||||
jr z,gotnam
|
||||
inc hl ; move input pointer
|
||||
dec b
|
||||
inc b ; test b
|
||||
jr z,scanfn ; loop back if zero
|
||||
ld (de),a ; save char in fcb
|
||||
cp '*' ; '*'?
|
||||
jr z,gotstr ; handle elsewhere if so
|
||||
inc de ; move output pointer
|
||||
dec b ; one less char to go
|
||||
jr scanfn
|
||||
gotnam: dec b ; decrease b till all done
|
||||
ret m
|
||||
ld a,' ' ; get a space
|
||||
ld (de),a ; put it in fcb
|
||||
inc de ; and move pointer
|
||||
jr gotnam
|
||||
gotstr: ld a,'?' ; put in a '?'
|
||||
ld (de),a
|
||||
inc de ; move pointer
|
||||
djnz gotstr ; loop till all full of '?'s
|
||||
jr scanfn ; continue parse
|
||||
|
||||
.extern areabu
|
||||
areabu: call areabp ; do an areabp, and ucsa the char
|
||||
|
||||
.extern ucsahl
|
||||
ucsahl: ld a,(hl) ; get char at hl
|
||||
|
||||
.extern ucsa
|
||||
ucsa: cp 'a'
|
||||
ret c ; return if it's below 'a'
|
||||
cp 'z' + 1
|
||||
ret nc ; or if it's above 'z'
|
||||
and 0x5f ; force lower case
|
||||
ret
|
||||
|
||||
; scnwld - enter with hl pointing at a filename, and add the list of
|
||||
; matching filenames to the list at fnbrpt / fnbspt
|
||||
|
||||
.extern scnwld
|
||||
scnwld:
|
||||
call byp ; strip leading space
|
||||
push hl ; save hl
|
||||
call scnfcb ; get a filename
|
||||
call xferax ; transfer to auxfcb
|
||||
ld hl,(auxfcb)
|
||||
ld (newusr),hl ; keep a copy of the drive and user
|
||||
ld de,auxlin
|
||||
ld c,setdma
|
||||
call bdos ; set dma to auxlin (seems like a safe place)
|
||||
ld c,srchf ; do a search first first time
|
||||
scnlp: ld de,auxfcb
|
||||
call usrbds ; any more names?
|
||||
inc a
|
||||
jr z,scannd ; exit if not
|
||||
rrca
|
||||
rrca
|
||||
rrca ; a *= 32
|
||||
ld de,(fnbspt)
|
||||
ld hl,work + 1024 ; out of room?
|
||||
or a
|
||||
sbc hl,de
|
||||
jr z,nosav ; skip if so - that's 64 filenames anyway!
|
||||
ld hl,(newusr) ; get drive and user
|
||||
ex de,hl
|
||||
ld (hl),e
|
||||
inc hl
|
||||
ld (hl),d ; and install them
|
||||
inc hl
|
||||
ex de,hl ; save save pointer in de
|
||||
ld l,a
|
||||
ld h,0
|
||||
ld bc,auxlin - 31 ; -32 because of the inc a above
|
||||
add hl,bc ; hl now points at name portion
|
||||
ld bc,14 ; 11 chars to transfer, + 3 for spacing
|
||||
ldir ; move them characters
|
||||
ld (fnbspt),de ; put save pointer back away
|
||||
nosav: ld c,srchn ; go look for next name
|
||||
jr scnlp
|
||||
scannd: pop hl ; restore string pointer
|
||||
; and step over filename to next one
|
||||
|
||||
.extern unbyp ; move a string pointer in hl to the end of
|
||||
unbyp: ; the current word
|
||||
ld a,(hl)
|
||||
cp ' '
|
||||
ret z ; stop when we hit a space
|
||||
or a
|
||||
ret z ; or a zero
|
||||
inc hl
|
||||
jr unbyp
|
||||
|
||||
.extern getlin ; read a line of data from file
|
||||
getlin:
|
||||
ld de,auxlin ; we'll save data in auxlin
|
||||
gallp: xor a
|
||||
ld (de),a ; set zero for end of line
|
||||
push de
|
||||
call getw2c ; get a character
|
||||
pop de
|
||||
ret c ; return carry on physical end of file
|
||||
cp 0x1a
|
||||
scf
|
||||
ret z ; or logical end of file
|
||||
cp 0x0d
|
||||
jr z,glstrp ; end of line - stip trailing blanks
|
||||
cp 0x7f
|
||||
jr z,gallp ; ignore deletes
|
||||
cp ' '
|
||||
jr c,gallp ; and other control characters
|
||||
ld (de),a ; save it
|
||||
ld hl,auxlin + 127
|
||||
or a
|
||||
sbc hl,de ; check line length
|
||||
jr z,gallp
|
||||
inc de ; and bump pointer if not at end of line
|
||||
jr gallp
|
||||
glstrp: ld hl,auxlin
|
||||
or a
|
||||
sbc hl,de ; did we hit the start of the line?
|
||||
ret z ; return if so
|
||||
dec de
|
||||
ld a,(de) ; look at previous character
|
||||
xor ' ' ; is it a space?
|
||||
ret nz ; no - leave it and return
|
||||
ld (de),a ; else turn it into a zero
|
||||
jr glstrp
|
||||
|
||||
.extern print ; print a local file to the remote
|
||||
print:
|
||||
call gofil ; get and open file
|
||||
ret c ; exit now on an error
|
||||
ld a,0x7f
|
||||
ld (b7flag),a ; set flag to strip bit 7
|
||||
ld a,2
|
||||
ld (cscqfl),a ; enable ctrl ^S ^Q spotting
|
||||
plp: call lstmod ; check incoming chars
|
||||
call kbdcc ; check the keyboard
|
||||
cp 'x' & 0x1f ; quit on a typed ^X
|
||||
jr z,prsent
|
||||
ld a,(cscqfl) ; ^S seen?
|
||||
rrca
|
||||
jr c,plp ; yes, so loop for a while
|
||||
call getw2c ; get next char to send
|
||||
jr c,prsent ; exit on physical end of file
|
||||
and 0x7f
|
||||
cp 0x1a
|
||||
jr z,prsent ; or logical end of file
|
||||
cp '\n'
|
||||
jr nz,nonlin ; not a linefeed
|
||||
ld a,(lflg)
|
||||
or a ; are we sending these?
|
||||
plpz: jr z,plp ; it gets thrown if disabled
|
||||
ld a,'\n'
|
||||
nonlin:
|
||||
cp ' '
|
||||
jr c,sendit ; if it's a control char, no echo check
|
||||
ld hl,ecflg
|
||||
inc (hl)
|
||||
dec (hl) ; echo check enabled?
|
||||
jr z,sendit ; nope - send as is
|
||||
inc hl
|
||||
ld (hl),a ; save echo check value
|
||||
sendit: push af ; save the char
|
||||
call modop ; send it
|
||||
ld a,(chd) ; get the character delay
|
||||
ld e,a
|
||||
ld d,0 ; to de
|
||||
pop af
|
||||
cp '\r' ; did we just send a return?
|
||||
jr nz,pwait ; nope - handle char delay / echo check
|
||||
ld de,(nld) ; get new line delay
|
||||
ld a,(lfecho) ; linefeed echo enabled?
|
||||
ld (ecval),a ; save it if so
|
||||
ld (lfwflg),a ; set linefeed wait flag if needed
|
||||
pwait: call setspd ; make a clock dependant value in hl
|
||||
add hl,hl ; and double it
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,pwlp
|
||||
inc l ; minimum 1
|
||||
pwlp: push hl
|
||||
call lstmod ; keep an eye on returning chars
|
||||
pop hl
|
||||
ld a,(ecval) ; echo check in progress?
|
||||
dec a
|
||||
jr z,ecok ; we got the needed char - break
|
||||
dec hl
|
||||
ld a,h
|
||||
or l ; count hl down
|
||||
jr nz,pwlp
|
||||
ecok: ld (ecval),a ; set echo check value to zero
|
||||
ld hl,lfwflg ; look at linefeed wait flag
|
||||
ld a,(hl)
|
||||
ld de,100 ; 100 ms delay in de (prototype)
|
||||
ld (hl),d ; turn linefeed wait flag off
|
||||
or a ; test original value
|
||||
jr z,plpz ; back to send next character if not there
|
||||
jr pwait ; back to wait again for the extra 1/10th sec.
|
||||
|
||||
prsent: call ilprt
|
||||
db '\r\nSent\r\n\0'
|
||||
jr cb7
|
||||
|
||||
.extern type ; type a file locally
|
||||
type:
|
||||
call gofil ; get and open the file
|
||||
ret c ; quit now on an error
|
||||
ld a,0x7f
|
||||
ld (b7flag),a ; set flag to strip bit 7
|
||||
call dim ; dim mode
|
||||
call clrpsp
|
||||
tlp: call getw2c ; get a character
|
||||
jr c,teof ; exit on eof
|
||||
cp 0x1a
|
||||
jr z,teof ; and on CP/M eof char
|
||||
call limitc
|
||||
jr c,tlp
|
||||
ld (lco),a ; save in last char
|
||||
call tabexp ; type it
|
||||
jr nc,tlp ; loop unless ^X cancelled
|
||||
teof: ld a,(lco)
|
||||
cp '\n'
|
||||
call nz,crlf ; output a newline if needed
|
||||
call bright ; back to bright
|
||||
cb7: xor a
|
||||
ld (cscqfl),a ; clear ^S ^Q flag
|
||||
dec a ; effectively ld a,0xff
|
||||
ld (b7flag),a ; clear bit 7 zap mask
|
||||
ret
|
||||
|
||||
.extern newdsk
|
||||
newdsk:
|
||||
call prompt
|
||||
db 'Drive? \0' ; prompt and input
|
||||
ld hl,ipbuf ; parse a full fcb, although we only want
|
||||
call scnfcb ; drive and user
|
||||
ld hl,(fcb) ; get new values
|
||||
dec h ; set drive correct
|
||||
ld (curusr),hl ; and save them
|
||||
|
||||
.extern reset ; reset: simply reset CP/M to remove R/O
|
||||
reset: ; status on changed disks
|
||||
ld a,(cflg)
|
||||
or a ; catch file open?
|
||||
ld c,rescpm
|
||||
jr z,zbdos ; nope, full reset
|
||||
ld a,(cfcb + 1) ; get catch file drive
|
||||
ld hl,fcb + 1
|
||||
cp (hl) ; same as reset drive?
|
||||
ret z ; yes, exit now
|
||||
dec a
|
||||
ld e,a
|
||||
ld c,seldrv ; select chat file drive
|
||||
call bdos
|
||||
ld a,(fcb + 1) ; get reset drive
|
||||
ld hl,1 ; set hl to 1
|
||||
ld c,logdrv
|
||||
shlp: dec a ; count down
|
||||
zbdos: jp z,bdos ; jump to bdos when done
|
||||
add hl,hl
|
||||
jr shlp
|
||||
|
||||
.dseg
|
||||
.extern b7flag
|
||||
b7flag: db 0xff
|
||||
.extern cscqfl
|
||||
cscqfl: db 0
|
||||
|
||||
.extern lfecho
|
||||
lfecho: db 0
|
||||
.extern ecflg
|
||||
ecflg: db 0
|
||||
.extern ecval
|
||||
ecval: db 0
|
||||
lfwflg: db 0
|
||||
|
||||
.useg
|
||||
lco: ds 1
|
||||
.extern curusr
|
||||
curusr: ds 1
|
||||
.extern curdrv
|
||||
curdrv: ds 1
|
||||
.extern auxfcb
|
||||
auxfcb: ds 37
|
||||
.extern auxlin
|
||||
auxlin: ds 128
|
||||
.extern script
|
||||
script: ds 1024
|
||||
.extern scrwrk
|
||||
scrwrk: ds 3072
|
||||
.extern work
|
||||
work: ds 1536
|
||||
|
133
source/FLAGS.Z
Normal file
133
source/FLAGS.Z
Normal file
@ -0,0 +1,133 @@
|
||||
; flags.z - code to handle trivial flag toggles
|
||||
|
||||
.incl "c:termcap"
|
||||
|
||||
.var ipbuf 0x80
|
||||
|
||||
.extern msbtog
|
||||
msbtog: call force ; go see what we're doing to the flag
|
||||
ld hl,bmask ; address where mask lives
|
||||
jr z,domsbt ; zero => straight toggle
|
||||
sub '0' ; was it a '0'?
|
||||
res 7,(hl)
|
||||
jr z,domsbt ; bit 7 off (so it gets turned on) if so
|
||||
set 7,(hl) ; else bit 7 on, so it gets turned off
|
||||
domsbt: ld a,(hl)
|
||||
xor 0x80 ; toggle the bit
|
||||
ld (hl),a
|
||||
inc a ; now 0xff => no mask becomes zero
|
||||
ld de,bit7ms ; point de at the "label"
|
||||
.dseg
|
||||
bit7ms: db 'Bit 7 masking\0'
|
||||
.cseg
|
||||
jr pdisen ; and print whether we turned it on or off
|
||||
|
||||
.extern echo
|
||||
echo: ld hl,eflg ; point at echo flag
|
||||
ld de,ecomsg ; and message
|
||||
.dseg
|
||||
ecomsg: db 'Remote echo\0'
|
||||
.cseg
|
||||
jr toggle ; go do the toggle
|
||||
|
||||
.extern hdxtog
|
||||
hdxtog: ld hl,hflg ; same as echo
|
||||
ld de,hdxmsg
|
||||
.dseg
|
||||
hdxmsg: db 'Half duplex\0'
|
||||
.cseg
|
||||
jr toggle
|
||||
|
||||
.extern jctog
|
||||
jctog: ld hl,jflg ; same as echo
|
||||
ld de,jcmsg
|
||||
.dseg
|
||||
jcmsg: db 'Control character discard\0'
|
||||
.cseg
|
||||
jr toggle
|
||||
|
||||
.extern lftog
|
||||
lftog: ld hl,lflg ; same as echo
|
||||
ld de,lfmsg
|
||||
.dseg
|
||||
lfmsg: db 'Line feed in print\0'
|
||||
.cseg
|
||||
jr toggle
|
||||
|
||||
.extern optog
|
||||
optog: ld hl,oflg ; same as echo
|
||||
ld de,opmsg
|
||||
.dseg
|
||||
opmsg: db 'Output to printer\0'
|
||||
.cseg
|
||||
jr toggle
|
||||
|
||||
.extern vttog
|
||||
vttog: call initv
|
||||
ld hl,vflg
|
||||
ld de,vtmsg
|
||||
.dseg
|
||||
vtmsg: db 'VT-100 emulation\0'
|
||||
.cseg
|
||||
toggle: call togflg ; flip the flag as needed
|
||||
pdisen: push af ; save flag state
|
||||
push de ; and message
|
||||
call crlf ; throw a new line
|
||||
call dim ; go into dim mode
|
||||
pop hl
|
||||
call prtslp ; print the message
|
||||
pop af ; restore the flag state
|
||||
jr z,pdis ; zero - it got disabled
|
||||
call ilprt
|
||||
db ' enabled\0' ; print the enabled message
|
||||
jr finis
|
||||
pdis: call ilprt
|
||||
db ' disabled\0' ; or disabled
|
||||
finis: jp crlf
|
||||
|
||||
.extern togflg
|
||||
togflg: push hl
|
||||
push de ; save some registers
|
||||
call force ; get input state depending on if we're in
|
||||
pop de ; a chat script
|
||||
pop hl
|
||||
jr z,doftog ; zero => straight toggle
|
||||
sub '0' ; '0' => turn it off
|
||||
set 0,(hl) ; turn the bit on so the xor turns it off
|
||||
jr z,doftog
|
||||
res 0,(hl) ; else clear bit - xor will set it
|
||||
doftog: ld a,(hl)
|
||||
xor 1 ; flip the bit
|
||||
ld (hl),a
|
||||
ret
|
||||
|
||||
force: ld a,(prmpfl)
|
||||
or a
|
||||
ret z ; return zero if we're not in a chat script
|
||||
call areabp ; get the character
|
||||
or a ; see if one was given
|
||||
ret
|
||||
|
||||
.dseg
|
||||
.extern bmask
|
||||
bmask: db 0xff
|
||||
.extern jflg
|
||||
jflg: db 0
|
||||
.extern lflg
|
||||
lflg: db 0
|
||||
.extern oflg
|
||||
oflg: db 0
|
||||
|
||||
; These next to _MUST_ remain adjacent, and in this order
|
||||
|
||||
.extern vflg
|
||||
vflg: db 0
|
||||
.extern wflg
|
||||
wflg: db 0
|
||||
|
||||
.extern hflg
|
||||
hflg: db 0
|
||||
|
||||
.extern eflg
|
||||
eflg: db 0
|
||||
|
20
source/KERMIT.I
Normal file
20
source/KERMIT.I
Normal file
@ -0,0 +1,20 @@
|
||||
; kermit.i - definitions for kermit file transfer code
|
||||
|
||||
.var MAXPSIZ 90 ; Maximum packet size
|
||||
.var MINPSIZ 20 ; minimum packet size
|
||||
.var SOH 1 ; Start of header
|
||||
.var DEL 0x7f ; Delete
|
||||
|
||||
.var MAXTRY 10 ; Times to retry a packet
|
||||
.var MYQUOTE '#' ; Quote character I will use
|
||||
.var MYHIBIT '&' ; char I use for hi-bit sending
|
||||
.var MYPACK '~' ; char I use for repeat packing
|
||||
.var MYPAD 0 ; Number of pad characters I need
|
||||
.var MYPCHAR 0 ; Padding character I need (NULL)
|
||||
|
||||
.var MYTIME 12 ; Seconds before I'm to be timed out
|
||||
.var MAXTIM 30 ; Maximum timeout interval
|
||||
.var MINTIM 4 ; Minumum timeout interval
|
||||
|
||||
.var MYEOL '\r' ; End-Of-Line character I need
|
||||
|
1121
source/KUTIL.Z
Normal file
1121
source/KUTIL.Z
Normal file
File diff suppressed because it is too large
Load Diff
10
source/MAKEQT.SUB
Normal file
10
source/MAKEQT.SUB
Normal file
@ -0,0 +1,10 @@
|
||||
xsub
|
||||
zc
|
||||
c:qterm.z c:termio.z c:vt100.z c:chat.z c:catch.z c:baud.z
|
||||
c:dir.z c:flags.z c:file.z c:odds.z c:cf.z c:send.z c:recv.z
|
||||
c:srutil.z c:sendk.z c:recvk.z c:kutil.z c:sendx.z c:recvx.z
|
||||
c:xutil.z c:srscrn.z
|
||||
c:shrink.z
|
||||
-x -l -s -be
|
||||
|
||||
|
658
source/ODDS.Z
Normal file
658
source/ODDS.Z
Normal file
@ -0,0 +1,658 @@
|
||||
; odds.z - code that has no place else to live
|
||||
|
||||
.incl "c:termcap"
|
||||
.incl "c:vars"
|
||||
|
||||
.var slow 86 ; should we slow down outgoing string
|
||||
|
||||
.extern prompt ; print an inline prompt then get a buffer
|
||||
prompt: ; full of data from the keyboard
|
||||
ld a,(prmpfl) ; see if we're in a chat script or not
|
||||
or a
|
||||
jr z,nochat ; no - do normal input
|
||||
push ix
|
||||
pop hl ; get string address to hl
|
||||
ld de,ipbuf
|
||||
ld bc,116 ; reasonable amount to copy
|
||||
ldir ; move it over, and we're done
|
||||
skipze: pop hl ; get string address - we have to skip over it
|
||||
skiplp: inc hl ; this relies on a non-empty string
|
||||
ld a,(hl)
|
||||
or a
|
||||
jr nz,skiplp ; skip till we reach the end
|
||||
jp (hl) ; and return to address in hl
|
||||
nochat: call dim ; set dim mode
|
||||
ld hl,crlfms
|
||||
call prtslp ; send a newline
|
||||
pop hl
|
||||
call prtslp ; print the prompt
|
||||
push hl
|
||||
ld de,ipbuf - 2 ; point at where we'll read info
|
||||
ld a,e
|
||||
ld (de),a ; set count
|
||||
ld c,buffin
|
||||
call bdos ; read a line
|
||||
ld hl,ipbuf - 1
|
||||
ld e,(hl) ; get count actually input
|
||||
ld d,h
|
||||
add hl,de
|
||||
inc hl ; turn into a buffer pointer
|
||||
ld (hl),d ; and zero terminate input data
|
||||
|
||||
.extern crlf ; just print a newline
|
||||
crlf:
|
||||
call ilprt
|
||||
crlfms: db '\r\n'
|
||||
zero: db 0
|
||||
ret
|
||||
|
||||
.extern ilprt
|
||||
ilprt: call dim ; in line print - start by going dim
|
||||
pop hl ; get string address
|
||||
call prtslp ; out it goes
|
||||
push hl ; restore return address - fall into bright
|
||||
|
||||
.extern bright
|
||||
bright: ld a,(tcbits)
|
||||
and b_brite ; do we have a bright string?
|
||||
ret z
|
||||
ld hl,bflag ; currently bright?
|
||||
ld a,(hl)
|
||||
dec a
|
||||
ret nz ; yes, don't resend
|
||||
ld (hl),a
|
||||
ld hl,brites ; get address of bright string
|
||||
jr prtslx ; and send it
|
||||
|
||||
.extern dim
|
||||
dim: ld a,(tcbits)
|
||||
and b_dim ; do we have a dim string?
|
||||
ret z
|
||||
ld hl,bflag ; currently dim?
|
||||
ld a,(hl)
|
||||
or a
|
||||
ret nz ; yes, don't resend
|
||||
inc (hl)
|
||||
ld hl,dims ; get address of dim string
|
||||
jr prtslx
|
||||
|
||||
.extern dellin
|
||||
dellin:
|
||||
ld hl,dlstr ; get address of dellin string
|
||||
jr prtslx ; and send it
|
||||
|
||||
.extern inslin
|
||||
inslin:
|
||||
ld hl,ilstr ; get address of inslin string
|
||||
jr prtslx ; and send it
|
||||
|
||||
.extern cleol
|
||||
cleol:
|
||||
ld hl,ceol ; get address of cleol string
|
||||
jr prtslx ; and send it
|
||||
|
||||
.extern cleos
|
||||
cleos:
|
||||
ld hl,ceos ; get address of cleos string
|
||||
jr prtslx ; and send it
|
||||
|
||||
.extern clear
|
||||
clear: ld hl,clrs ; get address of clear string
|
||||
|
||||
prtslx: ld a,h
|
||||
ld (optype),a
|
||||
call prtslp
|
||||
xor a
|
||||
ld (optype),a
|
||||
ret
|
||||
|
||||
.extern prtslp
|
||||
prtslp:
|
||||
call clrpcp
|
||||
|
||||
.extern prtsl1
|
||||
prtsl1:
|
||||
ld a,(hl)
|
||||
or a
|
||||
ret z
|
||||
inc hl
|
||||
push hl
|
||||
call tabexp
|
||||
pop hl
|
||||
; for ^X to can a long directory, add a 'ret c' here
|
||||
jr prtsl1
|
||||
|
||||
.extern tabexp
|
||||
tabexp:
|
||||
cp '\n'
|
||||
jr nz,nonl
|
||||
ld a,79
|
||||
ld (pos),a
|
||||
ld a,'\n'
|
||||
nonl: cp '\r'
|
||||
jr nz,nocr
|
||||
ld a,0xff
|
||||
ld (pos),a
|
||||
ld a,'\r'
|
||||
nocr: cp '\t'
|
||||
jr z,tablp
|
||||
call prtopc
|
||||
jr chk80
|
||||
tablp: ld a,' '
|
||||
call prtopc
|
||||
ld a,(pos)
|
||||
and 7
|
||||
jr nz,tablp
|
||||
chk80: ld hl,pos
|
||||
ld a,(hl)
|
||||
xor 80
|
||||
call z,newlin
|
||||
ret
|
||||
|
||||
prtopc: ld c,a
|
||||
ld a,(optype)
|
||||
or a
|
||||
ld a,c
|
||||
jp nz,scrout
|
||||
ld hl,mode
|
||||
ld e,(hl)
|
||||
push hl
|
||||
push de
|
||||
ld (hl),lf_bit
|
||||
call opchar
|
||||
pop de
|
||||
pop hl
|
||||
ld (hl),e
|
||||
ld hl,pos
|
||||
inc (hl)
|
||||
ret
|
||||
|
||||
newlin: ld (hl),a ; set char count back to zero
|
||||
inc hl ; point at line count
|
||||
inc (hl) ; bump that too
|
||||
ld a,(hl)
|
||||
xor 23 ; 23 lines?
|
||||
ret nz ; return if not
|
||||
ld a,(pagerf)
|
||||
or a
|
||||
ret z ; and return if not paging
|
||||
dec (hl) ; set back to 22 in case we get a return
|
||||
ld hl,mmsg
|
||||
.dseg
|
||||
mmsg: db '[more]\0'
|
||||
.cseg
|
||||
call prtsl1 ; print more message
|
||||
call kbdin ; get a character
|
||||
ld hl,cmstr
|
||||
.dseg
|
||||
cmstr: db '\r \r\0'
|
||||
.cseg
|
||||
cp (hl) ; return?
|
||||
jr z,clrmor ; yes - just remove '[more]', linec is set
|
||||
xor 'x' & 0x1f
|
||||
jr z,retcx ; special exit on a ^X
|
||||
xor a
|
||||
ld (linec),a ; else clear linc for a full page
|
||||
clrmor: jp prtsl1 ; and remove the more message
|
||||
|
||||
retcx: call prtsl1 ; come here after a ^X - we remove the message
|
||||
scf ; and return carry to flag the exit
|
||||
ret
|
||||
|
||||
.extern clrpsp
|
||||
clrpsp:
|
||||
db 0x3e ; makes a ld a,xx
|
||||
|
||||
.extern clrpcp
|
||||
clrpcp:
|
||||
xor a
|
||||
ld (pagerf),a
|
||||
push hl
|
||||
ld hl,0
|
||||
ld (pos),hl
|
||||
pop hl
|
||||
ret
|
||||
|
||||
.extern mtprt ; a call to this is followed by inline coords.
|
||||
mtprt: ; and a string to be printed at the coords
|
||||
pop hl
|
||||
ld e,(hl)
|
||||
inc hl
|
||||
ld d,(hl) ; get moveto coordinates
|
||||
inc hl
|
||||
push hl ; save address of string
|
||||
ex de,hl ; coords to hl
|
||||
call moveto ; move to wherever
|
||||
pop hl ; restore string to hl
|
||||
call prtslp ; print it
|
||||
jp (hl) ; and return
|
||||
|
||||
.extern decob ; print number in l, by zeroing h
|
||||
decob:
|
||||
ld h,0 ; clear h and fall through
|
||||
|
||||
.extern decout ; print number in hl in decimal
|
||||
decout:
|
||||
push de ; save running total
|
||||
push bc ; save char count
|
||||
ld bc,-10
|
||||
ld de,-1
|
||||
decou2: add hl,bc
|
||||
inc de
|
||||
jr c,decou2 ; divide hl by 10
|
||||
sbc hl,bc ; reset because of overflow
|
||||
ex de,hl ; remainder to e, answer to hl
|
||||
ld a,h
|
||||
or l
|
||||
pop bc ; restore char count for next call
|
||||
call nz,decout ; answer non-zero: print recursively
|
||||
ld a,e ; get remainder
|
||||
add a,'0'
|
||||
ld c,a
|
||||
push bc
|
||||
call scrout ; print to screen as a digit
|
||||
pop bc
|
||||
dec b ; keep count of printed chars in b
|
||||
pop de ; restore total
|
||||
ret
|
||||
|
||||
.extern break
|
||||
break:
|
||||
call tenth ; wait a while before beginning
|
||||
call sbreak ; start the break
|
||||
call tenth3 ; idle for 3/10 of a second
|
||||
jp ebreak ; finish off by ending the break
|
||||
|
||||
.extern hangup
|
||||
hangup:
|
||||
ld hl,#dtroff
|
||||
ld a,(hl)
|
||||
cp 0xc9 ; return at dtroff => no code
|
||||
jr z,strhup ; so send a string instead
|
||||
call dtroff ; drop dtr - should make modem hang up
|
||||
call tenth3
|
||||
call tenth3 ; wait a (long) while
|
||||
jp dtron ; dtr back on
|
||||
strhup: ld ix,hangup - slow
|
||||
inc hl
|
||||
ld b,(hl) ; get the string length
|
||||
inc hl
|
||||
jp sendcs ; and out it goes
|
||||
|
||||
tenth3: call tenth
|
||||
call tenth
|
||||
|
||||
.extern tenth ; delay for 1/10 of a second, but continue to
|
||||
tenth: ; save incoming chars
|
||||
ld de,100
|
||||
call setspd ; get speed constant to hl
|
||||
tnthlp: ld b,60
|
||||
tnthl1: djnz tnthl1 ; idle a while
|
||||
push hl
|
||||
call savrng ; check incoming chars, but only as far as
|
||||
pop hl ; the ring buffer
|
||||
dec hl ; count main timer
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,tnthlp
|
||||
ret
|
||||
|
||||
.extern tnthip ; delay for 1/10 of a second, but continue to
|
||||
tnthip: ; check the modem for incoming chars
|
||||
ld de,100
|
||||
|
||||
.extern msip ; delay for de msec, but continue to
|
||||
msip: ; check the modem for incoming chars
|
||||
ld a,d
|
||||
or e ; anything in de?
|
||||
ret z ; nope - return right now
|
||||
call setspd ; get speed constant to hl
|
||||
msil: ld b,60
|
||||
msl2: djnz msl2 ; idle a while
|
||||
push hl
|
||||
call lstmod ; process incoming chars and printer output
|
||||
pop hl
|
||||
dec hl ; count main timer
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,msil
|
||||
ret
|
||||
|
||||
.extern setspd ; take 1MHz value in de, get correct value in
|
||||
setspd: ; hl based on cpu speed
|
||||
ld hl,0
|
||||
ld a,(speed)
|
||||
ld b,a ; get cpu speed to b
|
||||
spdok: add hl,de ; multiply de by b
|
||||
djnz spdok
|
||||
ret
|
||||
|
||||
.extern help
|
||||
help:
|
||||
call crlf ; start off with a new line
|
||||
call dim ; and dim
|
||||
call presc ; print the escape character
|
||||
or a ; test the flag
|
||||
ld c,' '
|
||||
call z,scrout ; print a space if no '^'
|
||||
call ilprt ; and finish off
|
||||
db ' - Transmit escape character\t '
|
||||
db '? - Print this help\r\n'
|
||||
db '. - Send a break\t\t\t'
|
||||
db ', - Hang up modem\r\n'
|
||||
db 'B - Change baud rate and mode\t\t'
|
||||
db 'C - Open an input catch file\r\n'
|
||||
db 'D - Display local directory\t\t'
|
||||
db 'E - Toggle remote echo\r\n'
|
||||
db 'H - Toggle half duplex\t\t'
|
||||
db 'I - Print settings information\r\n'
|
||||
db 'J - Junk control characters\t\t'
|
||||
db 'K - Load a function key\r\n'
|
||||
db 'L - Toggle linefeed transmit for \'P\'\t'
|
||||
db 'M - Toggle bit 7 mask\r\n'
|
||||
db 'N - Select new default drive / user\t'
|
||||
db 'O - Toggle output to printer\r\n'
|
||||
db 'P - Print a file to remote\t\t'
|
||||
db 'Q - Quit\r\n'
|
||||
db 'R - Receive a file using protocol\t'
|
||||
db 'S - Send a file using protocol\r\n'
|
||||
db 'T - Type a local file\t\t\t'
|
||||
db 'U - Invoke user function\r\n'
|
||||
db 'V - Toggle VT100 Emulation\t\t'
|
||||
db 'W - Toggle split window mode\r\n'
|
||||
db 'X - Activate a chat script\t\t'
|
||||
db 'Y - Put catch file on hold\r\n'
|
||||
db 'Z - Close catch file\t\t\t'
|
||||
db '0-9 - Send function key string\r\n'
|
||||
db 0
|
||||
ret
|
||||
|
||||
.extern info ; print current settings
|
||||
info:
|
||||
call ilprt
|
||||
db '\r\nEscape character:\t\0'
|
||||
call dim
|
||||
call presc ; print the escape character
|
||||
call ilprt
|
||||
db '\r\nCurrent drive / user:\t\0'
|
||||
call dim
|
||||
ld hl,(curusr) ; get the current drive & user
|
||||
ld a,h
|
||||
add a,'A' ; convert drive to a letter
|
||||
ld c,a
|
||||
push hl
|
||||
call scrout ; print the drive
|
||||
pop hl
|
||||
call decob ; and print the user in l
|
||||
call ilprt
|
||||
db ':\r\n\0'
|
||||
ld a,(rate)
|
||||
cp ' '
|
||||
jr z,norate
|
||||
call ilprt
|
||||
db 'Baud rate:\t\t\0'
|
||||
call dim
|
||||
ld hl,rate
|
||||
call prtslp
|
||||
norate: ld a,(modsav)
|
||||
cp ' '
|
||||
jr z,nomode
|
||||
call ilprt
|
||||
db 'Communication Mode:\t\0'
|
||||
call dim
|
||||
ld hl,modsav
|
||||
call prtslp
|
||||
nomode: call ilprt
|
||||
db '^S delay:\t\t\0'
|
||||
call dim
|
||||
ld hl,(csdely) ; get the delay count
|
||||
call decob ; out it goes
|
||||
call ilprt
|
||||
db ' second(s)\r\nHalf duplex:\t\t\0'
|
||||
ld a,(hflg)
|
||||
call onoff ; say whether HDX is on or off
|
||||
call ilprt
|
||||
db 'Local echo:\t\t\0'
|
||||
ld a,(eflg)
|
||||
call onoff ; say what local echo is up to
|
||||
call ilprt
|
||||
db 'Control char. discard:\t\0'
|
||||
ld a,(jflg)
|
||||
call onoff ; say what local echo is up to
|
||||
call ilprt
|
||||
db 'Linefeed in \'P\':\t\0'
|
||||
ld a,(lflg)
|
||||
call onoff ; line feed in print
|
||||
call ilprt
|
||||
db 'Character delay:\t\0'
|
||||
call dim
|
||||
ld hl,(chd) ; get the character delay
|
||||
call decob ; out it goes
|
||||
call ilprt
|
||||
db ' msec. \0'
|
||||
ld a,(ecflg)
|
||||
or a
|
||||
jr z,noeci
|
||||
call ilprt
|
||||
db '\techo check\0'
|
||||
noeci: call ilprt
|
||||
db '\r\nNew line delay:\t\t\0'
|
||||
call dim
|
||||
ld hl,(nld) ; new line delay is a word
|
||||
call decout
|
||||
call ilprt
|
||||
db ' msec. \0'
|
||||
ld a,(lfecho)
|
||||
or a
|
||||
jr z,nolfe
|
||||
push af
|
||||
call ilprt
|
||||
db '\tnewline echo: \'\0'
|
||||
call dim
|
||||
pop af
|
||||
ld c,a
|
||||
call scrout
|
||||
ld c,'\''
|
||||
call scrout
|
||||
nolfe: call ilprt
|
||||
db '\r\nBit 7 masking:\t\t\0'
|
||||
ld a,(bmask)
|
||||
inc a
|
||||
call onoff ; say what bit 7 masking is up to
|
||||
call ilprt
|
||||
db 'VT100 emulation:\t\0'
|
||||
ld a,(vflg)
|
||||
call onoff ; and vt100 emulation
|
||||
call ilprt
|
||||
db 'Printer output:\t\t\0'
|
||||
ld a,(oflg)
|
||||
call onoff ; and printer output
|
||||
ld a,(cflg)
|
||||
or a
|
||||
jr nz,isctch ; catch file active?
|
||||
call ilprt ; if not then say so
|
||||
db 'Not catching\r\n\0'
|
||||
ret
|
||||
isctch: call ilprt
|
||||
db 'Current catch file:\t\0'
|
||||
call dim
|
||||
ld hl,cfcb
|
||||
call prtfl ; otherwise print the filename
|
||||
ld a,(cflg)
|
||||
dec a
|
||||
jp z,crlf ; if active we're done
|
||||
call ilprt ; else say it's on hold
|
||||
db ' (on hold)\r\n\0'
|
||||
ret
|
||||
|
||||
onoff: or a ; is the flag active
|
||||
jr z,proff ; jump if not
|
||||
call ilprt
|
||||
db 'on\r\n\0' ; say it's on
|
||||
ret
|
||||
proff: call ilprt
|
||||
db 'off\r\n\0' ; or say it's off
|
||||
ret
|
||||
|
||||
.extern presc
|
||||
presc:
|
||||
ld b,0
|
||||
ld a,(escval) ; get the escape character
|
||||
cp ' '
|
||||
jr c,prthat ; it's a control char - print the ^
|
||||
cp 0x7f
|
||||
jr nz,nohat ; also do that for deletes
|
||||
prthat: ld c,'^'
|
||||
push af ; save the escape val
|
||||
call scrout ; print the ^
|
||||
pop af
|
||||
ld b,64 ; flag we printed the ^
|
||||
xor b ; and "uncontrollify" the char
|
||||
nohat: ld c,a
|
||||
push bc ; save flag
|
||||
call scrout ; print the char
|
||||
pop af ; flag back to a
|
||||
ret
|
||||
|
||||
.extern quit
|
||||
quit:
|
||||
call cclose ; close catch file if open
|
||||
ld hl,23 * 256 ; blh corner of screen
|
||||
call moveto ; go there
|
||||
call exit ; call custom unwind code
|
||||
rst 0 ; exit to cp/m
|
||||
|
||||
.extern conin ; get char from function key or keyboard
|
||||
conin:
|
||||
ld a,(fkdely) ; check if we need to delay
|
||||
or a
|
||||
call nz,tnthip ; idle a while if we do
|
||||
ld hl,(fkptr)
|
||||
ld a,(hl) ; get the next char
|
||||
inc hl
|
||||
ld (fkptr),hl ; save revised pointer
|
||||
ret ; char is in a
|
||||
|
||||
.extern ctls
|
||||
ctls:
|
||||
ld a,(lxoff) ; get local xon / xoff status
|
||||
or a
|
||||
ld a,(cschr)
|
||||
call nz,modopc ; send the xoff if needed
|
||||
ld a,(csdely)
|
||||
or a
|
||||
ret z ; if it's zero, return right now
|
||||
ld b,a ; get the delay value
|
||||
add a,a
|
||||
add a,a
|
||||
add a,b
|
||||
add a,a ; * 10
|
||||
ld b,a ; to b
|
||||
waitlp: push bc
|
||||
call tenth ; wait a while
|
||||
pop bc
|
||||
djnz waitlp
|
||||
ret
|
||||
|
||||
.extern gotxon ; flag that an xon was sent from the kbd,
|
||||
gotxon: ; so we don't re-send
|
||||
ld (lxoff),a ; set the local xoff flag
|
||||
ret
|
||||
|
||||
.extern gotxof ; flag that an xof was sent: this just clears
|
||||
gotxof: ; the flag set in gotxon
|
||||
ld hl,lxoff
|
||||
ld (hl),0
|
||||
ret
|
||||
|
||||
.extern areabp ; areabp used in chat scripts: point at first
|
||||
areabp: ; non-white in text of a '!' command
|
||||
ld hl,area - 1 ; point at chat parse area and fall into byp
|
||||
|
||||
.extern incbyp
|
||||
incbyp: ; inc hl, and then byp
|
||||
inc hl
|
||||
|
||||
.extern byp ; step over spaces in string pointed to by hl
|
||||
byp:
|
||||
ld a,(hl)
|
||||
cp ' '
|
||||
ret nz ; return on the first char that is NOT a space
|
||||
inc hl
|
||||
jr byp
|
||||
|
||||
.extern ldfnk ; this will prompt and then use the string
|
||||
ldfnk: ; to program one of the 10 function keys
|
||||
ld hl,zero ; point the readback pointer at a zero
|
||||
ld (fkptr),hl ; in case we change the string under it
|
||||
call prompt
|
||||
db 'Key value: \0' ; get the string
|
||||
ld hl,ipbuf
|
||||
call byp ; strip spaces
|
||||
or a
|
||||
ret z ; skip if nothing to do
|
||||
cp '\e'
|
||||
ret z ; or if an escape typed
|
||||
ld c,0 ; clear c (will become slow/fast flag)
|
||||
sub '0'
|
||||
cp 10
|
||||
jr c,fast ; 0-9: is a fast, key index in a
|
||||
ld c,a ; non-digit: save a non-zero in c
|
||||
inc hl
|
||||
ld a,(hl) ; get the next character
|
||||
sub '0' ; and turn it into an index
|
||||
fast: cp 10
|
||||
jr c,fnkok ; check it's ok
|
||||
call ilprt ; complain and return if not
|
||||
db 'Invalid function key number\r\n\0'
|
||||
ret
|
||||
fnkok: inc hl ; point at string to be parsed
|
||||
push hl ; save input string address
|
||||
add a,a
|
||||
add a,a
|
||||
add a,a
|
||||
add a,a ; turn index into table offset
|
||||
ld e,a
|
||||
ld d,0 ; goes in de
|
||||
ld hl,fktbl
|
||||
add hl,de ; get table entry address
|
||||
ld (hl),c ; save speed flag
|
||||
inc hl
|
||||
ex de,hl ; string target address to de
|
||||
pop hl ; text back to hl
|
||||
ld bc,14 << 8 ; 14 chars, zero byte delimits
|
||||
jp parst ; go parse the string, and we're done
|
||||
|
||||
.extern cbios ; call the entry point in the bios witn number
|
||||
cbios: ; in a, saving ix and iy as we go
|
||||
push ix
|
||||
push iy
|
||||
call #bios
|
||||
pop iy
|
||||
pop iy
|
||||
ret
|
||||
|
||||
#bios: ; offset is in a
|
||||
ld hl,(1) ; get the warm boot value to hl
|
||||
ld l,a ; modify with function number
|
||||
jp (hl) ; go do the code
|
||||
|
||||
.dseg
|
||||
optype: db 0
|
||||
bflag: db 0
|
||||
.extern lxoff
|
||||
lxoff: db 1
|
||||
.extern prmpfl
|
||||
prmpfl: db 0
|
||||
.extern fkptr
|
||||
fkptr: dw zero
|
||||
|
||||
.useg
|
||||
pos: ds 1
|
||||
linec: ds 1
|
||||
pagerf: ds 1
|
||||
.extern fkdely
|
||||
fkdely: ds 1
|
||||
.extern fktbl
|
||||
fktbl: ds 16 * 10
|
||||
|
BIN
source/QT43SRC.LBR
Normal file
BIN
source/QT43SRC.LBR
Normal file
Binary file not shown.
903
source/QTERM.Z
Normal file
903
source/QTERM.Z
Normal file
@ -0,0 +1,903 @@
|
||||
; qterm.z - patch area and main control loop for qterm
|
||||
|
||||
.incl "c:vars"
|
||||
.incl "c:version"
|
||||
|
||||
.var escchr '\\' & 0x1f
|
||||
.var biosjp 1
|
||||
.var memtop 6
|
||||
|
||||
.macro table byte,addr
|
||||
dw addr
|
||||
db byte
|
||||
.endm
|
||||
|
||||
jp start ; skip over the patch area
|
||||
|
||||
; now for the screen access routines - these are put here because moveto
|
||||
; will have to access scrout, and this provides a ready access point
|
||||
|
||||
#kbdsts:
|
||||
jp 6 ; keyboard status routine
|
||||
#kbdin:
|
||||
jp 9 ; keyboard input routine
|
||||
#scrout:
|
||||
jp 12 ; screen output
|
||||
jp decoj ; access to decimal output routine
|
||||
|
||||
; These bits are system dependant, and are put at the beginning of the
|
||||
; program so that them as what needs to change them, can.
|
||||
|
||||
; modist - return with z flag clear iff there is a char waiting at modem port
|
||||
|
||||
.org 0x0010
|
||||
#modist:
|
||||
ld hl,(_base_)
|
||||
ld a,(hl)
|
||||
inc hl
|
||||
xor (hl)
|
||||
ret
|
||||
|
||||
; modin - read char from modem port: modist has been used to check it's there
|
||||
|
||||
.org 0x0020
|
||||
#modin:
|
||||
ld hl,(_base_)
|
||||
inc (hl)
|
||||
res 5,(hl)
|
||||
ld e,(hl)
|
||||
inc hl
|
||||
inc hl
|
||||
ld d,0
|
||||
add hl,de
|
||||
ld a,(hl)
|
||||
ret
|
||||
|
||||
; modost - return with z flag clear iff the modem can accept another char
|
||||
|
||||
.org 0x0030
|
||||
#modost:
|
||||
in a,(0x2e)
|
||||
and 0x80
|
||||
ret
|
||||
|
||||
; modout - send char to modem port
|
||||
|
||||
.org 0x0040
|
||||
#modout:
|
||||
out (0x2f),a
|
||||
ret
|
||||
|
||||
; sbreak - start a break condition on line
|
||||
|
||||
.org 0x0050
|
||||
#sbreak:
|
||||
ld a,0x0d
|
||||
out (0x2e),a
|
||||
ret
|
||||
|
||||
; ebreak - terminate break condition
|
||||
|
||||
.org 0x0060
|
||||
#ebreak:
|
||||
ld a,0x05
|
||||
out (0x2e),a
|
||||
ret
|
||||
|
||||
; dtroff - disable dtr to cause modem to hang up
|
||||
|
||||
.org 0x0070
|
||||
.extern #dtroff ; external so hangup can work
|
||||
#dtroff:
|
||||
ld a,0x24
|
||||
out (0x21),a
|
||||
ret
|
||||
|
||||
; dtron - re-enable dtr
|
||||
|
||||
.org 0x0080
|
||||
#dtron:
|
||||
xor a
|
||||
out (0x21),a
|
||||
ret
|
||||
|
||||
; setbd - take byte in a from baud table, use it to set baud rate
|
||||
|
||||
.org 0x0090
|
||||
#setbd:
|
||||
out (0x2b),a
|
||||
ret
|
||||
|
||||
; these next eight are byte pairs - the first byte is used by setbd above.
|
||||
; the second is a -1 for an active baud rate entry, and a 0 for inactive
|
||||
|
||||
.org 0x00a0
|
||||
.extern b38400
|
||||
b38400: db 0,no
|
||||
.extern b19200
|
||||
b19200: db 0,no
|
||||
.extern b9600
|
||||
b9600: db 1,yes
|
||||
.extern b4800
|
||||
b4800: db 2,yes
|
||||
.extern b2400
|
||||
b2400: db 4,yes
|
||||
.extern b1200
|
||||
b1200: db 8,yes
|
||||
.extern b600
|
||||
b600: db 16,yes
|
||||
.extern b300
|
||||
b300: db 32,yes
|
||||
|
||||
; setmod - take a byte from the mode table, use it to set the uart mode
|
||||
|
||||
.org 0x00b0
|
||||
#setmod:
|
||||
out (0x2c),a
|
||||
ret
|
||||
|
||||
; now the twelve mode bytes for setting comm format
|
||||
|
||||
.org 0x00c0
|
||||
.extern modtab
|
||||
modtab:
|
||||
n17: db 0b10101010
|
||||
n18: db 0b10001010
|
||||
n27: db 0b10111010
|
||||
n28: db 0b10011010
|
||||
e17: db 0b10101110
|
||||
e18: db 0b10001110
|
||||
e27: db 0b10111110
|
||||
e28: db 0b10011110
|
||||
o17: db 0b10101100
|
||||
o18: db 0b10001100
|
||||
o27: db 0b10111100
|
||||
o28: db 0b10011100
|
||||
|
||||
.org 0x00cc
|
||||
.extern resrvd
|
||||
resrvd:
|
||||
db 0
|
||||
|
||||
; xfersz - number of K to read / write to disk during protocol transfers:
|
||||
; must be 1 / 2 / 4 / 8. Generally this is best left at 8 unless you have
|
||||
; a REALLY slow disk (C128 maybe) when writing / reading 8K at a time
|
||||
; causes timeouts. Drop this to 4 or 2 to do disk access in smaller chunks
|
||||
; to help avoid the timeout problem
|
||||
|
||||
.extern xfersz
|
||||
xfersz: db 8
|
||||
|
||||
; speed - simply the cpu speed for a z80 in mhz.
|
||||
|
||||
.extern speed
|
||||
speed: db 4
|
||||
|
||||
; escape - this is the character used as the escape char: since the addresses
|
||||
; in the table tend to move, we just put the byte here, and then transfer
|
||||
; to the table later
|
||||
|
||||
escape: db escchr
|
||||
|
||||
; the signon message - change this to be appropriate for your system
|
||||
|
||||
.org 0x00d0
|
||||
signon: db 'Televideo TS803\0'
|
||||
|
||||
; now the string for clear screen
|
||||
|
||||
.org 0x00f0
|
||||
.extern clrs
|
||||
clrs: db 'z' & 0x1f, 0
|
||||
|
||||
; moveto - this routine is called with a word in hl - h = row &
|
||||
; l = column to move to, at 109 is a routine to print a char in c,
|
||||
; at 10c is a routine to print a decimal number in hl (for ansi tubes)
|
||||
|
||||
.org 0x0100
|
||||
#moveto:
|
||||
push hl ; save coords
|
||||
ld c,'\e'
|
||||
call #scrout ; lead in escape
|
||||
ld c,'='
|
||||
call #scrout ; leadin '='
|
||||
pop hl
|
||||
push hl
|
||||
ld a,h ; row to a
|
||||
call poff ; out it goes w/ offset
|
||||
pop hl
|
||||
ld a,l ; col to a
|
||||
poff: add a,' ' ; add offset
|
||||
ld c,a
|
||||
jp #scrout ; & print it
|
||||
|
||||
; these next strings are used to do various screen functions. There are
|
||||
; eight of them, and immediately preceding them is a flag byte. Each string
|
||||
; has a bit in the byte, and if a capability is present, its bit should
|
||||
; be set. This byte is an absolute necessity, as various programs use it
|
||||
; to tell if various things are present.
|
||||
|
||||
.org 0x012f
|
||||
.extern tcbits
|
||||
tcbits:
|
||||
db 0b11111111
|
||||
; ||||||||
|
||||
; |||||||+------ 0: bright (end highlight)
|
||||
; ||||||+------- 1: dim (start highlight)
|
||||
; |||||+-------- 2: delete line
|
||||
; ||||+--------- 3: insert line
|
||||
; |||+---------- 4: delete character
|
||||
; ||+----------- 5: insert character
|
||||
; |+------------ 6: clear to end of line
|
||||
; +------------- 7: clear to end of screen
|
||||
|
||||
.org 0x0130
|
||||
.extern brites
|
||||
brites: db '\e(\0'
|
||||
|
||||
.org 0x0138
|
||||
.extern dims
|
||||
dims: db '\e)\0'
|
||||
|
||||
.org 0x0140
|
||||
.extern dlstr
|
||||
dlstr: db '\eR\0'
|
||||
|
||||
.org 0x0148
|
||||
.extern ilstr
|
||||
ilstr: db '\eE\0'
|
||||
|
||||
.org 0x0150
|
||||
.extern dcstr
|
||||
dcstr: db '\eW\0'
|
||||
|
||||
.org 0x0158
|
||||
.extern icstr
|
||||
icstr: db '\eQ\0'
|
||||
|
||||
.org 0x0160
|
||||
.extern ceol
|
||||
ceol: db '\eT\0'
|
||||
|
||||
.org 0x0168
|
||||
.extern ceos
|
||||
ceos: db '\eY\0'
|
||||
|
||||
; Entry and exit hooks. These are provided to perform custom initialisation
|
||||
; on startup, and also to perform custom code on exit.
|
||||
|
||||
.org 0x0170
|
||||
.extern entry
|
||||
entry: jp do_ent
|
||||
|
||||
.org 0x0173
|
||||
.extern exit
|
||||
exit: jp do_ext
|
||||
|
||||
.org 0x0176
|
||||
.extern #user
|
||||
#user:
|
||||
.if dg
|
||||
jp _user_ ; go do ours
|
||||
.else
|
||||
ret
|
||||
.endif
|
||||
|
||||
.org 0x0179
|
||||
.extern #kbmap
|
||||
#kbmap:
|
||||
.if dg
|
||||
jp _kbmp_ ; hook into keyboard map routine
|
||||
.else
|
||||
ret
|
||||
.endif
|
||||
|
||||
.org 0x017c
|
||||
_ilpr_: jp prmpjp
|
||||
|
||||
; finally a patch area that is provided for patching odd systems that need
|
||||
; a lot of space.
|
||||
|
||||
.org 0x0180
|
||||
|
||||
do_ent:
|
||||
|
||||
.if dg
|
||||
|
||||
ld c,14
|
||||
ld e,3
|
||||
call 5
|
||||
ld c,32
|
||||
ld e,30
|
||||
call 5
|
||||
ld a,0b10001010 ; 8n1
|
||||
out (0x2c),a
|
||||
ld a,4 ; 2400
|
||||
out (0x2b),a
|
||||
|
||||
.endif
|
||||
|
||||
di
|
||||
ld hl,(0xff00)
|
||||
xor a
|
||||
ld (hl),a
|
||||
ld (_base_),hl ; OK, use GSX interface area for interrupts
|
||||
inc hl
|
||||
ld (hl),a
|
||||
ld (_here_ + 1),hl
|
||||
ld de,33
|
||||
add hl,de
|
||||
ex de,hl
|
||||
push de
|
||||
ld hl,icode
|
||||
ld bc,{endi - icode}
|
||||
ldir
|
||||
ld c,0x10
|
||||
pop de
|
||||
jr endit
|
||||
|
||||
do_ext: di
|
||||
ld de,(ivec)
|
||||
ld c,0
|
||||
|
||||
endit: ld a,i
|
||||
ld h,a
|
||||
ld l,0x78
|
||||
ld a,(hl)
|
||||
ld (hl),e
|
||||
ld e,a
|
||||
inc hl
|
||||
ld a,(hl)
|
||||
ld (hl),d
|
||||
ld d,a
|
||||
ld (ivec),de
|
||||
ld a,0x65
|
||||
out (0x28),a
|
||||
ld a,c
|
||||
out (0x20),a
|
||||
out (0x27),a
|
||||
ld a,0x64
|
||||
out (0x28),a
|
||||
ei
|
||||
clrlp: in a,(0x2f)
|
||||
in a,(0x2d)
|
||||
add a,a
|
||||
jr c,clrlp
|
||||
ret
|
||||
|
||||
icode: di
|
||||
push hl
|
||||
push af
|
||||
iclp: in a,(0x2d)
|
||||
add a,a
|
||||
jr nc,icdone
|
||||
_here_: ld hl,0 ; filled in later
|
||||
inc (hl)
|
||||
res 5,(hl)
|
||||
ld a,(hl)
|
||||
inc hl
|
||||
add a,l
|
||||
ld l,a
|
||||
jr nc,hok
|
||||
inc h
|
||||
hok: in a,(0x2f)
|
||||
ld (hl),a
|
||||
jr iclp
|
||||
icdone: pop af
|
||||
pop hl
|
||||
ei
|
||||
reti
|
||||
endi:
|
||||
|
||||
ivec: dw 0
|
||||
_base_: dw 0
|
||||
|
||||
.if dg
|
||||
|
||||
.var linesz 40 ; default number of chars before we start
|
||||
|
||||
_user_:
|
||||
call _ilpr_ ; prompt for and get an answer
|
||||
db 'Split? \0'
|
||||
ld hl,0x7f ; point just before it
|
||||
_byp: inc hl
|
||||
ld a,(hl) ; get the next character
|
||||
cp ' ' ; space?
|
||||
jr z,_byp ; yes, skip over it
|
||||
sub '0'
|
||||
cp 10
|
||||
jr c,_numbr ; numeric input - go handle it
|
||||
add a,'0' ; convert back
|
||||
or 0x20 ; force lower case
|
||||
xor 0x20 ; this really tests for a null .....
|
||||
jr z,_gtans ; yes, save zero byte
|
||||
xor 0x20 ^ 'y' ; and check for a 'y' (including 'Y')
|
||||
_gtans: ld (split),a ; save the flag - zero enables, non-zero
|
||||
; disables
|
||||
ld a,linesz ; set line length to default of 40
|
||||
_setll: ld (linlen),a ; set the line length from a
|
||||
xor a
|
||||
ld (count),a ; and set the count to zero
|
||||
ret
|
||||
|
||||
_numbr: ld e,a ; save current value in e
|
||||
inc hl ; point to next character
|
||||
ld a,(hl)
|
||||
sub '0' ; convert .....
|
||||
cp 10 ; and test if it's a digit
|
||||
jr nc,_gtnum ; nope - we're all done
|
||||
ld d,a
|
||||
ld a,e
|
||||
add a,a ; a = e * 2
|
||||
add a,a ; * 4
|
||||
add a,e ; * 5
|
||||
add a,a ; * 10
|
||||
add a,d ; + d
|
||||
jr _numbr
|
||||
_gtnum: xor a
|
||||
ld (split),a ; else set split flag to enable
|
||||
ld a,e ; and get the line length back from e
|
||||
jr _setll ; go do the set with whatever we have
|
||||
|
||||
_kbmp_: and 0x7f ; ditch bit 7, just because I'm paranoid
|
||||
_nodel: ld hl,split ; point at the flag
|
||||
inc (hl)
|
||||
dec (hl)
|
||||
ld c,a ; save char in c
|
||||
jp nz,_jstcn ; not splitting - get outa here
|
||||
ld hl,(state)
|
||||
ld a,h
|
||||
or l ; are we in the middle of a line break?
|
||||
jr nz,_linbr ; yes, so handle it elsewhere
|
||||
ld a,c ; get the character back from c
|
||||
ld hl,0x01cf ; point at the escape character
|
||||
cp (hl)
|
||||
ret z ; we have to let these through!
|
||||
ld hl,count ; point hl at the count for everyone
|
||||
cp '\b'
|
||||
jr z,_bcksp ; handle backspaces
|
||||
cp 'y' & 0x1f
|
||||
jr z,_ctly ; and ^Y's
|
||||
cp '\r'
|
||||
jr z,_retrn ; and returns
|
||||
cp '\n'
|
||||
jr z,_newln ; and linefeeds
|
||||
inc b ; set b to 1 for a potential swallow
|
||||
cp 0x7f ; throw away deletes
|
||||
ret z
|
||||
cp ' ' ; is it a space?
|
||||
jr z,_space ; handle specially if so
|
||||
ret c ; and throw away other control characters
|
||||
dec b ; reset b to pass the single character
|
||||
inc (hl) ; bump count
|
||||
ret ; and return - char is still in a
|
||||
|
||||
_bcksp: dec (hl) ; anything in the current count
|
||||
inc b ; set b to 1 for a swallow
|
||||
inc (hl) ; restore count
|
||||
ret z ; and return if nothing there
|
||||
dec (hl) ; decrement count since we're allowing it
|
||||
dec b ; reset b
|
||||
ret
|
||||
|
||||
_retrn: ld hl,retstr ; point at the return string
|
||||
jr _linbr
|
||||
|
||||
_newln: ld hl,nlstr ; point at the new line string
|
||||
jr _linbr
|
||||
|
||||
_ctly: ld hl,(count)
|
||||
ld h,0 ; set state from count
|
||||
or a
|
||||
jr _setbs
|
||||
|
||||
_space: inc (hl) ; we passed another character, count it
|
||||
ld a,(linlen) ; get the line length
|
||||
cp (hl) ; too long yet?
|
||||
ld a,c
|
||||
dec b
|
||||
ret nc ; no, return character in a
|
||||
ld hl,string ; else point at the string to send
|
||||
|
||||
_linbr: ld a,h
|
||||
or a
|
||||
jr z,_sndbs ; if h is zero, send l backspaces
|
||||
ld a,(hl) ; get the next character from the string
|
||||
inc hl ; move the pointer
|
||||
inc (hl)
|
||||
dec (hl) ; end of string?
|
||||
ld b,2 ; set b to 2 to say there's more coming
|
||||
jr nz,_savhl ; not end of string, save hl and return
|
||||
ld b,(hl) ; set b to zero again
|
||||
ld hl,count
|
||||
ld (hl),b ; zero out the count from b
|
||||
ld h,b
|
||||
ld l,b ; set hl to zero to reset the state machine
|
||||
_savhl: ld (state),hl ; save the pointer / NULL
|
||||
ret
|
||||
|
||||
_sndbs: dec l ; one less to go
|
||||
_setbs: ld (state),hl ; save the state back
|
||||
ld b,2 ; flag more to come
|
||||
jr nz,_bok ; unless this is the last
|
||||
ld b,h ; in which case b gets zero
|
||||
ld (count),a ; set count to zero (a is zero from jp above)
|
||||
_bok: ld a,'\b' ; stuff a backspace in a, and we're done
|
||||
ret
|
||||
|
||||
_jstcn: ld hl,(state)
|
||||
ld a,h
|
||||
or l ; are we in the middle of a line break?
|
||||
jr nz,_linbr ; yes, so handle it elsewhere
|
||||
ld a,c
|
||||
ld b,0
|
||||
ld hl,count ; point hl at the count for everyone
|
||||
cp '\b'
|
||||
jr z,_cbksp ; count backwards
|
||||
cp '\n'
|
||||
jr z,_cntrt ; count return's - set to zero
|
||||
cp '\r'
|
||||
jr z,_cntrt
|
||||
cp 'y' & 0x1f
|
||||
jr z,_ctly ; handle ^Y's
|
||||
cp ' '
|
||||
ret c ; let control chars pass, but don't count them
|
||||
inc (hl)
|
||||
ret
|
||||
_cntrt: ld (hl),b ; set count to zero
|
||||
ret
|
||||
|
||||
_cbksp: dec (hl) ; anything in the current count
|
||||
inc (hl)
|
||||
ret z ; no, leave count alone
|
||||
dec (hl) ; drop it back by one
|
||||
ret ; all done
|
||||
|
||||
count: db 0 ; count of chars since the last new line
|
||||
linlen: db linesz ; line size we're currently using
|
||||
split: db 1 ; flag if we're splitting: zero => we are
|
||||
state: dw 0 ; what state are we in?
|
||||
|
||||
string: db ' .....\r\0' ; space string to break lines
|
||||
retstr: db ' [end]' ; return string to end a paragraph
|
||||
nlstr: db '\r\0' ; newline to end
|
||||
|
||||
.endif
|
||||
|
||||
.org 0x0400
|
||||
|
||||
; put this jump here, because decout may move, so we can't have it's address
|
||||
; in the patch area
|
||||
|
||||
decoj: jp decout
|
||||
|
||||
; same again: prompt may move
|
||||
|
||||
prmpjp: jp prompt
|
||||
|
||||
; now the start of the main code
|
||||
|
||||
start: ld sp,(memtop) ; set the stack
|
||||
ld a,(biosjp + 1) ; get the bios base address
|
||||
ld (#kbdsts + 2),a
|
||||
ld (#kbdin + 2),a
|
||||
ld (#scrout + 2),a ; fix the three jumps
|
||||
call #subchk ; but now check for XSUB installed
|
||||
ld a,(escape)
|
||||
ld (escval),a ; set the escape character in the jump table
|
||||
call setshr ; do shrink adjustment
|
||||
ld a,(xfersz)
|
||||
ld hl,512
|
||||
sizlp: add hl,hl ; set size in K in hl
|
||||
rra
|
||||
jr nc,sizlp ; loop till size is set in hl
|
||||
ld de,work2
|
||||
add hl,de
|
||||
ld (ew2p),hl ; and set pointer for transfers
|
||||
ld hl,fktbl
|
||||
ld de,fktbl + 1
|
||||
ld bc,16 * 10 - 1
|
||||
ld (hl),b
|
||||
ldir ; clear fk table initially
|
||||
call entry ; do the users custom code
|
||||
ld sp,(memtop) ; reload the stack pointer in case things got
|
||||
; bashed in the entry hook
|
||||
call ilprt ; print fixed part of signon
|
||||
db 'QTERM V'
|
||||
version
|
||||
db '\r\n'
|
||||
db '(C) Copyright DPG '
|
||||
year
|
||||
db ' - All rights reserved\r\n'
|
||||
db 'Version for \0'
|
||||
call dim
|
||||
ld hl,signon
|
||||
call prtslp ; print the system signon message
|
||||
call ilprt
|
||||
db '\r\nEscape character is \0'
|
||||
call dim
|
||||
call presc ; remind what the escape character is
|
||||
call crlf
|
||||
call crlf ; throw a newline or two
|
||||
ld a,(#dtroff)
|
||||
cp 0xc9
|
||||
call nz,dtron ; enable dtr
|
||||
ld c,getdrv ; now, in case we changed drive / user in the
|
||||
call bdos ; entry hook, we get the current drive / user
|
||||
ld (curdrv),a
|
||||
ld (chtdrv),a ; chat drive
|
||||
ld c,gsuser
|
||||
ld e,0xff
|
||||
call bdos ; find out which user
|
||||
ld (curusr),a ; save it away as well
|
||||
ld (chtusr),a ; chat user
|
||||
ld hl,0x80 ; get command tail
|
||||
ld e,(hl) ; get it's length
|
||||
ld (hl),' ' ; add a space so that byp will grok it
|
||||
inc hl
|
||||
ld d,h ; extend length to de
|
||||
ex de,hl
|
||||
add hl,de
|
||||
ld (hl),d ; stick a zero byte on the end of it
|
||||
ex de,hl ; base address back to hl
|
||||
call byp ; was there anything there?
|
||||
or a
|
||||
call nz,ichat ; yes - go process it
|
||||
|
||||
; this loop provides terminal mode: it simply loops round polling the kdb &
|
||||
; modem port - when it finds something, then it starts to get clever
|
||||
|
||||
.extern main
|
||||
main: ld sp,(memtop) ; since we long jump here occasionally
|
||||
ld hl,main
|
||||
push hl ; push "here" so a return gets us back
|
||||
ld a,lf_bit
|
||||
ld (mode),a ; reset mode
|
||||
call lstmod ; keep the printer going and check modem port
|
||||
ld hl,(fkptr)
|
||||
ld a,(hl)
|
||||
or a ; sending a function key?
|
||||
jr z,nofkey ; nope, go try the keyboard
|
||||
call conin ; get the key
|
||||
jr gotcon
|
||||
nofkey: ld (prmpfl),a
|
||||
ld a,(more)
|
||||
rra ; should we get a keyboard character
|
||||
jr c,skipin ; skip if not
|
||||
call kbdsts ; keyboard ready?
|
||||
or a
|
||||
ret z ; no, loop back
|
||||
call kbdin ; get the char
|
||||
skipin: ld b,0 ; set b so a return is a no-op
|
||||
call #kbmap ; run through the keyboard window
|
||||
srl b
|
||||
ret c ; swallowed, start again
|
||||
gotcon: ld c,a ; save in c
|
||||
ld a,b ; copy more bit to a
|
||||
ld (more),a ; and save it
|
||||
ld de,escstt
|
||||
ld a,(de) ; what state are we in?
|
||||
dec a
|
||||
ld a,c ; get char back
|
||||
jr z,hadesc ; we've had an esc char, handle next
|
||||
ld hl,cschr
|
||||
cp (hl)
|
||||
call z,gotxof ; note passing xoff's
|
||||
jr z,noxon
|
||||
ld hl,lxoff
|
||||
inc (hl)
|
||||
dec (hl)
|
||||
ld hl,escval
|
||||
jr nz,noxon
|
||||
cp (hl)
|
||||
call nz,gotxon ; and xon's
|
||||
noxon: cp (hl) ; test the char for an escape
|
||||
jr nz,modopj ; no it's not, send it to the modem
|
||||
ld hl,(fkptr)
|
||||
ld a,(hl) ; in the midst of a pfk send?
|
||||
or a
|
||||
ld a,(escval) ; get an escape char back into a
|
||||
modopj: jr z,gotesc ; yes - skip the usual escape
|
||||
ld a,(wflg)
|
||||
or a
|
||||
ld a,c
|
||||
call nz,limitb ; legal character?
|
||||
ret c ; nope - exit now
|
||||
modjp: jp modop
|
||||
|
||||
; gotesc - we just got the escape char in state 0: set state to 1
|
||||
|
||||
gotesc: ex de,hl
|
||||
inc (hl) ; set state to 1
|
||||
ret
|
||||
|
||||
; esctbl - table of special values for the escape handler
|
||||
|
||||
.dseg
|
||||
esctbl: dw modop
|
||||
.extern escval
|
||||
escval: db escchr
|
||||
table '?',help
|
||||
table '.',break
|
||||
table 0x2c,hangup
|
||||
table 'B',baud
|
||||
table 'C',catch
|
||||
table 'D',dir
|
||||
table 'E',echo
|
||||
table 'H',hdxtog
|
||||
table 'I',info
|
||||
table 'J',jctog
|
||||
table 'K',ldfnk
|
||||
table 'L',lftog
|
||||
table 'M',msbtog
|
||||
table 'N',newdsk
|
||||
table 'O',optog
|
||||
table 'P',print
|
||||
table 'Q',quit
|
||||
table 'R',recv
|
||||
table 'S',send
|
||||
table 'T',type
|
||||
table 'U',#user
|
||||
table 'V',vttog
|
||||
table 'W',witog
|
||||
table 'X',chat
|
||||
table 'Y',hold
|
||||
table 'Z',cclose
|
||||
tblend:
|
||||
.cseg
|
||||
|
||||
; hadesc - we are in state 1 and a char arrived: process it as appropriate
|
||||
|
||||
hadesc: ex de,hl
|
||||
dec (hl) ; reset state
|
||||
nowjp: ld a,c
|
||||
ld hl,esctbl ; get address of table
|
||||
ld b,{tblend - esctbl} / 3
|
||||
call ucsa ; force it upper case
|
||||
escscn: ld e,(hl)
|
||||
inc hl
|
||||
ld d,(hl) ; get jump address to de
|
||||
inc hl
|
||||
cp (hl) ; test for a match
|
||||
inc hl
|
||||
push de
|
||||
ret z ; got it: go and process
|
||||
pop de
|
||||
djnz escscn ; loop back & try again
|
||||
nowpop: ld a,c ; get char from c (again)
|
||||
sub '0'
|
||||
cp 10 ; check for '0' thru '9'
|
||||
ret nc ; didn't find it - give up
|
||||
add a,a
|
||||
add a,a
|
||||
add a,a
|
||||
add a,a ; * 16 gives table offset
|
||||
ld l,a
|
||||
ld h,0
|
||||
ld de,fktbl
|
||||
add hl,de ; index into table
|
||||
ld a,(hl) ; pick up
|
||||
ld (fkdely),a ; and save delay flag
|
||||
inc hl ; point at main string
|
||||
ld (fkptr),hl ; save string address
|
||||
ret
|
||||
|
||||
.dseg
|
||||
escstt: db 0 ; state of escape detection
|
||||
more: db 0 ; keyboard window code
|
||||
|
||||
; V4.1e rev
|
||||
;
|
||||
; we now save ix and iy through all patch and bios calls: these entries
|
||||
; are used, and do all the work needed
|
||||
|
||||
.cseg
|
||||
|
||||
.macro access entry
|
||||
.extern entry
|
||||
entry:
|
||||
push ix
|
||||
push iy
|
||||
call #`entry
|
||||
pop iy
|
||||
pop ix
|
||||
ret
|
||||
.endm
|
||||
|
||||
access kbdsts
|
||||
access scrout
|
||||
access modist
|
||||
access modin
|
||||
access modost
|
||||
access modout
|
||||
access sbreak
|
||||
access ebreak
|
||||
access dtroff
|
||||
access dtron
|
||||
access setbd
|
||||
access setmod
|
||||
access moveto
|
||||
|
||||
.extern kbdcc ; get a keyboard character if it's waiting
|
||||
kbdcc:
|
||||
call kbdsts
|
||||
or a
|
||||
ret z ; return 0 if nothing
|
||||
|
||||
access kbdin
|
||||
|
||||
.var #bdos 5
|
||||
|
||||
|
||||
.extern usrbds ; call bdos, but with a user switch
|
||||
usrbds:
|
||||
push bc ; save the function code
|
||||
ld a,(de) ; get the user number to switch to
|
||||
inc de ; point de at bdos's idea of the fcb
|
||||
push de ; save the address
|
||||
ld e,a
|
||||
ld c,gsuser
|
||||
call bdos ; set the user number
|
||||
pop de ; restore the fcb address
|
||||
pop bc ; and function number
|
||||
|
||||
.extern bdos
|
||||
bdos:
|
||||
push ix
|
||||
push iy
|
||||
call #bdos
|
||||
pop iy
|
||||
pop ix
|
||||
ret
|
||||
|
||||
.extern #subchk
|
||||
#subchk:
|
||||
ld hl,(1)
|
||||
ld a,l
|
||||
ld de,3
|
||||
xor e
|
||||
jr nz,chngit
|
||||
ld l,a
|
||||
ld b,6
|
||||
jplp: ld a,(hl)
|
||||
cp 0xc3
|
||||
jr nz,chngit
|
||||
add hl,de
|
||||
djnz jplp
|
||||
ret
|
||||
chngit: ld hl,jptab
|
||||
ld de,0x0103
|
||||
ld bc,9
|
||||
ldir
|
||||
ret
|
||||
|
||||
jptab: jp locst
|
||||
jp locin
|
||||
jp locout
|
||||
|
||||
locst: ld hl,peekc
|
||||
ld a,(hl)
|
||||
.dseg
|
||||
peekc: db 0
|
||||
.cseg
|
||||
or a
|
||||
ret nz
|
||||
ld c,6
|
||||
ld e,-1
|
||||
push hl
|
||||
call 5
|
||||
pop hl
|
||||
ld (hl),a
|
||||
or a
|
||||
ret
|
||||
|
||||
locin: call locst
|
||||
jr z,locin
|
||||
ld (hl),0
|
||||
ret
|
||||
|
||||
locout: res 7,c
|
||||
ld e,c
|
||||
ld c,6
|
||||
jp 5
|
||||
|
77
source/RECV.Z
Normal file
77
source/RECV.Z
Normal file
@ -0,0 +1,77 @@
|
||||
; recv.z - protocol receive code for qterm
|
||||
|
||||
.incl "c:vars"
|
||||
|
||||
.extern recv
|
||||
recv:
|
||||
call pmode
|
||||
jr z,modok
|
||||
cp 'x'
|
||||
jp nz,moderr ; k & x are the only legal modes (for now)
|
||||
modok: inc hl
|
||||
push hl ; save pointer
|
||||
push af ; and mode character
|
||||
call unbyp ; step over flags
|
||||
call scnfcb ; parse name (or drive only for batch)
|
||||
ld hl,(fcb)
|
||||
ld (newusr),hl ; save receive drive and user
|
||||
pop bc
|
||||
pop hl
|
||||
jp z,nowcp
|
||||
push bc
|
||||
push hl
|
||||
call reset ; do a reset
|
||||
pop hl
|
||||
pop bc
|
||||
ld a,'k'
|
||||
cp b ; Kermit or Xmodem
|
||||
jr nz,recvx
|
||||
call recvk ; receive kermit
|
||||
jr xferd ; and unwrap
|
||||
recvx: call xmflgs ; parse xmodem flags
|
||||
call initx
|
||||
call initrc ; set up screen
|
||||
dorecv: call xrfile ; receive a file
|
||||
or a
|
||||
jr nz,dorecv ; loop if more to come
|
||||
ld a,(errorf)
|
||||
or a ; flag if there was an error or not
|
||||
|
||||
.extern xferd ; finish transfer - print completion message
|
||||
xferd:
|
||||
push af ; save z flag
|
||||
ld a,(beep)
|
||||
or a ; is a beep wanted?
|
||||
call nz,ilprt ; go beep ONLY IF ASKED!
|
||||
db 7,0 ; this ONLY works because 7 is a single byte
|
||||
; instruction: rlca.
|
||||
call mtprt
|
||||
dw [16 << 8] + 10
|
||||
db 'Transfer \0' ; start printout
|
||||
pop af
|
||||
ld hl,cplmsg ; assume all is well
|
||||
jr z,pxfmsg ; z => no error: go tell about it
|
||||
ld hl,ermsg ; else set up an error message
|
||||
pxfmsg: jp prtslp
|
||||
|
||||
.extern pmode
|
||||
pmode:
|
||||
pop hl
|
||||
ld (ressp),sp
|
||||
push hl
|
||||
call prompt
|
||||
db 'Mode? \0' ; how are we receiving?
|
||||
ld hl,ipbuf
|
||||
call byp ; see what first char is
|
||||
or a ; see if anything at all
|
||||
pop de
|
||||
ret z ; return to next lower level if not
|
||||
or 0x20 ; lower case
|
||||
push de
|
||||
cp 'k' ; check the 'k' of kermit
|
||||
ret
|
||||
|
||||
.dseg
|
||||
cplmsg: db 'complete\r\n\n\0'
|
||||
ermsg: db 'error\r\n\n\0'
|
||||
|
259
source/RECVK.Z
Normal file
259
source/RECVK.Z
Normal file
@ -0,0 +1,259 @@
|
||||
; recvk.z - code to receive kermit protocol transfers
|
||||
|
||||
.incl "c:vars"
|
||||
.incl "c:kermit"
|
||||
|
||||
.extern recvk
|
||||
recvk:
|
||||
call kinit
|
||||
call initrc
|
||||
xor a
|
||||
ld (nn),a
|
||||
ld (numtry),a
|
||||
ld (ksflg),a
|
||||
ld a,(getflg)
|
||||
or a
|
||||
call nz,sndget
|
||||
ld a,'R'
|
||||
recvlp: ld (state),a
|
||||
cp 'R'
|
||||
jr nz,norr
|
||||
call rinit
|
||||
jr recvlp
|
||||
norr: cp 'F'
|
||||
jr nz,norf
|
||||
call rfile
|
||||
jr recvlp
|
||||
norf: cp 'D'
|
||||
jr nz,nord
|
||||
call rdata
|
||||
jr recvlp
|
||||
nord: xor 'C'
|
||||
ret
|
||||
|
||||
rinit:
|
||||
ld hl,numtry
|
||||
ld a,(hl)
|
||||
inc (hl)
|
||||
cp MAXTRY + 1
|
||||
jr nc,reta
|
||||
call rpack
|
||||
cp 'S'
|
||||
jr nz,noris
|
||||
ld a,(nn)
|
||||
cp c
|
||||
jr nz,retan
|
||||
call rpar
|
||||
call spar
|
||||
call pktok
|
||||
ld a,'Y'
|
||||
ld bc,(nn)
|
||||
ld de,13
|
||||
ld b,d
|
||||
call spack
|
||||
ld hl,numtry
|
||||
ld a,(hl)
|
||||
ld (oldtry),a
|
||||
xor a
|
||||
ld (hl),a
|
||||
ld (getflg),a
|
||||
ld hl,nn
|
||||
inc (hl)
|
||||
res 6,(hl)
|
||||
ld a,(cktypq)
|
||||
ld (cktyp),a
|
||||
ld a,'F'
|
||||
ret
|
||||
noris: or a
|
||||
jr nz,norif
|
||||
call dtime
|
||||
ld a,(getflg)
|
||||
or a
|
||||
jr z,rinak
|
||||
call sndget
|
||||
jr rierr
|
||||
rinak: ld bc,(nn)
|
||||
ld de,0
|
||||
ld b,e
|
||||
ld a,'N'
|
||||
sretst: call spack
|
||||
rierr: call pkterr
|
||||
ld a,(state)
|
||||
ret
|
||||
norif: cp 'E'
|
||||
jr nz,retab
|
||||
call prerrp
|
||||
jr reta
|
||||
retan: call dnum
|
||||
jr reta
|
||||
retab: call dbadp
|
||||
jr reta
|
||||
retar: call dtries
|
||||
reta: ld a,'A'
|
||||
ret
|
||||
|
||||
rfile:
|
||||
ld hl,numtry
|
||||
ld a,(hl)
|
||||
inc (hl)
|
||||
cp MAXTRY + 1
|
||||
jr nc,reta
|
||||
call rpack
|
||||
cp 'S'
|
||||
jr nz,norfs
|
||||
ld hl,oldtry
|
||||
ld a,(hl)
|
||||
inc (hl)
|
||||
cp MAXTRY + 1
|
||||
jr nc,retar
|
||||
ld a,(nn)
|
||||
dec a
|
||||
and 63
|
||||
cp c
|
||||
jr nz,retan
|
||||
push de
|
||||
call spar
|
||||
pop de
|
||||
ld de,13
|
||||
ld b,d
|
||||
cntsrs: xor a
|
||||
ld (numtry),a
|
||||
ld a,'Y'
|
||||
jr sretst
|
||||
norfs: cp 'Z'
|
||||
jr nz,norfz
|
||||
ld hl,oldtry
|
||||
ld a,(hl)
|
||||
inc (hl)
|
||||
cp MAXTRY + 1
|
||||
retanc: jr nc,retar
|
||||
ld a,(nn)
|
||||
dec a
|
||||
and 63
|
||||
xor c
|
||||
jr nz,retan
|
||||
ld e,a
|
||||
ld d,a
|
||||
ld b,a
|
||||
jr cntsrs
|
||||
norfz: cp 'F'
|
||||
jr nz,norff
|
||||
ld a,(nn)
|
||||
cp c
|
||||
retanz: jr nz,retan
|
||||
ld hl,packet
|
||||
ld de,packet + 500
|
||||
ld a,(pack)
|
||||
or a
|
||||
jr z,nopkfn
|
||||
call exprp
|
||||
ld hl,packet + 500
|
||||
nopkfn: call cpmaux
|
||||
xor a
|
||||
ld (ymdmb),a
|
||||
call auxopn
|
||||
ld de,-1
|
||||
ld hl,auxfcb
|
||||
call prfile
|
||||
pokd: call pktok
|
||||
ld a,'Y'
|
||||
ld bc,(nn)
|
||||
ld de,0
|
||||
ld b,e
|
||||
call spack
|
||||
ld hl,numtry
|
||||
ld a,(hl)
|
||||
ld (oldtry),a
|
||||
ld (hl),0
|
||||
ld hl,nn
|
||||
inc (hl)
|
||||
res 6,(hl)
|
||||
ld a,'D'
|
||||
ret
|
||||
norff: cp 'B'
|
||||
noris1: jp nz,noris
|
||||
ld a,(nn)
|
||||
xor c
|
||||
retnz1: jr nz,retanz
|
||||
call pktok
|
||||
ld a,'Y'
|
||||
ld bc,(nn)
|
||||
ld de,0
|
||||
ld b,e
|
||||
call spack
|
||||
ld a,'C'
|
||||
ret
|
||||
|
||||
rdata:
|
||||
ld hl,numtry
|
||||
ld a,(hl)
|
||||
inc (hl)
|
||||
cp MAXTRY + 1
|
||||
retnc1: jp nc,retar
|
||||
call rpack
|
||||
cp 'D'
|
||||
jr nz,nordd
|
||||
ld a,(nn)
|
||||
cp c
|
||||
jr z,dnok
|
||||
ackold: ld hl,oldtry
|
||||
ld a,(hl)
|
||||
inc (hl)
|
||||
cp MAXTRY + 1
|
||||
jr nc,retnc1
|
||||
ld a,(nn)
|
||||
dec a
|
||||
and 63
|
||||
xor c
|
||||
retnz2: jr nz,retnz1
|
||||
ld e,a
|
||||
ld d,a
|
||||
ld b,a
|
||||
jp cntsrs
|
||||
dnok: call bufemp
|
||||
jp pokd
|
||||
nordd: cp 'F'
|
||||
jr z,ackold
|
||||
cp 'Z'
|
||||
jr nz,noris1
|
||||
ld a,(nn)
|
||||
cp c
|
||||
jr nz,retnz2
|
||||
call flshw2
|
||||
ld de,auxfcb
|
||||
ld c,close
|
||||
call usrbds
|
||||
call pktok
|
||||
ld hl,nn
|
||||
ld c,(hl)
|
||||
inc (hl)
|
||||
res 6,(hl)
|
||||
ld de,0
|
||||
ld b,e
|
||||
ld a,'Y'
|
||||
call spack
|
||||
ld a,'F'
|
||||
ret
|
||||
|
||||
sndget: ld bc,(getnam)
|
||||
ressg: ld hl,packet
|
||||
ld de,0xff
|
||||
sgelp: ld a,(bc)
|
||||
inc bc
|
||||
ld (hl),a
|
||||
cp ':'
|
||||
jr z,ressg
|
||||
cp MYQUOTE
|
||||
jr nz,noquot
|
||||
inc hl
|
||||
inc e
|
||||
ld (hl),a
|
||||
noquot: inc hl
|
||||
inc e
|
||||
or a
|
||||
jr nz,sgelp
|
||||
ld b,d
|
||||
ld c,d
|
||||
ld a,'R'
|
||||
jp spack
|
||||
|
359
source/RECVX.Z
Normal file
359
source/RECVX.Z
Normal file
@ -0,0 +1,359 @@
|
||||
; recvx.z - receive a file via xmodem protocol
|
||||
|
||||
.incl "c:vars"
|
||||
.incl "c:xmodem"
|
||||
|
||||
.extern xrfile
|
||||
xrfile:
|
||||
xor a
|
||||
ld (batch),a
|
||||
ld (ymdmb),a
|
||||
ld (fatal),a
|
||||
ld (errors),a
|
||||
ld (crcerc),a
|
||||
ld (errorf),a
|
||||
ld (openfl),a
|
||||
ld (secip),a
|
||||
ld (eotc),a
|
||||
ld h,a
|
||||
ld l,a
|
||||
ld (sectnm),hl
|
||||
ld (sntsec),hl
|
||||
ld l,128
|
||||
ld (bufsiz),hl
|
||||
call snint
|
||||
jr mainlp
|
||||
sndnk1: call flsnak
|
||||
mainlp: xor a
|
||||
ld (errorf),a
|
||||
reget: call gettc3
|
||||
ld hl,eotc
|
||||
jr c,nmoneh
|
||||
cp EOT
|
||||
jp z,soheot
|
||||
ld (hl),0
|
||||
cp CAN
|
||||
jr z,sohcan
|
||||
cp STX
|
||||
jr z,sohsh1
|
||||
cp SOH
|
||||
sohsh1: jp z,sohsoh
|
||||
cp ACK
|
||||
jr nz,reget
|
||||
sohack: ld hl,(sntsec)
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,reget
|
||||
ld (chksum),a
|
||||
ld de,auxfcb + 2
|
||||
ld b,NAMSIZ
|
||||
acknlp: ld a,4
|
||||
call gettcp
|
||||
jr c,nmonec
|
||||
cp CAN
|
||||
jr nz,nonmcn
|
||||
sohcan: call chkcan
|
||||
ret z
|
||||
nmonec: jp ckserr
|
||||
nmoneh: ld a,(hl)
|
||||
or a
|
||||
jp nz,ackeot
|
||||
jr nmonec
|
||||
nonmcn: cp EOT
|
||||
jr nz,nonmet
|
||||
ld hl,auxfcb + 2
|
||||
sbc hl,de
|
||||
ld a,l
|
||||
ret z
|
||||
ld a,BADNAM
|
||||
nonmet: cp BADNAM
|
||||
jr z,nmonec
|
||||
nmsavc: ld (de),a
|
||||
inc de
|
||||
ld hl,chksum
|
||||
add a,(hl)
|
||||
ld (hl),a
|
||||
ld a,ACK
|
||||
push bc
|
||||
push de
|
||||
call modopc
|
||||
pop de
|
||||
pop bc
|
||||
djnz acknlp
|
||||
call gettc3
|
||||
cp CTRLZ
|
||||
jr nz,nmonec
|
||||
ld hl,chksum
|
||||
add a,(hl)
|
||||
call modopc
|
||||
call gettc3
|
||||
cp ACK
|
||||
jr nz,nmonec
|
||||
ld hl,(newusr)
|
||||
ld (auxfcb),hl
|
||||
ld hl,auxfcb + 13
|
||||
ld de,auxfcb + 14
|
||||
ld bc,20
|
||||
ld (hl),b
|
||||
ldir
|
||||
call auxopn
|
||||
ld (batch),a
|
||||
ld (openfl),a
|
||||
call pktok
|
||||
jp setb
|
||||
sohsoh: ld hl,128
|
||||
cp SOH
|
||||
jr z,gotbsz
|
||||
ld hl,1024
|
||||
gotbsz: ld (bufsiz),hl
|
||||
ld hl,(sntsec)
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,noinit
|
||||
ld (errors),a
|
||||
noinit: call gettc3
|
||||
push af
|
||||
call gettc3
|
||||
pop bc
|
||||
ld c,a
|
||||
add a,b
|
||||
inc a
|
||||
jp nz,snerr
|
||||
ld a,(sectnm)
|
||||
inc a
|
||||
xor b
|
||||
jr nz,pnerr
|
||||
inc a
|
||||
ld (secip),a
|
||||
call redsec
|
||||
jp c,ckerr
|
||||
call pktok
|
||||
xor a
|
||||
ld (errors),a
|
||||
ld a,(bufsiz + 1)
|
||||
or a
|
||||
ld de,1
|
||||
jr z,updrsc
|
||||
ld e,8
|
||||
updrsc: ld hl,(sntsec)
|
||||
add hl,de
|
||||
ld (sntsec),hl
|
||||
ld hl,sectnm
|
||||
inc (hl)
|
||||
dec hl ; i.e. ld hl,openfl
|
||||
ld a,(hl)
|
||||
or a
|
||||
jr nz,isopen
|
||||
inc (hl)
|
||||
ld bc,13
|
||||
call xferaz
|
||||
ld de,auxfcb + 2
|
||||
ld a,(de)
|
||||
cp ' '
|
||||
jr nz,isaux
|
||||
ld hl,genfn
|
||||
ld bc,11
|
||||
ldir
|
||||
isaux: call auxopn
|
||||
jr isopen
|
||||
opener: call can3
|
||||
xor a
|
||||
ret
|
||||
isopen: ld hl,(bufsiz)
|
||||
ld de,xbuff
|
||||
wrtlp: ld a,(de)
|
||||
push de
|
||||
push hl
|
||||
call putw2c
|
||||
pop hl
|
||||
pop de
|
||||
inc de
|
||||
dec hl
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,wrtlp
|
||||
sndack: ld a,ACK
|
||||
call modopc
|
||||
jp mainlp
|
||||
pnerr: ld hl,(sntsec)
|
||||
ld a,h
|
||||
or l
|
||||
or b
|
||||
jr z,ymname
|
||||
ld a,(sectnm)
|
||||
cp b
|
||||
jr nz,numbad
|
||||
call diag
|
||||
db 'Duplicate sector flushed\0'
|
||||
flsdup: call gettc3
|
||||
jr nc,flsdup
|
||||
jr sndack
|
||||
numbad: call dnum
|
||||
ld a,1
|
||||
ld (fatal),a
|
||||
call can3
|
||||
jr ckserr
|
||||
ymname: call redsec
|
||||
jr c,ckerr
|
||||
call pktok
|
||||
ld a,(xbuff)
|
||||
or a
|
||||
jr nz,isynam
|
||||
ld a,ACK
|
||||
call modopc
|
||||
xor a
|
||||
ret
|
||||
isynam: ld (ymdmb),a
|
||||
ld hl,xbuff
|
||||
call cpmaux
|
||||
call auxopn
|
||||
ld a,ACK
|
||||
ld (batch),a
|
||||
ld (openfl),a
|
||||
call modopc
|
||||
ld b,20
|
||||
waitjn: push bc
|
||||
call tenth
|
||||
pop bc
|
||||
djnz waitjn
|
||||
jr setb
|
||||
snerr: call dnum
|
||||
ckserr: ld hl,errorf
|
||||
inc (hl)
|
||||
ckerr: call pkterr
|
||||
ld hl,errors
|
||||
inc (hl)
|
||||
ld hl,(sntsec)
|
||||
ld a,(secip)
|
||||
or h
|
||||
or l
|
||||
jr z,setb
|
||||
ld a,(errorf)
|
||||
or a
|
||||
jr z,noerr
|
||||
ld a,(fatal)
|
||||
or a
|
||||
jp nz,killit
|
||||
quiet: call gettc3
|
||||
jr nc,quiet
|
||||
jr sndnak
|
||||
setb: ld hl,errors
|
||||
ld a,(hl)
|
||||
xor CRCSW
|
||||
jr nz,crcnak
|
||||
ld (hl),a
|
||||
inc hl
|
||||
inc (hl)
|
||||
ld a,(hl)
|
||||
xor 4
|
||||
jp z,killit
|
||||
inc hl
|
||||
ld a,(hl)
|
||||
or a
|
||||
jr z,setcrc
|
||||
ld (hl),0
|
||||
call diag
|
||||
db 'Switching to checksum\0'
|
||||
jr crcnak
|
||||
setcrc: inc (hl)
|
||||
call diag
|
||||
db 'Switching to CRC\0'
|
||||
crcnak: call snint
|
||||
jr noerr
|
||||
sndnak: call flsnak
|
||||
noerr: ld a,(errors)
|
||||
cp ERRMAX
|
||||
jp c,mainlp
|
||||
killit: call can3
|
||||
xor a
|
||||
ret
|
||||
soheot: ld a,1
|
||||
call gettoc
|
||||
jr c,eotok
|
||||
call diag
|
||||
db 'EOT followed by character - ignored\0'
|
||||
jp ckserr
|
||||
eotok: ld hl,eotc
|
||||
ld a,(hl)
|
||||
or a
|
||||
jr nz,ackeot
|
||||
inc (hl)
|
||||
ld a,(errors)
|
||||
cp ERRMAX
|
||||
jr nc,killit
|
||||
jp sndnk1
|
||||
ackeot: call flshw2
|
||||
ld de,auxfcb
|
||||
ld c,close
|
||||
call usrbds
|
||||
ld a,ACK
|
||||
call modopc
|
||||
ld a,(batch)
|
||||
or a
|
||||
ret
|
||||
|
||||
redsec: ld hl,0
|
||||
ld (chksum),hl
|
||||
ld hl,(bufsiz)
|
||||
ld de,xbuff
|
||||
rblp: push hl
|
||||
push de
|
||||
call gettc3
|
||||
pop de
|
||||
jr nc,nordto
|
||||
pop hl
|
||||
rdtime: call dtime
|
||||
seterr: ld hl,errorf
|
||||
inc (hl)
|
||||
scf
|
||||
ret
|
||||
nordto: ld (de),a
|
||||
ld a,(crcmod)
|
||||
or a
|
||||
ld a,(de)
|
||||
jr z,updcsm
|
||||
push de
|
||||
call updcrc
|
||||
pop de
|
||||
jr mvptr
|
||||
updcsm: ld hl,chksum
|
||||
add a,(hl)
|
||||
ld (hl),a
|
||||
mvptr: pop hl
|
||||
inc de
|
||||
dec hl
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,rblp
|
||||
ld a,(crcmod)
|
||||
or a
|
||||
call nz,gettc3
|
||||
jr c,rdtime
|
||||
ld d,a
|
||||
push af
|
||||
call gettc3
|
||||
pop de
|
||||
jr c,rdtime
|
||||
ld e,a
|
||||
ld hl,(chksum)
|
||||
xor a
|
||||
sbc hl,de
|
||||
ret z
|
||||
ld a,(crcmod)
|
||||
or a
|
||||
jr nz,badcrc
|
||||
call dcheck
|
||||
jr seterr
|
||||
badcrc: call dcrc
|
||||
jr seterr
|
||||
|
||||
snint: ld a,(crcmod)
|
||||
or a
|
||||
ld a,CRCCHR
|
||||
jr nz,sendnc
|
||||
flsnak: ld a,NAK
|
||||
push af
|
||||
call flsrng
|
||||
pop af
|
||||
sendnc: jp modopc
|
||||
|
84
source/SEND.Z
Normal file
84
source/SEND.Z
Normal file
@ -0,0 +1,84 @@
|
||||
; send.z - protocol send code for qterm
|
||||
|
||||
.var ipbuf 0x80
|
||||
|
||||
.extern send
|
||||
send:
|
||||
call pmode
|
||||
inc hl
|
||||
jr z,modokk
|
||||
cp 'x'
|
||||
jr z,modok ; k & x are the only legal modes (for now)
|
||||
|
||||
.extern moderr
|
||||
moderr:
|
||||
call ilprt
|
||||
db 'Unknown mode\r\n\0'
|
||||
ret
|
||||
|
||||
modokk:
|
||||
ld a,(hl)
|
||||
or 0x20
|
||||
cp 'f'
|
||||
jr z,arefil
|
||||
cp 'l'
|
||||
jr z,arefil
|
||||
xor a
|
||||
modok: push hl ; save pointer
|
||||
push af ; and mode character
|
||||
call unbyp ; step over flags
|
||||
call scnswl ; parse names
|
||||
ld hl,(fnbspt)
|
||||
ld de,work
|
||||
pop af
|
||||
sbc hl,de
|
||||
pop hl
|
||||
jr nz,arefil ; any files found?
|
||||
call ilprt ; tell if not
|
||||
db 'No files to send\r\n\0'
|
||||
ret
|
||||
arefil: ex af,af'
|
||||
ld a,(xfersz) ; get proposed transfer size
|
||||
ld e,4
|
||||
sizlp: sla e ; shift size around in e
|
||||
rra
|
||||
jr nc,sizlp ; loop till we hit a bit
|
||||
ld a,e
|
||||
ld (btxf),a ; and save it away
|
||||
ex af,af'
|
||||
cp 'x' ; Kermit or Xmodem
|
||||
jr z,sendx
|
||||
call sendk ; send kermit
|
||||
jr xferdj ; and unwrap
|
||||
sendx: call xmflgs ; parse xmodem flags
|
||||
call initx
|
||||
call initsn ; set up screen
|
||||
ld hl,(mdm7b)
|
||||
ld a,h
|
||||
or l ; batch send?
|
||||
jr z,nosb ; no - just send one file
|
||||
ld a,(longpk)
|
||||
ld (olp),a ; save 1K packet flag
|
||||
sblp: call srnxt
|
||||
jr z,doneb ; loop till all names done
|
||||
call xsfile ; send a file
|
||||
jr nz,xferdj ; terminate on an error
|
||||
ld a,(olp)
|
||||
ld (longpk),a ; reset 1K packet flag
|
||||
jr sblp
|
||||
doneb: xor a
|
||||
ld (auxfcb + 2),a ; set flag for end of transfer
|
||||
jr xjsf
|
||||
nosb: call srnxt ; single file send - get it
|
||||
jr nz,xjsf ; send it if it exists
|
||||
call can3 ; kill the far end
|
||||
xor a
|
||||
inc a
|
||||
jr xferdj ; and return error
|
||||
xjsf: call xsfile ; send single file or batch close
|
||||
xferdj: push af
|
||||
ld a,(obtxf)
|
||||
ld (btxf),a ; reset transfer size to whatever
|
||||
pop af
|
||||
jp xferd
|
||||
|
262
source/SENDK.Z
Normal file
262
source/SENDK.Z
Normal file
@ -0,0 +1,262 @@
|
||||
; sendk.z - kermit send xfer code
|
||||
|
||||
.incl "c:vars"
|
||||
.incl "c:kermit"
|
||||
|
||||
.extern sendk
|
||||
sendk:
|
||||
call kinit
|
||||
call initsn
|
||||
ld a,(sercmd)
|
||||
or a
|
||||
ld l,'G'
|
||||
jr nz,sendit
|
||||
call srnxt
|
||||
ret z
|
||||
ld l,'S'
|
||||
sendit: xor a
|
||||
ld (nn),a
|
||||
ld (numtry),a
|
||||
ld a,l
|
||||
ld (ksflg),a
|
||||
sndklp: ld (state),a
|
||||
cp 'S'
|
||||
jr nz,nosini
|
||||
call sinit
|
||||
jr sndklp
|
||||
nosini: cp 'F'
|
||||
jr nz,nosfil
|
||||
call sfile
|
||||
jr sndklp
|
||||
nosfil: cp 'D'
|
||||
jr nz,nosdat
|
||||
call sdata
|
||||
jr sndklp
|
||||
nosdat: cp 'Z'
|
||||
jr nz,noseof
|
||||
call seof
|
||||
jr sndklp
|
||||
noseof: cp 'B'
|
||||
jr nz,nosbrk
|
||||
call sbreak
|
||||
jr sndklp
|
||||
nosbrk: cp 'G'
|
||||
jr nz,nossrv
|
||||
call sserve
|
||||
jr sndklp
|
||||
nossrv: xor 'C'
|
||||
ret
|
||||
|
||||
sinit:
|
||||
ld hl,numtry
|
||||
ld a,(hl)
|
||||
inc (hl)
|
||||
cp MAXTRY
|
||||
ld a,'A'
|
||||
ret nc
|
||||
call spar
|
||||
call flsrng
|
||||
ld a,'S'
|
||||
ld bc,(nn) ; packet number
|
||||
ld de,13 ; size
|
||||
ld b,d ; b == 0 => not extended
|
||||
call spack
|
||||
call rpack
|
||||
ld b,a
|
||||
cp 'N'
|
||||
jr nz,nosin
|
||||
retstt: ld a,b
|
||||
or a
|
||||
jr z,perr
|
||||
cp 'N'
|
||||
jr nz,pbn
|
||||
call dnak
|
||||
jr perr
|
||||
pbn: call dnum
|
||||
perr: call pkterr
|
||||
ld a,(state)
|
||||
ret
|
||||
nosin: or a
|
||||
jr z,perr
|
||||
cp 'E'
|
||||
jr nz,nosie
|
||||
call prerrp
|
||||
jr sreta1
|
||||
sireta: call dbadp
|
||||
sreta1: ld a,'A'
|
||||
ret
|
||||
nosie: cp 'Y'
|
||||
jr nz,sireta
|
||||
ld a,(nn)
|
||||
cp c
|
||||
jr nz,retstt
|
||||
ipakok: call rpar
|
||||
xor a
|
||||
ld (numtry),a
|
||||
ld hl,nn
|
||||
inc (hl)
|
||||
res 6,(hl)
|
||||
call pktok
|
||||
ld a,(cktypq)
|
||||
ld (cktyp),a
|
||||
ld a,'F'
|
||||
ret
|
||||
|
||||
sfile:
|
||||
ld hl,numtry
|
||||
ld a,(hl)
|
||||
inc (hl)
|
||||
cp MAXTRY
|
||||
ld a,'A'
|
||||
ret nc
|
||||
call kresgp
|
||||
ld de,auxfcb + 2
|
||||
ld hl,packet
|
||||
ld b,8
|
||||
call scnfil
|
||||
ld a,(de)
|
||||
and 0x7f
|
||||
cp ' '
|
||||
jr z,noext
|
||||
ld (hl),'.'
|
||||
inc hl
|
||||
ld b,3
|
||||
call scnfil
|
||||
noext: ld (hl),b
|
||||
ld de,packet
|
||||
sbc hl,de
|
||||
ld bc,(nn)
|
||||
ld e,l
|
||||
ld d,0
|
||||
ld b,d
|
||||
ld a,'F'
|
||||
finsf: call spack
|
||||
call rpack
|
||||
ld b,a
|
||||
cp 'N'
|
||||
jr nz,nosfn
|
||||
dec c
|
||||
res 7,c
|
||||
res 6,c
|
||||
ld a,'Y'
|
||||
nosfn: cp 'Y'
|
||||
jp nz,nosin
|
||||
ld a,(nn)
|
||||
xor c
|
||||
jp nz,retstt
|
||||
ld (numtry),a
|
||||
ld a,c
|
||||
inc a
|
||||
and 63
|
||||
ld (nn),a
|
||||
call pktok
|
||||
call bufill
|
||||
ld (size),bc
|
||||
inc a
|
||||
ld a,'Z'
|
||||
ret z
|
||||
ld a,'D'
|
||||
ret
|
||||
|
||||
sdata:
|
||||
ld hl,numtry
|
||||
ld a,(hl)
|
||||
inc (hl)
|
||||
cp MAXTRY
|
||||
ld a,'A'
|
||||
ret nc
|
||||
ld de,(size)
|
||||
ld bc,(nn)
|
||||
ld b,1
|
||||
ld a,e
|
||||
cp MAXPSIZ
|
||||
ld a,'D'
|
||||
jr nc,finsf
|
||||
ld b,d
|
||||
jr finsf
|
||||
|
||||
seof:
|
||||
ld hl,numtry
|
||||
ld a,(hl)
|
||||
inc (hl)
|
||||
cp MAXTRY
|
||||
ld a,'A'
|
||||
ret nc
|
||||
ld a,'Z'
|
||||
ld bc,(nn)
|
||||
ld de,0
|
||||
ld b,e
|
||||
call spack
|
||||
call rpack
|
||||
ld b,a
|
||||
cp 'N'
|
||||
jr nz,nosen
|
||||
dec c
|
||||
res 7,c
|
||||
res 6,c
|
||||
ld a,'Y'
|
||||
nosen: cp 'Y'
|
||||
jp nz,nosin
|
||||
ld a,(nn)
|
||||
xor c
|
||||
jp nz,retstt
|
||||
ld (numtry),a
|
||||
ld a,c
|
||||
inc a
|
||||
and 63
|
||||
ld (nn),a
|
||||
call pktok
|
||||
call srnxt
|
||||
ld a,'F'
|
||||
ret nz
|
||||
ld a,'B'
|
||||
ret
|
||||
|
||||
sbreak:
|
||||
ld hl,numtry
|
||||
ld a,(hl)
|
||||
inc (hl)
|
||||
cp MAXTRY
|
||||
ld a,'A'
|
||||
ret nc
|
||||
ld a,'B'
|
||||
ld de,0
|
||||
finsb: ld bc,(nn)
|
||||
ld b,d
|
||||
call spack
|
||||
call rpack
|
||||
ld b,a
|
||||
cp 'N'
|
||||
jr nz,nosbn
|
||||
dec c
|
||||
res 7,c
|
||||
res 6,c
|
||||
ld a,'Y'
|
||||
nosbn: cp 'Y'
|
||||
jp nz,nosin
|
||||
ld a,(nn)
|
||||
xor c
|
||||
jp nz,retstt
|
||||
ld (numtry),a
|
||||
ld a,c
|
||||
inc a
|
||||
and 63
|
||||
ld (nn),a
|
||||
call pktok
|
||||
ld a,'C'
|
||||
ret
|
||||
|
||||
sserve:
|
||||
ld hl,numtry
|
||||
ld a,(hl)
|
||||
inc (hl)
|
||||
cp MAXTRY
|
||||
ld a,'A'
|
||||
ret nc
|
||||
ld a,(sercmd)
|
||||
and 0x5f
|
||||
ld (packet),a
|
||||
ld a,'G'
|
||||
ld de,1
|
||||
jr finsb
|
||||
|
402
source/SENDX.Z
Normal file
402
source/SENDX.Z
Normal file
@ -0,0 +1,402 @@
|
||||
; sendx.z - file send using xmodem protocol
|
||||
|
||||
.incl "c:vars"
|
||||
.incl "c:xmodem"
|
||||
|
||||
.extern xsfile
|
||||
xsfile:
|
||||
xor a
|
||||
ld (closeo),a
|
||||
ld (attmps),a
|
||||
ld a,(auxfcb + 2)
|
||||
or a
|
||||
jr nz,noclos
|
||||
inc a
|
||||
ld (closeo),a
|
||||
jr sbufsz
|
||||
noclos: ld de,auxfcb
|
||||
ld c,cfsize
|
||||
call usrbds
|
||||
ld hl,(auxfcb + 34)
|
||||
ld (expsec),hl
|
||||
sbufsz: ld a,(longpk)
|
||||
or a
|
||||
ld hl,128
|
||||
jr z,gotbsz
|
||||
ld hl,1024
|
||||
gotbsz: ld (bufsiz),hl
|
||||
waitsu: ld a,30
|
||||
call gettoc
|
||||
cp 'K'
|
||||
jr z,waitsu
|
||||
cp CAN
|
||||
jr z,sucan
|
||||
cp CRCCHR
|
||||
jr z,sucrcn
|
||||
xor NAK
|
||||
jr z,sucrcn
|
||||
ld hl,attmps
|
||||
inc (hl)
|
||||
ld a,(hl)
|
||||
cp NAKMAX
|
||||
jr c,waitsu
|
||||
call rnresp
|
||||
jr m7err
|
||||
sucan: call chkcan
|
||||
jr nz,waitsu
|
||||
jr m7err
|
||||
sucrcn: ld (crcmod),a
|
||||
ld a,(mdm7b)
|
||||
or a
|
||||
jp z,nom7
|
||||
ld a,(closeo)
|
||||
or a
|
||||
jr z,nom7c
|
||||
ld a,ACK
|
||||
call modopc
|
||||
ld a,EOT
|
||||
call modopc
|
||||
xor a
|
||||
ret
|
||||
nom7c: ld (attmps),a
|
||||
call sndnam
|
||||
jr nc,m7nmok
|
||||
call pkterr
|
||||
ld a,(attmps)
|
||||
inc a
|
||||
cp RETRMX
|
||||
jr c,nom7c
|
||||
call diag
|
||||
db 'MODEM7 batch filename error\0'
|
||||
m7errc: call can3
|
||||
m7err: xor a
|
||||
inc a
|
||||
ret
|
||||
m7nmok: call pktok
|
||||
wack: ld a,5
|
||||
call gettoc
|
||||
cp 'K'
|
||||
jr z,wack
|
||||
cp CRCCHR
|
||||
jr z,setm7c
|
||||
xor NAK
|
||||
jr z,setm7c
|
||||
call diag
|
||||
db 'MODEM7 error: NAK/C expected\0'
|
||||
jr m7errc
|
||||
setm7c: ld (crcmod),a
|
||||
nom7: ld hl,1
|
||||
ld (sectnm),hl
|
||||
ld a,(ymdmb)
|
||||
or a
|
||||
jr z,noymf
|
||||
ld hl,128
|
||||
ld (bufsiz),hl
|
||||
ld l,h
|
||||
ld (sectnm),hl
|
||||
noymf: xor a
|
||||
ld (errors),a
|
||||
ld h,a
|
||||
ld l,a
|
||||
ld (sntsec),hl
|
||||
packlp: xor a
|
||||
ld (attmps),a
|
||||
ld a,(ymdmb)
|
||||
or a
|
||||
jr z,noym
|
||||
ld hl,(sectnm)
|
||||
dec hl
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,noym
|
||||
ld a,(closeo)
|
||||
or a
|
||||
jr z,noymc
|
||||
xor a
|
||||
ret
|
||||
noymc: ld a,(longpk)
|
||||
or a
|
||||
jr z,getyfs
|
||||
ld h,1024 >> 8
|
||||
ld (bufsiz),hl
|
||||
getyfs: call gettc3
|
||||
cp CAN
|
||||
jr z,yfscan
|
||||
cp 'K'
|
||||
jr z,getyfs
|
||||
cp CRCCHR
|
||||
jr z,yfscrc
|
||||
ld hl,attmps
|
||||
inc (hl)
|
||||
ld a,(hl)
|
||||
cp NAKMAX
|
||||
jr c,getyfs
|
||||
call diag
|
||||
db 'YMODEM error: C expected\0'
|
||||
yfserc: call can3
|
||||
yfserr: xor a
|
||||
inc a
|
||||
ret
|
||||
yfscan: call chkcan
|
||||
jr nz,getyfs
|
||||
jr yfserr
|
||||
yfscrc: ld (crcmod),a
|
||||
xor a
|
||||
ld (attmps),a
|
||||
noym: ld a,(bufsiz 1)
|
||||
or a
|
||||
jr z,bsok
|
||||
ld a,(errors)
|
||||
cp KSWMAX
|
||||
jr nz,noksw
|
||||
call diag
|
||||
db 'Too many errors - reducing packet size\0'
|
||||
xor a
|
||||
ld (olp),a
|
||||
jr dropbs
|
||||
noksw: ld hl,(expsec)
|
||||
ld de,(sntsec)
|
||||
or a
|
||||
sbc hl,de
|
||||
jr z,bsok
|
||||
ld a,l
|
||||
and ~7
|
||||
or h
|
||||
jr nz,bsok
|
||||
call diag
|
||||
db 'End of file - reducing packet size\0'
|
||||
dropbs: ld hl,128
|
||||
ld (bufsiz),hl
|
||||
xor a
|
||||
ld (longpk),a
|
||||
bsok: ld hl,(sectnm)
|
||||
ld a,h
|
||||
or l
|
||||
jr z,ymname
|
||||
ld de,xbuff
|
||||
ld hl,(bufsiz)
|
||||
filbuf: push hl
|
||||
push de
|
||||
call getw2c
|
||||
pop de
|
||||
pop hl
|
||||
jp c,pakbrk
|
||||
ld (de),a
|
||||
inc de
|
||||
dec hl
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,filbuf
|
||||
jr xmitlp
|
||||
ymname: ld hl,xbuff
|
||||
ld de,xbuff + 1
|
||||
ld bc,127
|
||||
ld (hl),b
|
||||
ldir
|
||||
ld a,(closeo)
|
||||
or a
|
||||
jr nz,noymnm
|
||||
ld de,auxfcb + 2
|
||||
ld hl,xbuff
|
||||
ld b,8
|
||||
call scnfil
|
||||
ld a,(de)
|
||||
and 0x7f
|
||||
cp ' '
|
||||
jr z,noext
|
||||
ld (hl),'.'
|
||||
inc hl
|
||||
ld b,3
|
||||
call scnfil
|
||||
noext: ld hl,xbuff - 1
|
||||
lower: inc hl
|
||||
ld a,(hl)
|
||||
or a
|
||||
jr z,setfs
|
||||
cp 'A'
|
||||
jr c,lower
|
||||
cp 'Z' + 1
|
||||
jr nc,lower
|
||||
set 5,(hl)
|
||||
jr lower
|
||||
setfs: ld hl,(expsec)
|
||||
ld (xbuff + 126),hl
|
||||
noymnm: xor a
|
||||
ld (attmps),a
|
||||
xmitlp: ld a,(bufsiz + 1)
|
||||
or a
|
||||
ld a,SOH
|
||||
jr z,gotsoh
|
||||
inc a
|
||||
gotsoh: call modopc
|
||||
ld a,(sectnm)
|
||||
push af
|
||||
call modopc
|
||||
pop af
|
||||
cpl
|
||||
call modopc
|
||||
ld hl,0
|
||||
ld (chksum),hl
|
||||
ld hl,(bufsiz)
|
||||
ld de,xbuff
|
||||
snddat: ld a,(de)
|
||||
push hl
|
||||
push de
|
||||
call modopc
|
||||
pop de
|
||||
ld a,(crcmod)
|
||||
or a
|
||||
ld a,(de)
|
||||
jr z,updcsm
|
||||
push de
|
||||
call updcrc
|
||||
pop de
|
||||
jr sndcnt
|
||||
updcsm: ld hl,chksum
|
||||
add a,(hl)
|
||||
ld (hl),a
|
||||
sndcnt: pop hl
|
||||
inc de
|
||||
dec hl
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,snddat
|
||||
call flsrng
|
||||
ld a,(crcmod)
|
||||
or a
|
||||
ld a,(chksum + 1)
|
||||
call nz,modopc
|
||||
ld a,(chksum)
|
||||
call modopc
|
||||
ld hl,attmps
|
||||
inc (hl)
|
||||
ld a,10
|
||||
call gettoc
|
||||
jr c,timeo
|
||||
cp ACK
|
||||
jr z,respok
|
||||
cp CAN
|
||||
jr nz,nocan
|
||||
call chkcan
|
||||
jp z,m7err
|
||||
nocan: push af
|
||||
call cvtnib
|
||||
ld (char + 1),a
|
||||
pop af
|
||||
rrca
|
||||
rrca
|
||||
rrca
|
||||
rrca
|
||||
call cvtnib
|
||||
ld (char),a
|
||||
call diag
|
||||
db 'Non-ACK: 0x'
|
||||
char: db 'ZZ\0'
|
||||
jr ackerr
|
||||
timeo: call diag
|
||||
db 'Timeout\0'
|
||||
ackerr: call pkterr
|
||||
ld hl,errors
|
||||
inc (hl)
|
||||
ld a,(attmps)
|
||||
cp RETRMX
|
||||
jr nc,retrer
|
||||
ld a,(hl)
|
||||
cp ERRMAX
|
||||
jp c,xmitlp
|
||||
call diag
|
||||
db 'Too many errors\0'
|
||||
jr rtrcan
|
||||
retrer: call diag
|
||||
db 'Too many retries\0'
|
||||
rtrcan: jp m7errc
|
||||
respok: call pktok
|
||||
ld hl,(sectnm)
|
||||
inc hl
|
||||
ld (sectnm),hl
|
||||
dec hl
|
||||
ld a,h
|
||||
or l
|
||||
jr z,jppl
|
||||
ld a,(bufsiz + 1)
|
||||
ld de,8
|
||||
or a
|
||||
jr nz,updss
|
||||
ld e,1
|
||||
updss: ld hl,(sntsec)
|
||||
add hl,de
|
||||
ld (sntsec),hl
|
||||
jppl: jp packlp
|
||||
pakbrk: ld b,RETRMX
|
||||
eotlp: push bc
|
||||
ld a,EOT
|
||||
call modopc
|
||||
ld a,15
|
||||
call gettoc
|
||||
pop bc
|
||||
cp ACK
|
||||
jr z,didit
|
||||
cp NAK
|
||||
jr z,eotlp
|
||||
eotna: call diag
|
||||
db 'EOT not acked\0'
|
||||
badeot: djnz eotlp
|
||||
call rnresp
|
||||
xor a
|
||||
inc a
|
||||
ret
|
||||
didit: xor a
|
||||
ret
|
||||
|
||||
.extern sndnam
|
||||
sndnam:
|
||||
ld hl,auxfcb + 2
|
||||
ld de,auxlin
|
||||
push de
|
||||
ld bc,11
|
||||
ldir
|
||||
pop hl
|
||||
ld bc,11 << 8
|
||||
ld a,ACK
|
||||
call moppsh
|
||||
snlp: call mopahl
|
||||
cknak: ld a,6
|
||||
call gettcp
|
||||
cp CAN
|
||||
jr nz,nocan1
|
||||
ld a,3
|
||||
call gettcp
|
||||
cp CAN
|
||||
jr nz,cknak
|
||||
scf
|
||||
ret
|
||||
nocan1: cp ACK
|
||||
jr nz,badnam
|
||||
acknam: inc hl
|
||||
djnz snlp
|
||||
ld (hl),0x1a
|
||||
call mopahl
|
||||
ld a,10
|
||||
call gettcp
|
||||
cp c
|
||||
jr nz,badnam
|
||||
ld a,ACK
|
||||
call modopc
|
||||
or a
|
||||
ret
|
||||
badnam: ld a,BADNAM
|
||||
call modopc
|
||||
scf
|
||||
ret
|
||||
|
||||
mopahl: ld a,(hl)
|
||||
add a,c
|
||||
ld c,a
|
||||
ld a,(hl)
|
||||
moppsh: push bc
|
||||
push hl
|
||||
call modopc
|
||||
pop hl
|
||||
pop bc
|
||||
ret
|
||||
|
48
source/SHRINK.Z
Normal file
48
source/SHRINK.Z
Normal file
@ -0,0 +1,48 @@
|
||||
; shrink.z - buffers and pointers that get small for a "shrunk" QTERM
|
||||
|
||||
.var memtop 6
|
||||
|
||||
.extern setshr
|
||||
setshr:
|
||||
ld hl,(memtop)
|
||||
ld de,work2 + 16384 + 1024
|
||||
or a
|
||||
sbc hl,de
|
||||
ex de,hl
|
||||
ld hl,xfersz
|
||||
set 3,(hl)
|
||||
ret nc
|
||||
set 2,(hl)
|
||||
ld hl,work2 + 4096
|
||||
ld (cbuff),hl
|
||||
ld hl,work2 + 8192
|
||||
ld (endcbf),hl
|
||||
ld hl,4095
|
||||
ld (cbfsiz),hl
|
||||
ld a,4096 / 128
|
||||
ld (btxf),a
|
||||
ld (obtxf),a
|
||||
ld hl,8192
|
||||
add hl,de
|
||||
ret c
|
||||
call ilprt
|
||||
db 'Insufficient memory\r\n\0'
|
||||
rst 0
|
||||
|
||||
.dseg
|
||||
.extern cbuff
|
||||
cbuff: dw work2 + 8192
|
||||
.extern endcbf
|
||||
endcbf: dw work2 + 16384
|
||||
.extern cbfsiz
|
||||
cbfsiz: dw 8191
|
||||
.extern btxf
|
||||
btxf: db 8192 / 128
|
||||
.extern obtxf
|
||||
obtxf: db 8192 / 128
|
||||
|
||||
.useg
|
||||
.extern work2
|
||||
work2:
|
||||
ds 16384 ; so that #end in the .SYM file is right
|
||||
|
226
source/SRSCRN.Z
Normal file
226
source/SRSCRN.Z
Normal file
@ -0,0 +1,226 @@
|
||||
; srscrn.z - screen routines for displaying status of a transfer
|
||||
|
||||
.incl "c:termcap"
|
||||
|
||||
.extern initsc ; initialise everything
|
||||
initsc:
|
||||
push hl
|
||||
ld hl,0
|
||||
ld (packet),hl
|
||||
ld (terr),hl
|
||||
ld (perr),hl ; clear the variables
|
||||
call clear ; and the screen
|
||||
ld hl,30
|
||||
call moveto ; set up for the title
|
||||
pop hl
|
||||
call prtslp ; print protocol type
|
||||
ld hl,m1
|
||||
.dseg
|
||||
m1: db ' File Transfer\0'
|
||||
.cseg
|
||||
call prtslp ; finish title
|
||||
call mtprt
|
||||
dw [5 << 8] + 10
|
||||
db 'Packet:\0'
|
||||
call mtprt
|
||||
dw [5 << 8] + 26
|
||||
db '0\0'
|
||||
call mtprt
|
||||
dw [7 << 8] + 10
|
||||
db 'Packet Errors: 0\0'
|
||||
call mtprt
|
||||
dw [9 << 8] + 10
|
||||
db 'Total Errors: 0\0'
|
||||
ret ; print rest of screen background
|
||||
|
||||
.extern initsn ; finish setting up screen for send
|
||||
initsn:
|
||||
call mtprt
|
||||
dw [3 << 8] + 10
|
||||
db 'Sending:\0' ; direction for where filename goes
|
||||
call mtprt
|
||||
dw [11 << 8] + 10
|
||||
db 'Sent:\0' ; set up for K transferred printout
|
||||
ret
|
||||
|
||||
.extern initrc ; finish setting up screen for receive
|
||||
initrc:
|
||||
call mtprt
|
||||
dw [3 << 8] + 10
|
||||
db 'Receiving:\0' ; direction for where filename goes
|
||||
call mtprt
|
||||
dw [11 << 8] + 10
|
||||
db 'Received:\0' ; and for K transferred
|
||||
ret
|
||||
|
||||
.extern pktok ; register a good packet
|
||||
pktok:
|
||||
ld hl,kcnt ; point at k count flag
|
||||
ld a,(hl) ; get value
|
||||
or a
|
||||
jr z,nokprt ; not set, so don't print
|
||||
dec (hl) ; clear flag
|
||||
call one_k ; and print a K
|
||||
nokprt: ld hl,dcnt ; look at count till we need clear
|
||||
ld a,(hl)
|
||||
or a
|
||||
jr z,nocdg ; no clear needed - bypass
|
||||
dec (hl)
|
||||
jr nz,nocdg ; not yet ..... skip it
|
||||
call diag
|
||||
db 0 ; OK there goes the message
|
||||
xor a
|
||||
ld (dcnt),a ; and reset dcnt back to zero
|
||||
nocdg: ld hl,(perr)
|
||||
ld a,h
|
||||
or l
|
||||
jr z,ncperr
|
||||
call mtprt
|
||||
dw [7 << 8] + 26
|
||||
db '0 \0' ; reset packet error count on screen
|
||||
ld hl,0
|
||||
ld (perr),hl ; and in memory
|
||||
ncperr: ld a,(qcount)
|
||||
or a
|
||||
ret nz
|
||||
ld hl,[5 << 8] + 26
|
||||
call moveto ; moveto where packet number goes
|
||||
ld hl,(packet)
|
||||
inc hl
|
||||
ld (packet),hl ; bump
|
||||
jp decout ; and print
|
||||
|
||||
.extern pkterr ; register a bad packet
|
||||
pkterr:
|
||||
ld hl,[7 << 8] + 26
|
||||
call moveto
|
||||
ld hl,(perr)
|
||||
inc hl
|
||||
ld (perr),hl ; bump and print packet errors
|
||||
call decout
|
||||
ld hl,[9 << 8] + 26
|
||||
call moveto
|
||||
ld hl,(terr)
|
||||
inc hl
|
||||
ld (terr),hl ; same for total errors
|
||||
jp decout
|
||||
|
||||
.extern prfile ; print the filename from auxfcb
|
||||
prfile:
|
||||
push hl
|
||||
ld a,d
|
||||
and e
|
||||
inc a ; check if there's a real size
|
||||
jr z,noprte ; skip if not - this is receive
|
||||
push de
|
||||
call mtprt
|
||||
dw [11 << 8] + 34
|
||||
db 'out of \0' ; and file size print
|
||||
pop hl
|
||||
call decout ; and print it
|
||||
ld hl,m2
|
||||
call prtslp ; and the 'K'
|
||||
noprte: ld hl,0
|
||||
ld (kxfer),hl ; reset count of K transferred
|
||||
call mtprt
|
||||
dw [11 << 8] + 26
|
||||
db '0' ; and print 0K to start things
|
||||
m2: db 'K \0'
|
||||
ld hl,[3 << 8] + 26
|
||||
call moveto ; move to where filename gets printed
|
||||
pop hl ; get fcb address to hl
|
||||
call prtfl ; print the filename
|
||||
ld b,14 ; 14 chars to nuke anything left over
|
||||
jr cleol
|
||||
|
||||
.extern prtfl
|
||||
prtfl:
|
||||
ld c,(hl) ; get user number to c
|
||||
inc hl
|
||||
ld a,(hl) ; get drive code
|
||||
inc hl ; point at first char of name
|
||||
push hl ; save fcb address
|
||||
push bc ; save user number
|
||||
add a,'@' ; convert to a letter
|
||||
ld c,a
|
||||
call scrout ; and print it
|
||||
pop hl ; user number back to l
|
||||
call decob ; and print it
|
||||
ld c,':'
|
||||
call scrout ; add a ':'
|
||||
pop hl
|
||||
nodrv: ld b,8
|
||||
call pfilnm ; print the name portion
|
||||
ld a,(hl)
|
||||
cp ' ' ; check for an extension
|
||||
ret z ; no - all done
|
||||
push hl
|
||||
ld c,'.'
|
||||
call scrout ; print a '.'
|
||||
pop hl
|
||||
ld b,3
|
||||
|
||||
pfilnm: ld a,(hl) ; get a char from fcb
|
||||
inc hl
|
||||
push hl
|
||||
push bc
|
||||
and 0x7f ; ditch attribute bit
|
||||
cp ' ' ; is it printable?
|
||||
ld c,a
|
||||
call nz,scrout ; print if so
|
||||
pop bc
|
||||
pop hl
|
||||
djnz pfilnm ; loop till all done
|
||||
ret
|
||||
|
||||
.extern diag
|
||||
diag:
|
||||
ld a,3
|
||||
ld (dcnt),a ; set so that 3 packets later we'll clear
|
||||
ld hl,[14 << 8] + 10
|
||||
call moveto ; move to where messages go
|
||||
pop hl ; string address to hl
|
||||
push hl ; back on stack
|
||||
call prtslp ; print it
|
||||
pop de ; restore start to de
|
||||
push hl ; save end
|
||||
or a
|
||||
sbc hl,de ; get length
|
||||
ld a,50
|
||||
sub l ; get 50 - length
|
||||
ld b,a ; to b
|
||||
cleol: ld a,(tcbits)
|
||||
and b_cleol ; clear to eol possible
|
||||
jp z,cleol ; do it if so
|
||||
ld c,' ' ; put a space in c
|
||||
cleolp: push bc
|
||||
call scrout ; and print it
|
||||
pop bc
|
||||
djnz cleolp ; till count runs out
|
||||
ret
|
||||
|
||||
.extern one_k
|
||||
one_k:
|
||||
ld a,(qcount)
|
||||
or a
|
||||
ret nz
|
||||
ld hl,[11 << 8] + 26
|
||||
call moveto ; move to where K printout goes
|
||||
ld hl,(kxfer)
|
||||
inc hl
|
||||
ld (kxfer),hl ; add one to count
|
||||
call decout ; print the number
|
||||
ld c,'K'
|
||||
jp scrout ; and add a 'K'
|
||||
|
||||
.dseg
|
||||
.extern kcnt
|
||||
kcnt: db 0
|
||||
|
||||
.useg
|
||||
dcnt: ds 1
|
||||
packet: ds 2
|
||||
terr: ds 2
|
||||
perr: ds 2
|
||||
kxfer: ds 2
|
||||
|
468
source/SRUTIL.Z
Normal file
468
source/SRUTIL.Z
Normal file
@ -0,0 +1,468 @@
|
||||
; srutil.z - utilities for file transfer
|
||||
|
||||
.incl "c:vars"
|
||||
|
||||
.extern kgettc ; kgettc - get a character for kermit - we
|
||||
kgettc: ; wait as prescribed by kermit's timint
|
||||
ld a,(timint) ; get the timeout
|
||||
; fall into gettcp
|
||||
|
||||
.extern gettcp ; call gettoc, but save registers as we do so
|
||||
gettcp:
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
call gettoc
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
.extern gettc3 ; calls gettoc with a timeout of 3 seconds
|
||||
gettc3:
|
||||
ld a,4 ; set up, and fall through
|
||||
|
||||
.extern gettoc ; gettoc - get a character, noting timeout.
|
||||
gettoc: ; enter with timeout (in seconds) in a, return
|
||||
; char in a, carry set <=> timeout
|
||||
ld c,a ; seconds of timeout to c
|
||||
push bc
|
||||
call fstmc ; quick pre-check to make sure this has a
|
||||
pop bc ; chance of working at 38400
|
||||
ret nc
|
||||
gtlp: push bc
|
||||
call kbdcc ; character from kbd?
|
||||
xor 'x' & 0x1f ; was it a ^X?
|
||||
jr nz,noab
|
||||
ld hl,(abortf) ; abort function set up?
|
||||
ld e,a
|
||||
ld d,a
|
||||
ld (abortf),de ; kill it whatever
|
||||
ld a,h
|
||||
or l
|
||||
jr z,noab ; nope - don't do anything
|
||||
jp (hl) ; go do the abort code
|
||||
noab: pop bc
|
||||
ld de,1100
|
||||
call setspd ; set delay value
|
||||
qrtrms: push hl
|
||||
push bc
|
||||
call fstmc ; check for a char at the modem
|
||||
pop bc
|
||||
pop hl
|
||||
ret nc ; yes - send it back
|
||||
ld b,60 ; wait a while
|
||||
qmslp: djnz qmslp
|
||||
dec hl
|
||||
ld a,h
|
||||
or l
|
||||
jr nz,qrtrms ; count down hl
|
||||
dec c
|
||||
jr nz,gtlp ; and seconds
|
||||
scf ; timed out - return w/ carry
|
||||
ret
|
||||
|
||||
fstmc: call modist ; modem character available?
|
||||
scf
|
||||
ret z ; return with carry if not
|
||||
call modin ; get one if so
|
||||
or a ; and clear carry
|
||||
ret
|
||||
|
||||
.extern flsrng
|
||||
flsrng: call fstmc ; get a char if there's one there
|
||||
jr nc,flsrng ; loop while they're coming
|
||||
ret ; exit - all flushed
|
||||
|
||||
.extern srnxt ; get next name from batched list for send
|
||||
srnxt:
|
||||
call nxtnam ; get next name from buffer to fcb
|
||||
ret z ; all done - return zero
|
||||
call xferax ; move fcb from fcb to auxfcb
|
||||
ld de,auxfcb
|
||||
push de ; get and save it's address
|
||||
ld c,open
|
||||
call usrbds ; try to open the file
|
||||
ld h,l
|
||||
pop de
|
||||
add a,a ; test a == -1 this way so we get a carry on
|
||||
sbc a,a ; failure
|
||||
ret nz ; open failed - return now
|
||||
push de
|
||||
ld c,cfsize
|
||||
call usrbds ; how big is it?
|
||||
ld de,(auxfcb + 34)
|
||||
dec de
|
||||
ld a,d
|
||||
and e
|
||||
inc a ; was de dec'ed from 0 to 0xffff
|
||||
ld a,(auxfcb + 36)
|
||||
jr nz,aok
|
||||
dec a ; drop a by 1 if so (big file!)
|
||||
aok: ld b,3
|
||||
mulk: rra ; convert 128 byte blocks to K
|
||||
rr d
|
||||
rr e ; shift right
|
||||
djnz mulk
|
||||
inc de ; reset de - we ditch what's left in a
|
||||
pop hl ; fcb back to hl
|
||||
call prfile ; print file
|
||||
xor a ; clear carry
|
||||
inc a ; and z flag
|
||||
|
||||
.extern clrw2
|
||||
clrw2:
|
||||
ld (onekp),a
|
||||
ld hl,(w2ptr)
|
||||
ld (endw2),hl ; set pointers so reads from getw2c work
|
||||
ret
|
||||
|
||||
.extern getw2c ; get a character from work2, via fcb at
|
||||
getw2c: ; auxfcb, return c on eof
|
||||
ld de,(w2ptr) ; get current read pointer
|
||||
ld hl,(endw2)
|
||||
or a
|
||||
sbc hl,de ; compare with end of data
|
||||
ld hl,work2 - 1
|
||||
jr z,fillw2 ; at end of buffer - go fill it up again
|
||||
sbc hl,de ; see how far down buffer we are
|
||||
ld a,h
|
||||
and 3
|
||||
or l ; on a K boundary?
|
||||
push de
|
||||
jr nz,no1k
|
||||
ld a,(onekp) ; printing k?
|
||||
ld (kcnt),a
|
||||
no1k: ld hl,b7flag ; zapping bit 7?
|
||||
ld a,(hl) ; get the mask
|
||||
pop hl
|
||||
and (hl) ; mask a character (and clear the carry)
|
||||
inc hl
|
||||
ld (w2ptr),hl ; resave new pointer
|
||||
ret
|
||||
fillw2: ld a,(btxf)
|
||||
ld b,a
|
||||
inc hl
|
||||
ld (w2ptr),hl ; get dma address & reset read pointer
|
||||
filw2l: push bc
|
||||
push hl
|
||||
ex de,hl
|
||||
ld c,setdma
|
||||
call bdos ; set dma
|
||||
ld de,auxfcb
|
||||
ld c,read
|
||||
call usrbds ; read
|
||||
pop hl
|
||||
pop bc
|
||||
or a
|
||||
jr nz,filled ; eof - exit now
|
||||
ex de,hl
|
||||
ld hl,lbrcnt
|
||||
inc (hl) ; .LBR active?
|
||||
jr z,cntok ; nope, don't check
|
||||
dec (hl) ; adjust count
|
||||
cntok: dec (hl)
|
||||
ld hl,128
|
||||
add hl,de ; bump dma
|
||||
jr z,filled ; exit if all done
|
||||
djnz filw2l ; loop till count runs out
|
||||
filled: ld (endw2),hl ; save end pointer
|
||||
ld de,work2
|
||||
or a
|
||||
sbc hl,de ; anything in buffer?
|
||||
ccf
|
||||
ret z ; return with carry if not
|
||||
jr getw2c ; else jump back & get a character
|
||||
|
||||
.extern gw2pb ; push a character back onto work2
|
||||
gw2pb:
|
||||
ld hl,(w2ptr) ; get current read pointer
|
||||
dec hl ; decrease
|
||||
ld (hl),a ; and save character
|
||||
ld (w2ptr),hl ; restore pointer
|
||||
ret
|
||||
|
||||
.extern putw2c ; output a character in a to file at auxfcb
|
||||
putw2c: ; update K count as needed
|
||||
ld hl,(w2ptr)
|
||||
ld (hl),a ; save the character
|
||||
inc hl
|
||||
ld (w2ptr),hl
|
||||
ld de,(ew2p)
|
||||
sbc hl,de
|
||||
jr z,wrtw2
|
||||
ld a,h
|
||||
and 3
|
||||
or l
|
||||
ret nz
|
||||
jr jone_k
|
||||
wrtw2: call flshw2
|
||||
jone_k: jp one_k
|
||||
|
||||
.extern flshw2 ; flush pending write to auxfcb
|
||||
flshw2:
|
||||
ld hl,(w2ptr) ; what is in buffer
|
||||
ld de,work2
|
||||
ld (w2ptr),de ; reset save pointer
|
||||
or a
|
||||
sbc hl,de ; see if anything there
|
||||
ret z ; no - stop right now
|
||||
dec hl
|
||||
add hl,hl
|
||||
inc h
|
||||
ld b,h ; convert bytes to 128 byte blocks in b
|
||||
flshlp: push bc
|
||||
push de
|
||||
ld c,setdma
|
||||
call bdos ; set dma address
|
||||
ld de,auxfcb
|
||||
ld c,write
|
||||
call usrbds ; write the data
|
||||
pop de
|
||||
ld hl,128
|
||||
add hl,de
|
||||
ex de,hl ; move dma pointer
|
||||
pop bc
|
||||
djnz flshlp ; loop till all written
|
||||
|
||||
.extern fill1a ; fill write buffer with 0x1a
|
||||
fill1a:
|
||||
ld hl,work2
|
||||
ld (w2ptr),hl
|
||||
ld de,work2 + 1
|
||||
ld bc,(cbfsiz)
|
||||
ld (hl),0x1a
|
||||
ldir
|
||||
ret
|
||||
|
||||
; setlbr - getw2c is used to read text for a script. Under certain
|
||||
; circumstances we need to adjust auxfcb to read from a .LBR, so setlbr
|
||||
; does the necessary work
|
||||
|
||||
.extern setlbr
|
||||
setlbr:
|
||||
ld de,xbuff ; point at buffer to use
|
||||
push de ; save for later
|
||||
ld c,setdma
|
||||
call bdos ; set dma address
|
||||
ld de,auxfcb
|
||||
ld c,read
|
||||
call usrbds ; read a sector
|
||||
or a
|
||||
scf
|
||||
pop de ; restore address
|
||||
ret nz ; return carry (i.e. error on eof)
|
||||
ld hl,lbrcnt
|
||||
bit 7,(hl) ; first time through?
|
||||
jr z,scnlbr ; nope - go check the stuff
|
||||
ld a,(xbuff + 14) ; get directory size
|
||||
ld (hl),a ; save it away
|
||||
jr add32 ; go move to first real entry
|
||||
scnlbr: ld a,(de) ; get first byte of this entry
|
||||
or a
|
||||
jr nz,add32 ; no file here, move to next
|
||||
push de ; save pointer to sector in xbuff
|
||||
inc de ; point at .LBR filename entry
|
||||
ld hl,fcb + 2 ; point at filename saved in fcb
|
||||
ld b,11 ; 11 characters to check
|
||||
nchk: ld a,(de)
|
||||
xor (hl) ; did we match?
|
||||
and 0x7f ; don't care about MS bit
|
||||
jr nz,add32p ; failed the match, try the next name
|
||||
inc hl
|
||||
inc de ; move pointers
|
||||
djnz nchk ; and loop
|
||||
ex de,hl ; swap .LBR directory pointer to hl
|
||||
ld e,(hl)
|
||||
inc hl
|
||||
ld d,(hl) ; get the starting index to de
|
||||
inc hl
|
||||
ld (auxfcb + 34),de ; save it in the fcb
|
||||
ld a,(hl) ; get the record count
|
||||
ld (lbrcnt),a
|
||||
xor a
|
||||
ld (auxfcb + 36),a ; zero fill top byte of auxfcb
|
||||
ld de,auxfcb
|
||||
ld c,redrnd
|
||||
call usrbds ; seek as needed
|
||||
or a ; any errors
|
||||
pop de ; clean up the stack
|
||||
ret z ; yeaaa - we got it - return w/ no carry
|
||||
scf ; else set carry for error
|
||||
ret
|
||||
add32p: pop de
|
||||
add32: ld hl,32
|
||||
add hl,de ; bump de by 32
|
||||
ex de,hl ; save result to de
|
||||
ld hl,xbuff + 0x80
|
||||
sbc hl,de ; end of sector?
|
||||
jr nz,scnlbr ; no - look for another
|
||||
ld hl,lbrcnt
|
||||
dec (hl) ; out of directory sectors?
|
||||
jr nz,setlbr ; no, back for another chunk
|
||||
dec (hl) ; turn off .LBR scans
|
||||
scf ; carry for the error
|
||||
ret
|
||||
|
||||
; scnswl - parse a list of wildcard filenames into work buffer for subsequent
|
||||
; transmission
|
||||
|
||||
.extern scnswl ; generate list of filenames for batch send
|
||||
scnswl:
|
||||
ld de,work
|
||||
ld (fnbrpt),de
|
||||
ld (fnbspt),de ; set read and write pointers
|
||||
swloop: call byp ; look at next one
|
||||
or a
|
||||
ret z ; return when all done
|
||||
call scnwld ; parse the next selection
|
||||
jr swloop ; and try again
|
||||
|
||||
.extern cpmaux ; convert generic filename in (hl) to a
|
||||
cpmaux: ; cp/m fcb in auxfcb
|
||||
push hl ; save string
|
||||
ld hl,auxfcb + 2
|
||||
ld de,auxfcb + 3
|
||||
ld bc,10
|
||||
ld (hl),' '
|
||||
ldir ; fill filename portion with spaces
|
||||
ld bc,(newusr) ; get receive drive and user
|
||||
pop de ; name string back to de
|
||||
ld hl,auxfcb + 10 ; point hl at extent part of name
|
||||
push hl
|
||||
ld hl,auxfcb
|
||||
ld (hl),c ; save user in place
|
||||
inc hl
|
||||
ld (hl),b ; and the drive
|
||||
inc hl ; point at name part
|
||||
ld a,3 ; 3 chars in extent
|
||||
ex af,af' ; in a'
|
||||
ld b,8 ; 8 chars in name
|
||||
scanlp: ld a,(de)
|
||||
inc de ; get next char
|
||||
cp ' '
|
||||
jr nz,nospc ; space gets changed to '-'
|
||||
ld a,'-'
|
||||
nospc: or a ; end of string?
|
||||
jr nz,more ; carry on going if not
|
||||
pop hl
|
||||
ret
|
||||
more: cp '.' ; swap portions on a '.'
|
||||
jr z,swap
|
||||
inc b
|
||||
dec b ; any space left?
|
||||
jr z,scanlp ; no - loop back
|
||||
cp '?'
|
||||
jr z,scanlp ; ignore '?'
|
||||
cp '*'
|
||||
jr z,scanlp ; and '*'s
|
||||
call ucsa ; convert to upper case
|
||||
ld (hl),a ; finally got us a letter - save it away
|
||||
inc hl ; move pointer
|
||||
dec b ; keep count
|
||||
jr scanlp ; and keep going
|
||||
swap: ex (sp),hl ; swap pointer on top of stack
|
||||
ld a,b ; count to a
|
||||
ex af,af' ; swap w/ a'
|
||||
ld b,a ; back to b
|
||||
jr scanlp
|
||||
|
||||
.extern auxopn
|
||||
auxopn:
|
||||
call fill1a ; prepare buffer & reset pointer
|
||||
ld hl,auxfcb + 13
|
||||
ld de,auxfcb + 14
|
||||
ld bc,20
|
||||
ld (hl),b ; nuke out rest of fcb
|
||||
ldir
|
||||
ld de,auxfcb
|
||||
ld c,open
|
||||
push de
|
||||
call usrbds ; open the file if we can
|
||||
pop de
|
||||
inc a
|
||||
jr z,fileok ; failed - create & we're done
|
||||
ld hl,genfn
|
||||
inc de
|
||||
inc de
|
||||
ld bc,11
|
||||
ldir ; copy in "canned" filename
|
||||
mvnaml: dec hl
|
||||
inc (hl) ; keep filenames changing
|
||||
ld a,(hl)
|
||||
cp '9' + 1
|
||||
jr c,auxopn ; done - try this one
|
||||
jr nz,ckltr ; greater than '9', check if it's a letter
|
||||
ld (hl),'A' ; no - put in 'A' now
|
||||
ckltr: cp 'Z' + 1 ; used all the letters?
|
||||
jr c,auxopn ; no - back and try it
|
||||
ld (hl),'0' ; reset to '0' and try next character
|
||||
jr mvnaml
|
||||
fileok: ld c,create ; file doesn't exist - create it
|
||||
call usrbds
|
||||
ld a,(ymdmb) ; ymodem name incoming?
|
||||
ld de,-1
|
||||
or a
|
||||
jr z,nosiz ; no - don't print a size
|
||||
ld hl,(xbuff + 126); get the record count
|
||||
ld de,7
|
||||
add hl,de ; adjust
|
||||
ld b,3
|
||||
stok: sra h
|
||||
rr l ; divide by 8 to get K
|
||||
djnz stok
|
||||
ex de,hl
|
||||
nosiz: ld hl,auxfcb ; print filename from aux fcb
|
||||
jp prfile
|
||||
|
||||
.extern dnak ; call diag to complain about a NAK
|
||||
dnak:
|
||||
call diag
|
||||
db 'NAK received\0'
|
||||
ret
|
||||
|
||||
.extern dnum ; ..... a bad packet number
|
||||
dnum:
|
||||
call diag
|
||||
db 'Bad packet number\0'
|
||||
ret
|
||||
|
||||
.extern dtime ; ..... a timeout
|
||||
dtime:
|
||||
call diag
|
||||
db 'Timeout error\0'
|
||||
ret
|
||||
|
||||
.extern dcheck ; ..... a checksum error
|
||||
dcheck:
|
||||
call diag
|
||||
db 'Checksum error\0'
|
||||
ret
|
||||
|
||||
.extern dcrc ; ..... a crc error
|
||||
dcrc:
|
||||
call diag
|
||||
db 'CRC error\0'
|
||||
ret
|
||||
|
||||
.extern dtries ; ..... too many retries
|
||||
dtries:
|
||||
call diag
|
||||
db 'Too many retries\0'
|
||||
ret
|
||||
|
||||
.dseg
|
||||
.extern genfn
|
||||
genfn: db '--XFER--000'
|
||||
.extern abortf
|
||||
abortf: dw 0
|
||||
.extern lbrcnt
|
||||
lbrcnt: db 0xff
|
||||
|
||||
.useg
|
||||
w2ptr: ds 2
|
||||
endw2: ds 2
|
||||
onekp: ds 1
|
||||
.extern ew2p
|
||||
ew2p: ds 2
|
||||
|
11
source/TERMCAP.I
Normal file
11
source/TERMCAP.I
Normal file
@ -0,0 +1,11 @@
|
||||
; termcap.i - bit values for telling which terminal capabilities are present
|
||||
|
||||
.var b_brite 1
|
||||
.var b_dim 2
|
||||
.var b_delln 4
|
||||
.var b_insln 8
|
||||
.var b_delch 16
|
||||
.var b_insch 32
|
||||
.var b_cleol 64
|
||||
.var b_cleos 128
|
||||
|
512
source/TERMIO.Z
Normal file
512
source/TERMIO.Z
Normal file
@ -0,0 +1,512 @@
|
||||
; termio.z - subroutines for doing the terminal i/o part of qterm
|
||||
|
||||
.incl "c:termcap"
|
||||
.incl "c:vars"
|
||||
|
||||
.macro table byte,addr
|
||||
dw addr
|
||||
db byte
|
||||
.endm
|
||||
|
||||
.extern procch
|
||||
procch: call kbdcc ; get a char if it's waiting
|
||||
or a
|
||||
jr z,lstmod ; skip if no character
|
||||
cp 'x' & 0x1f ; ctl x?
|
||||
jp z,canscr ; quit if so
|
||||
ld e,a ; save char in e
|
||||
ld a,(escval) ; get the escape value
|
||||
ld hl,pccs
|
||||
inc (hl)
|
||||
dec (hl) ; what state?
|
||||
jr z,pccs0 ; state zero - look for escape
|
||||
dec (hl) ; reset to 0
|
||||
cp e ; escape twice?
|
||||
jr z,pccop ; yes - send one to modem
|
||||
ld a,e ; get char back
|
||||
cp ',' ; was it a ','?
|
||||
call z,hangup ; hang up if so
|
||||
cp '.' ; or a '.'
|
||||
call z,break ; do a break
|
||||
jr lstmod
|
||||
|
||||
; This is here for branch length reasons
|
||||
|
||||
.extern modop
|
||||
modop: ; send a character to the modem, respecting
|
||||
; half duplex etc.
|
||||
push af
|
||||
call modopc ; send it to the modem first
|
||||
pop hl
|
||||
ld a,(wflg) ; window mode?
|
||||
or a
|
||||
ld a,h ; get character back
|
||||
jr z,nowin
|
||||
push hl
|
||||
call winsnd ; go give it to window input code
|
||||
pop af ; char back
|
||||
cp '\r'
|
||||
ret nz ; returns get special processing
|
||||
ld a,(eflg) ; echo mode?
|
||||
or a
|
||||
ret z ; return if not
|
||||
ld a,'\n' ; throw a linefeed into the system
|
||||
jr modop
|
||||
nowin: ld a,(hflg) ; half duplex?
|
||||
or a
|
||||
ret z
|
||||
ld a,h ; get character again
|
||||
cp '\r'
|
||||
jr nz,ipchar ; pass non-return chars straight in
|
||||
ld a,(eflg) ; echo mode too?
|
||||
or a
|
||||
ld a,h ; get the '\r' back
|
||||
jr z,ipchar ; no echo mode, don't expand it
|
||||
call ipchar ; go send return to receive code
|
||||
ld a,'\n'
|
||||
jr ipmchr ; throw a newline into system as well
|
||||
|
||||
pccs0: cp e ; did we see an escape?
|
||||
jr z,setesc ; yes, set the flag
|
||||
ld a,e
|
||||
pccop: call modop ; send char to modem
|
||||
db 0x3e ; ld a,xx opcode
|
||||
setesc: inc (hl)
|
||||
|
||||
.extern lstmod
|
||||
lstmod:
|
||||
call wrtscn ; keep the printer going and check if a
|
||||
; character is waiting at the modem port.
|
||||
ret c ; return if nothing arrived
|
||||
|
||||
ld hl,ecval ; echo check needed?
|
||||
dec (hl)
|
||||
inc (hl)
|
||||
jr z,noec ; jump if not
|
||||
cp (hl) ; did we match?
|
||||
jr nz,noec ; no - leave value in place
|
||||
ld (hl),1 ; reset to say we got it
|
||||
noec: ld hl,bmask
|
||||
and (hl) ; mask if 7 bit mode
|
||||
scf
|
||||
ret z ; return on nulls as well
|
||||
ld hl,cscqfl
|
||||
inc (hl)
|
||||
dec (hl) ; ^S ^Q spotting enabled?
|
||||
jr z,nocscq
|
||||
bit 0,(hl)
|
||||
jr nz,nocs ; waiting for a ^Q?
|
||||
cp 's' & 0x1f ; ^S ?
|
||||
jr nz,nocscq ; nope, check status now
|
||||
set 0,(hl) ; flag that a ^S arrived
|
||||
scf
|
||||
ret
|
||||
nocs: cp 'q' & 0x1f ; was it a ^Q
|
||||
jr z,wascq
|
||||
cp 's' & 0x1f ; also let a second ^S toggle
|
||||
jr nz,nocscq ; not yet - pass this character
|
||||
wascq: res 0,(hl) ; clear the flag
|
||||
scf
|
||||
ret
|
||||
nocscq: ld hl,eflg
|
||||
inc (hl)
|
||||
dec (hl) ; echo mode?
|
||||
zipch: jr z,ipchar ; no, hand straight to input code
|
||||
cp '\r' ; return?
|
||||
jr nz,ipmchr ; no, echo and hand to input code
|
||||
call ipmchr ; otherwise process,
|
||||
ld a,'\n' ; and send a newline into the system as well
|
||||
|
||||
ipmchr: push af
|
||||
call modopc ; send character to modem to echo it
|
||||
pop af
|
||||
|
||||
.extern ipchar ; needed for sendcs in chat
|
||||
ipchar: ld c,a ; save char in c
|
||||
ld a,(jflg)
|
||||
or a ; junking control characters?
|
||||
ld a,c
|
||||
call nz,limitb ; if so it gets tested
|
||||
ret c ; and thrown if bad
|
||||
push af ; save the character
|
||||
call opchar
|
||||
pop af
|
||||
call oplst ; output to printer
|
||||
or a ; clear the carry
|
||||
ld hl,cflg
|
||||
bit 0,(hl) ; catch mode enabled
|
||||
ret z ; no - return
|
||||
ld hl,(cptr)
|
||||
ld (hl),a ; save char away
|
||||
inc hl
|
||||
ld (cptr),hl ; update pointer
|
||||
ld de,(endcbf)
|
||||
or a
|
||||
sbc hl,de ; buffer full?
|
||||
scf
|
||||
ccf ; clear carry w/o affecting zero
|
||||
ret nz ; no - keep going
|
||||
push af
|
||||
call flushc ; go flush data in catch buffer
|
||||
call ctlq
|
||||
pop af
|
||||
ret
|
||||
|
||||
.extern savrng
|
||||
savrng: ; get a char and save in ring buffer
|
||||
call modist ; char available?
|
||||
ret z ; no.
|
||||
call modin ; get it
|
||||
ld de,(ringpw) ; pick up indices
|
||||
ld hl,(ringpr)
|
||||
inc de ; move write index
|
||||
res 2,d
|
||||
or a
|
||||
sbc hl,de ; buffer full?
|
||||
ret z ; return if so
|
||||
ld (ringpw),de ; save revised index
|
||||
ld hl,ring
|
||||
add hl,de
|
||||
ld (hl),a
|
||||
ret
|
||||
|
||||
wrtscn: call wrtlst ; keep printer output rolling
|
||||
call savrng ; get any incoming characters
|
||||
ld de,(ringpr)
|
||||
ld hl,(ringpw)
|
||||
xor a
|
||||
sbc hl,de ; anything in the ring?
|
||||
scf
|
||||
ret z ; nope
|
||||
inc de
|
||||
res 2,d
|
||||
ld (ringpr),de ; save new index
|
||||
ld hl,ring
|
||||
add hl,de ; index into buffer
|
||||
ld a,(hl) ; get the char
|
||||
ret ; and return it
|
||||
|
||||
.extern oplst ; put a character in the list ring buffer
|
||||
oplst:
|
||||
ld hl,oflg ; are we saving?
|
||||
bit 0,(hl)
|
||||
ret z ; return if not
|
||||
push bc ; save bc
|
||||
ld hl,(lstpr)
|
||||
ld de,(lstpw) ; get the list ring buffer indices
|
||||
inc de ; move the write pointer
|
||||
res 2,d ; wrap if it hits 1K
|
||||
or a
|
||||
sbc hl,de ; check for buffer full
|
||||
jr nz,notful
|
||||
push af ; save the character
|
||||
call ctls ; send an xoff and wait for things to cool
|
||||
mtloop: call wrtlst ; write a character if we can
|
||||
jr nc,mtloop ; keep writing if we're not done
|
||||
call ctlq ; OK - you can wake up again
|
||||
pop af ; restore char again
|
||||
notful: ld hl,(lstpw)
|
||||
inc hl
|
||||
res 2,h
|
||||
ld (lstpw),hl ; save the revised write pointer
|
||||
ld de,lstbuf ; address the list buffer
|
||||
add hl,de
|
||||
ld (hl),a ; and save the character
|
||||
pop bc ; get bc back.
|
||||
ret
|
||||
|
||||
wrtlst: ld de,(lstpr) ; see if we can send a character to the lst
|
||||
ld hl,(lstpw) ; get the ring buffer indices
|
||||
or a
|
||||
sbc hl,de ; anything in the buffer
|
||||
scf ; set carry to say we're done
|
||||
ret z ; nope - nothing to do
|
||||
push de
|
||||
ld a,0x2d
|
||||
call cbios ; call to list status
|
||||
pop de ; get read pointer back
|
||||
or a
|
||||
ret z ; can't write - return now
|
||||
ld hl,lstbuf
|
||||
add hl,de ; index into buffer
|
||||
inc de
|
||||
res 2,d ; wrap if over 1K
|
||||
ld (lstpr),de ; save new index
|
||||
ld c,(hl)
|
||||
|
||||
.extern lstout
|
||||
lstout: ld a,0x0f
|
||||
call cbios
|
||||
or a ; clear the carry
|
||||
ret
|
||||
|
||||
.extern ctlq
|
||||
ctlq:
|
||||
ld a,(lxoff) ; get local xon / xoff status
|
||||
or a
|
||||
ret z ; send nothing if xoff sent from keyboard
|
||||
ld a,(cqchr)
|
||||
|
||||
.extern modopc
|
||||
modopc: push af ; save character on stack
|
||||
modopl: call modost ; check if we can send
|
||||
jr z,modopl ; can't send - loop back
|
||||
pop af ; char back to a
|
||||
jp modout ; and away it goes
|
||||
|
||||
.extern limitb
|
||||
limitb: ; like limitc, but includes backspace
|
||||
cp '\b'
|
||||
ret z
|
||||
|
||||
.extern limitc
|
||||
limitc:
|
||||
cp 0x7f ; del or greater
|
||||
ccf
|
||||
ret c ; are invalid
|
||||
|
||||
.extern iswa
|
||||
iswa:
|
||||
cp ' ' ; space to '~'
|
||||
ret nc ; are valid
|
||||
cp '\r'
|
||||
ret z ; return is valid
|
||||
cp '\n'
|
||||
ret z ; newline also
|
||||
cp '\t'
|
||||
ret z ; and tab
|
||||
scf ; rest are bad
|
||||
ret
|
||||
|
||||
.var #where 0
|
||||
.var #bot 1
|
||||
.var #top 2
|
||||
.var #col 6
|
||||
.var #row 7
|
||||
.var #lff 8
|
||||
|
||||
nocndo: call ilprt ; and finish the message
|
||||
db '\r\nW ignored - insufficient terminal capabilities\r\n\0'
|
||||
ret
|
||||
|
||||
wend: ld hl,23 << 8
|
||||
jp moveto
|
||||
|
||||
.extern witog
|
||||
witog: ld a,(tcbits) ; check what terminal abilities we have
|
||||
cpl
|
||||
and b_delln | b_insln
|
||||
ld (wtflag),a ; save window type value
|
||||
jr z,cando ; got insert and delete - away we go
|
||||
ld a,(tcbits)
|
||||
and b_cleol ; alternatively check for clear to end-of-line
|
||||
jr z,nocndo ; missing it as well - can't do this
|
||||
|
||||
cando: ld hl,wflg
|
||||
call togflg ; toggle the flag first of all
|
||||
jr z,wend ; disabled - so return & do nothing
|
||||
dec (hl) ; temporarily turn mode back off so prompt
|
||||
push hl ; works right
|
||||
call prompt
|
||||
db 'Window size (b / s)? \0'
|
||||
pop hl
|
||||
inc (hl) ; turn flag back on
|
||||
ld hl,ipbuf
|
||||
call byp
|
||||
or 0x20
|
||||
xor 's' ; did they say 's'?
|
||||
|
||||
; we could probably optimise this even more, only two numbers actually change
|
||||
|
||||
ld hl,sdat ; get small window data
|
||||
jr z,gotdat ; jump if so
|
||||
ld hl,bdat ; otherwise large window data
|
||||
gotdat: ld de,wrdat
|
||||
ld bc,6
|
||||
ldir ; go install it
|
||||
ld h,d
|
||||
ld l,e
|
||||
inc de
|
||||
ld c,5
|
||||
ld (hl),b ; clear the rest of the information
|
||||
ldir
|
||||
ld a,(wtflag)
|
||||
or a ; what sort of windowing
|
||||
jr nz,setrol ; rolling w/ clear to eol
|
||||
ld hl,(rbot) ; normal - get bottom row
|
||||
ld a,(sbot) ; and the other
|
||||
jr wsetsc ; and install them
|
||||
setrol: ld hl,(rtop) ; get top row
|
||||
ld a,(stop) ; and the other
|
||||
wsetsc: ld (srow),a ; save send window current row
|
||||
ld a,l
|
||||
ld (rrow),a ; and receive window
|
||||
ld (where),a ; and set where so we'll do a moveto
|
||||
call clear
|
||||
ld hl,(rtop - 1) ; get top of receive window
|
||||
dec h ; - 1 to move up a line
|
||||
ld l,0 ; and the first positon
|
||||
call moveto ; go there
|
||||
call dim ; dim mode
|
||||
ld bc,[80 << 8] + '-'
|
||||
dashes: push bc
|
||||
call scrout ; spit out 80 dashes
|
||||
pop bc
|
||||
djnz dashes
|
||||
jp bright ; set bright mode and we're done
|
||||
|
||||
istab: ld c,' '
|
||||
call opwc
|
||||
ld a,(iy + #col)
|
||||
and 7
|
||||
jr nz,istab
|
||||
ret
|
||||
|
||||
trybs: cp '\b'
|
||||
jr nz,trytab
|
||||
ld a,(iy + #col)
|
||||
or a
|
||||
ret z
|
||||
dec (iy + #col)
|
||||
call opbs
|
||||
ld c,' '
|
||||
call scrout
|
||||
opbs: ld c,'\b'
|
||||
jp scrout
|
||||
|
||||
trytab: cp '\t'
|
||||
jr z,istab
|
||||
|
||||
nobs: cp '~' + 1
|
||||
ret nc
|
||||
cp ' '
|
||||
ret c
|
||||
opwc: push hl
|
||||
call scrout
|
||||
pop hl
|
||||
ld (iy + #lff),0
|
||||
inc (iy + #col)
|
||||
ld a,(iy + #col)
|
||||
xor 80
|
||||
jr z,scrl
|
||||
ret
|
||||
|
||||
.extern winrec
|
||||
winrec: ld iy,wrdat
|
||||
jr winpc
|
||||
|
||||
winsnd: ld iy,wsdat
|
||||
ld c,a
|
||||
|
||||
winpc: ld hl,where
|
||||
ld a,(iy + #where)
|
||||
cp (hl)
|
||||
jr z,posok
|
||||
ld (hl),a
|
||||
push hl
|
||||
push bc
|
||||
ld l,(iy + #col)
|
||||
ld h,(iy + #row)
|
||||
call moveto
|
||||
pop bc
|
||||
pop hl
|
||||
posok: ld a,c
|
||||
cp '\n'
|
||||
jr z,scrl
|
||||
cp '\r'
|
||||
jr nz,trybs
|
||||
scrl: xor a
|
||||
cp (iy + #lff)
|
||||
ret nz
|
||||
ld (iy + #col),a
|
||||
ld (hl),h
|
||||
ld (iy + #lff),h
|
||||
ld a,(wtflag)
|
||||
or a
|
||||
jr nz,roll
|
||||
ld a,(iy + #top)
|
||||
ld h,(iy + #bot)
|
||||
ld l,22
|
||||
|
||||
; rollit - scroll a region on the screen - this is made external so the VT100
|
||||
; code can get at it
|
||||
|
||||
.extern rollit
|
||||
rollit: or a
|
||||
push hl
|
||||
jr nz,dell
|
||||
ld hl,23 << 8
|
||||
call moveto
|
||||
ld c,'\n'
|
||||
call scrout
|
||||
jr dontop
|
||||
dell: ld l,0
|
||||
ld h,a
|
||||
call moveto
|
||||
call dellin
|
||||
dontop: pop hl
|
||||
ld a,h
|
||||
cp l
|
||||
ret z
|
||||
ld l,0
|
||||
call moveto
|
||||
jp inslin
|
||||
|
||||
roll: ld a,(iy + #row)
|
||||
call incrow
|
||||
ld (iy + #row),a
|
||||
call incrow
|
||||
ld h,a
|
||||
ld l,0
|
||||
call moveto
|
||||
jp cleol
|
||||
|
||||
incrow: cp (iy + #bot)
|
||||
jr z,reload
|
||||
inc a
|
||||
ret
|
||||
reload: ld a,(iy + #top)
|
||||
ret
|
||||
|
||||
.dseg
|
||||
.extern pccs
|
||||
pccs: db 0
|
||||
ringpr: dw 0
|
||||
ringpw: dw 0
|
||||
lstpr: dw 0
|
||||
lstpw: dw 0
|
||||
|
||||
.useg
|
||||
ring: ds 1024
|
||||
lstbuf: ds 1024
|
||||
|
||||
wrdat:
|
||||
rwhere: ds 1
|
||||
rbot: ds 1
|
||||
rtop: ds 1
|
||||
|
||||
wsdat:
|
||||
swhere: ds 1
|
||||
sbot: ds 1
|
||||
stop: ds 1
|
||||
|
||||
rcol: ds 1
|
||||
rrow: ds 1
|
||||
rlff: ds 1
|
||||
|
||||
scol: ds 1
|
||||
srow: ds 1
|
||||
slff: ds 1
|
||||
|
||||
.extern where
|
||||
where: ds 1
|
||||
wtflag: ds 1
|
||||
|
||||
.dseg
|
||||
|
||||
sdat: db 0,22,12
|
||||
db 1,10,0
|
||||
|
||||
bdat: db 0,22,5
|
||||
db 1,3,0
|
||||
|
31
source/VARS.I
Normal file
31
source/VARS.I
Normal file
@ -0,0 +1,31 @@
|
||||
; vars.i - global variables for qterm
|
||||
|
||||
.var buffin 10 ; console buffered input
|
||||
.var versn 12 ; get operating system version
|
||||
.var rescpm 13 ; reset bdos to avoid R/O disk problems
|
||||
.var seldrv 14 ; select drive
|
||||
.var open 15 ; open a file
|
||||
.var close 16 ; close a file
|
||||
.var srchf 17 ; find the first occurance
|
||||
.var srchn 18 ; find the next occurance
|
||||
.var erase 19 ; erase file
|
||||
.var read 20 ; read sequential
|
||||
.var write 21 ; write sequential
|
||||
.var create 22 ; create a file
|
||||
.var rename 23 ; rename file
|
||||
.var getdrv 25 ; get current drive
|
||||
.var setdma 26 ; set the dma address
|
||||
.var dpbadr 31 ; get disk parameter block address
|
||||
.var gsuser 32 ; get or set user code
|
||||
.var redrnd 33 ; read random
|
||||
.var cfsize 35 ; compute the filesize
|
||||
.var logdrv 37 ; reset individual drive
|
||||
|
||||
.var fcb 0x5b ; fcb address
|
||||
.var ipbuf 0x80 ; input buffer
|
||||
.var buffer 0x80 ; buffer used for wildcard scans
|
||||
.var cmdlin 0x80 ; where the command tail lives
|
||||
|
||||
.var op_bit 1 ; output modem chars flag
|
||||
.var mat_bit 2 ; print match messages flag
|
||||
.var lf_bit 4 ; print looking for messages flag
|
49
source/VERSION.I
Normal file
49
source/VERSION.I
Normal file
@ -0,0 +1,49 @@
|
||||
; version.i - keep the version in one place
|
||||
|
||||
.var no 0
|
||||
.var yes ! no
|
||||
|
||||
.var major 4
|
||||
.var minor 3
|
||||
.var rev 'e'
|
||||
.var subver 0
|
||||
|
||||
;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
.var dg yes ; set this no for release versions
|
||||
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.macro year
|
||||
db '1991'
|
||||
.endm
|
||||
|
||||
.macro version
|
||||
.if major >= 100
|
||||
db major / 100 + '0'
|
||||
.endif
|
||||
.if major >= 10
|
||||
db [major / 10] % 10 + '0'
|
||||
.endif
|
||||
db major % 10 + '0'
|
||||
db '.'
|
||||
.if minor >= 100
|
||||
db minor / 100 + '0'
|
||||
.endif
|
||||
.if minor >= 10
|
||||
db [minor / 10] % 10 + '0'
|
||||
.endif
|
||||
db minor % 10 + '0', rev
|
||||
.if subver
|
||||
db ' ('
|
||||
.if subver >= 1000
|
||||
db subver / 1000 + '0'
|
||||
.endif
|
||||
.if subver >= 100
|
||||
db [subver / 100] % 10 + '0'
|
||||
.endif
|
||||
.if subver >= 10
|
||||
db [subver / 10] % 10 + '0'
|
||||
.endif
|
||||
db subver % 10 + '0', ')'
|
||||
.endif
|
||||
.endm
|
||||
|
508
source/VT100.Z
Normal file
508
source/VT100.Z
Normal file
@ -0,0 +1,508 @@
|
||||
; vt100.z - handle vt100 emulation in QTERM
|
||||
|
||||
.incl "c:vars"
|
||||
|
||||
.var decom 0x20
|
||||
.var ascrl 0x40
|
||||
|
||||
.extern initv
|
||||
initv:
|
||||
ld hl,inits
|
||||
ld de,inits + 1
|
||||
ld bc,{inite - inits}
|
||||
ld (hl),b
|
||||
ldir
|
||||
jp23: ld hl,23 << 8
|
||||
jr dochk
|
||||
chkxy: ld hl,(x)
|
||||
dochk: ld a,l
|
||||
ld e,79
|
||||
call chk1
|
||||
ld l,a
|
||||
ld a,h
|
||||
ld e,23
|
||||
call chk1
|
||||
ld h,a
|
||||
ld a,(flags)
|
||||
and decom
|
||||
jr z,savmov
|
||||
ld de,(hi)
|
||||
ld a,h
|
||||
cp e
|
||||
jr nc,aok1
|
||||
ld h,e
|
||||
aok1: ld a,d
|
||||
cp h
|
||||
jr nc,savmov
|
||||
ld h,d
|
||||
savmov: ld (x),hl
|
||||
lodmov: ld hl,(x)
|
||||
jp moveto
|
||||
|
||||
.extern opchar
|
||||
opchar: ld c,a ; save char in c
|
||||
ld a,(mode)
|
||||
and op_bit
|
||||
ret nz ; exit if not doing output
|
||||
ld a,(wflg) ; split window mode?
|
||||
or a
|
||||
jp nz,winrec ; yes - hand to receive portion
|
||||
ld a,(vflg) ; vt100 emulation on?
|
||||
or a
|
||||
jp z,scrout ; no- send to screen
|
||||
; otherwise give char to vt100 processor
|
||||
|
||||
.extern vt100
|
||||
vt100:
|
||||
ld a,c
|
||||
cp '\b'
|
||||
ld hl,x
|
||||
jr nz,nobs
|
||||
ld a,(hl)
|
||||
dec a
|
||||
ret m
|
||||
savho: ld (hl),a
|
||||
jpsco: jp scrout
|
||||
nobs: xor '\r'
|
||||
jr z,savho
|
||||
cp '\t' ^ '\r'
|
||||
jr nz,notab
|
||||
ld a,(hl)
|
||||
and ~7
|
||||
add a,8
|
||||
cp 80
|
||||
ret z
|
||||
ld (hl),a
|
||||
jr lodmov
|
||||
notab: cp '\n' ^ '\r'
|
||||
jr nz,nonl
|
||||
inc hl
|
||||
ld a,(lo)
|
||||
or a
|
||||
jr nz,islo
|
||||
ld a,23
|
||||
islo: cp (hl)
|
||||
jp z,scrlvt
|
||||
ld a,(hl)
|
||||
cp 23
|
||||
jr z,lodmov
|
||||
inc (hl)
|
||||
lodmv1: jr lodmov
|
||||
nonl: cp '\7' ^ '\r'
|
||||
jr z,jpsco
|
||||
ld hl,nk
|
||||
ld a,(hl)
|
||||
or a
|
||||
jr z,nokil
|
||||
dec (hl)
|
||||
ret
|
||||
nokil: ld a,(state)
|
||||
or a
|
||||
jr nz,stt1
|
||||
ld a,c
|
||||
cp '\e'
|
||||
jr nz,noesc
|
||||
xor a
|
||||
ld (fbits),a
|
||||
ld (setv),a
|
||||
inc a
|
||||
savstt: ld (state),a
|
||||
ret
|
||||
noesc: cp ' '
|
||||
ret c ; all other control chars are tossed
|
||||
cp 0x7f ; delete?
|
||||
ret z ; yes - we throw it away
|
||||
jr c,okasc ; less than delete => not a grafix char
|
||||
ld c,'+' ; assume all are '+'s
|
||||
ld hl,vtxtbl ; except special ones in the table
|
||||
.dseg
|
||||
vtxtbl: db 205,'='
|
||||
db 186,'|'
|
||||
db 196,'-'
|
||||
db 179,'|'
|
||||
db 0
|
||||
.cseg
|
||||
xtblp: ld e,(hl) ; get char to match
|
||||
dec e
|
||||
inc e ; is it zero?
|
||||
jr z,okasc ; yes, all done so exit
|
||||
inc hl
|
||||
ld d,(hl) ; get ascii char to use
|
||||
inc hl
|
||||
cp e ; did we hit it?
|
||||
jr nz,xtblp ; nope, back to try again
|
||||
ld c,d ; else save character from d
|
||||
okasc: ld hl,x
|
||||
ld a,(hl)
|
||||
cp 79
|
||||
jr nc,xge79
|
||||
inc (hl)
|
||||
jr jpsco
|
||||
xge79: inc hl
|
||||
ld a,(hl)
|
||||
cp 23
|
||||
jr nz,yne23
|
||||
ld a,(lo)
|
||||
or a
|
||||
jr z,cka
|
||||
cp 23
|
||||
ret nz
|
||||
cka: ld a,(flags)
|
||||
and ascrl
|
||||
ret z
|
||||
push bc
|
||||
call scrlvt
|
||||
ld hl,[22 << 8] + 79
|
||||
call moveto
|
||||
pop bc
|
||||
call scrout
|
||||
jp jp23
|
||||
yne23: call scrout
|
||||
ld a,(flags)
|
||||
and ascrl
|
||||
jr z,lodmv1
|
||||
ld hl,y
|
||||
ld a,(lo)
|
||||
or a
|
||||
jr z,nolo
|
||||
cp (hl)
|
||||
jr nz,nolo
|
||||
push hl
|
||||
call scrlvt
|
||||
pop hl
|
||||
dec (hl)
|
||||
nolo: inc (hl)
|
||||
dec hl
|
||||
ld (hl),0
|
||||
jr lodmv2
|
||||
stt1: dec a
|
||||
jr nz,stt2
|
||||
ld a,c
|
||||
cp '['
|
||||
ld a,2
|
||||
jr z,savstt
|
||||
xor a
|
||||
ld (state),a
|
||||
ld a,c
|
||||
cp '#'
|
||||
jr z,k1
|
||||
cp '('
|
||||
jr z,k1
|
||||
cp ')'
|
||||
jr nz,tryM
|
||||
k1: ld hl,nk
|
||||
inc (hl)
|
||||
ret
|
||||
tryM: ld hl,y
|
||||
cp 'M'
|
||||
jr nz,tryE
|
||||
ld a,(hi)
|
||||
cp (hl)
|
||||
jr nz,nohi
|
||||
call revsvt
|
||||
jr lodmv2
|
||||
nohi: dec (hl)
|
||||
jp p,lodmov
|
||||
inc (hl)
|
||||
jr lodmv2
|
||||
tryE: xor 'E'
|
||||
jr nz,tryD
|
||||
dec hl
|
||||
ld (hl),a
|
||||
inc hl
|
||||
jr doD
|
||||
tryD: dec a
|
||||
jr nz,try7
|
||||
doD: ld a,(lo)
|
||||
or a
|
||||
jr z,look
|
||||
ld a,23
|
||||
look: cp (hl)
|
||||
jr nz,nolo1
|
||||
call scrlvt
|
||||
jr lodmv2
|
||||
nolo1: ld a,(hl)
|
||||
cp 23
|
||||
jr nc,lodmv2
|
||||
inc (hl)
|
||||
lodmv2: jp lodmov
|
||||
try7: cp ['7' ^ 'E'] - 1
|
||||
jr nz,try8
|
||||
ld hl,(x)
|
||||
ld (sx),hl
|
||||
ld a,(mm)
|
||||
ld (sm),a
|
||||
ret
|
||||
try8: cp ['8' ^ 'E'] - 1
|
||||
ret nz
|
||||
ld hl,(sx)
|
||||
ld (x),hl
|
||||
ld a,(sm)
|
||||
call setdb
|
||||
jp chkxy
|
||||
stt2: dec a
|
||||
jr nz,stt3
|
||||
ld hl,p1
|
||||
ld (pp),hl
|
||||
ld hl,0
|
||||
ld (p1),hl
|
||||
ld a,3
|
||||
ld (state),a
|
||||
ld a,c
|
||||
cp '?'
|
||||
jr nz,stt3
|
||||
ld (setv),a
|
||||
ret
|
||||
cs2: call clear
|
||||
lodmv3: jr lodmv2
|
||||
vclrs: ld a,(de)
|
||||
or a
|
||||
jp z,cleos
|
||||
dec a
|
||||
jr nz,cs2
|
||||
push hl
|
||||
ld hl,0
|
||||
call moveto
|
||||
pop bc
|
||||
push bc
|
||||
ld a,b
|
||||
or a
|
||||
jr z,nolin
|
||||
cslp: push bc
|
||||
call cleol
|
||||
ld c,'\n'
|
||||
call scrout
|
||||
pop bc
|
||||
djnz cslp
|
||||
nolin: ld b,c
|
||||
inc b
|
||||
ld c,' '
|
||||
cllp: push bc
|
||||
call scrout
|
||||
pop bc
|
||||
djnz cllp
|
||||
ld c,'\b'
|
||||
jp scrout
|
||||
cl2: ld c,'\r'
|
||||
call scrout
|
||||
call cleol
|
||||
jr lodmv3
|
||||
vclrl: ld a,(de)
|
||||
or a
|
||||
jp z,cleol
|
||||
dec a
|
||||
jr nz,cl2
|
||||
ld c,'\r'
|
||||
push hl
|
||||
call scrout
|
||||
pop bc
|
||||
jr nolin
|
||||
stt3: ld a,c
|
||||
cp ';'
|
||||
jr nz,nosc
|
||||
ld a,(setv)
|
||||
or a
|
||||
jr z,nosv
|
||||
dofbit: ld hl,p1
|
||||
ld a,(hl)
|
||||
or a
|
||||
ret z
|
||||
ld b,a
|
||||
xor a
|
||||
ld (hl),a
|
||||
scf
|
||||
fblp: adc a,a
|
||||
djnz fblp
|
||||
dec hl
|
||||
or (hl)
|
||||
ld (hl),a
|
||||
ret
|
||||
nosv: ld hl,(pp)
|
||||
ld de,p1
|
||||
sbc hl,de
|
||||
jr nz,setp3
|
||||
add hl,de
|
||||
inc hl
|
||||
savpp: ld (pp),hl
|
||||
ret
|
||||
setp3: ld hl,p3
|
||||
ld (hl),0
|
||||
jr savpp
|
||||
nosc: sub '0'
|
||||
cp 10
|
||||
jr nc,notdig
|
||||
ld hl,(pp)
|
||||
ld e,a
|
||||
ld a,(hl)
|
||||
add a,a
|
||||
add a,a
|
||||
add a,(hl)
|
||||
add a,a
|
||||
add a,e
|
||||
ld (hl),a
|
||||
ret
|
||||
notdig: ld hl,state
|
||||
ld (hl),0
|
||||
ld hl,swtab - 1
|
||||
.dseg
|
||||
.macro table byte,word
|
||||
dw word
|
||||
db byte - '0'
|
||||
.endm
|
||||
swtab:
|
||||
table 'A',vup
|
||||
table 'B',vdown
|
||||
table 'C',vright
|
||||
table 'D',vleft
|
||||
table 'H',vmove
|
||||
table 'f',vmove
|
||||
table 'J',vclrs
|
||||
table 'K',vclrl
|
||||
table 'r',vmarg
|
||||
table 'm',vmode
|
||||
table 'h',vsm
|
||||
table 'l',vrm
|
||||
endtab:
|
||||
.cseg
|
||||
ld b,{endtab - swtab} / 3
|
||||
switch: inc hl
|
||||
ld e,(hl)
|
||||
inc hl
|
||||
ld d,(hl)
|
||||
inc hl
|
||||
cp (hl)
|
||||
jr z,hitit
|
||||
djnz switch
|
||||
ret
|
||||
hitit: push de
|
||||
ld hl,(x)
|
||||
ld de,p1
|
||||
ret
|
||||
vup: call defp1
|
||||
neg
|
||||
jr addy
|
||||
vdown: call defp1
|
||||
addy: add a,h
|
||||
ld h,a
|
||||
dochk1: jp dochk
|
||||
vleft: call defp1
|
||||
neg
|
||||
jr addx
|
||||
vright: call defp1
|
||||
addx: add a,l
|
||||
ld l,a
|
||||
jr dochk1
|
||||
vmove: call defp1
|
||||
ld h,a
|
||||
ld a,(flags)
|
||||
and decom
|
||||
jr z,hok
|
||||
ld a,(hi)
|
||||
add a,h
|
||||
ld h,a
|
||||
hok: inc de
|
||||
call defp1
|
||||
ld l,a
|
||||
dec h
|
||||
dec l
|
||||
jr dochk1
|
||||
vmarg: call defp1
|
||||
ld c,a
|
||||
inc de
|
||||
ld a,(de)
|
||||
or a
|
||||
jr nz,look1
|
||||
ld a,24
|
||||
look1: ld b,a
|
||||
ld hl,[24 << 8] + 1
|
||||
sbc hl,bc
|
||||
jr nz,chkbc
|
||||
ld b,c
|
||||
jr setbc
|
||||
chkbc: ld a,c
|
||||
cp b
|
||||
ret nc
|
||||
setbc: dec b
|
||||
dec c
|
||||
ld (hi),bc
|
||||
ld hl,0
|
||||
jr dochk1
|
||||
vmode: ld hl,(pp)
|
||||
ld a,(hl)
|
||||
setdb: ld (mm),a
|
||||
or a
|
||||
jp nz,dim
|
||||
jp bright
|
||||
vsm: call dofbit
|
||||
ld a,(fbits)
|
||||
ld hl,flags
|
||||
or (hl)
|
||||
ld (hl),a
|
||||
ret
|
||||
vrm: call dofbit
|
||||
ld a,(fbits)
|
||||
cpl
|
||||
ld hl,flags
|
||||
and (hl)
|
||||
ld (hl),a
|
||||
ret
|
||||
|
||||
chk1: or a
|
||||
jp p,chkp
|
||||
xor a
|
||||
ret
|
||||
chkp: cp e
|
||||
ret c
|
||||
ld a,e
|
||||
ret
|
||||
|
||||
defp1: ld a,(de)
|
||||
or a
|
||||
ret nz
|
||||
inc a
|
||||
ret
|
||||
|
||||
scrlvt: ld hl,(hi)
|
||||
ld a,l
|
||||
cp h
|
||||
ld l,23
|
||||
jr nz,jproll
|
||||
ld h,l
|
||||
jproll: jp rollit
|
||||
|
||||
revsvt: ld a,(lo)
|
||||
or a
|
||||
jr z,norevd
|
||||
cp 23
|
||||
jr z,norevd
|
||||
ld h,a
|
||||
ld l,0
|
||||
call moveto
|
||||
call dellin
|
||||
norevd: ld hl,(hi - 1)
|
||||
ld l,0
|
||||
call moveto
|
||||
jp inslin
|
||||
|
||||
.useg
|
||||
inits:
|
||||
state: ds 1
|
||||
hi: ds 1
|
||||
lo: ds 1
|
||||
flags: ds 1
|
||||
sx: ds 1
|
||||
sy: ds 1
|
||||
mm: ds 1
|
||||
sm: ds 1
|
||||
nk: ds 1
|
||||
inite:
|
||||
x: ds 1
|
||||
y: ds 1
|
||||
|
||||
setv: ds 1
|
||||
fbits: ds 1
|
||||
p1: ds 1
|
||||
p2: ds 1
|
||||
p3: ds 1
|
||||
pp: ds 2
|
||||
|
34
source/XMODEM.I
Normal file
34
source/XMODEM.I
Normal file
@ -0,0 +1,34 @@
|
||||
; xmodem.i - header file for xmodem file transfer code
|
||||
|
||||
.var FALSE 0
|
||||
.var TRUE 1
|
||||
|
||||
; ASCII Constants
|
||||
|
||||
.var SOH 001
|
||||
.var STX 002
|
||||
.var ETX 003
|
||||
.var EOT 004
|
||||
.var ENQ 005
|
||||
.var ACK 006
|
||||
.var LF '\n'
|
||||
.var CR '\r'
|
||||
.var NAK 025
|
||||
.var SYN 026
|
||||
.var CAN 030
|
||||
.var ESC '\e'
|
||||
|
||||
; XMODEM Constants
|
||||
|
||||
.var TIMEOUT -1
|
||||
.var ERRMAX 20
|
||||
.var NAKMAX 2
|
||||
.var RETRMX 8
|
||||
.var CRCSW 3
|
||||
.var KSWMAX 5
|
||||
.var BBUFSIZ 1024
|
||||
.var NAMSIZ 11
|
||||
.var CTRLZ 032
|
||||
.var CRCCHR 'C'
|
||||
.var BADNAM 'u'
|
||||
|
178
source/XUTIL.Z
Normal file
178
source/XUTIL.Z
Normal file
@ -0,0 +1,178 @@
|
||||
; xutil.z - xmodem utilities
|
||||
|
||||
.incl "c:xmodem"
|
||||
|
||||
.extern initx ; set up an xmodem file transfer
|
||||
initx:
|
||||
ld hl,xabort
|
||||
ld (abortf),hl ; set the abort function
|
||||
ld hl,xmstr
|
||||
jp initsc ; just set up screen with 'Xmodem' string
|
||||
.dseg
|
||||
xmstr: db 'Xmodem\0'
|
||||
.cseg
|
||||
|
||||
.extern xmflgs ; parse flags for an xmodem send
|
||||
xmflgs:
|
||||
call clrflg
|
||||
ld a,1
|
||||
ld (crcmod),a ; but set crc flag
|
||||
xmflp: ld a,(hl)
|
||||
or 0x20
|
||||
cp 0x20
|
||||
ret z ; return on end of string or space
|
||||
inc hl
|
||||
cp 'b' ; 'b' - modem7 batch
|
||||
jr nz,noxmb
|
||||
ld (mdm7b),a ; set modem7 batch flag
|
||||
xor a
|
||||
ld (ymdmb),a ; clear ymodem batch (can't have both)
|
||||
jr xmflp
|
||||
noxmb: cp 'y' ; 'y' - ymodem batch
|
||||
jr nz,noxmy
|
||||
ld (ymdmb),a ; set ymodem batch flag
|
||||
xor a
|
||||
ld (mdm7b),a ; clear modem7 batch (can't have both)
|
||||
jr xmflp
|
||||
noxmy: cp 'k' ; 'k' - 1K packets
|
||||
jr nz,noxmk
|
||||
ld (longpk),a ; set the flag
|
||||
jr xmflp
|
||||
noxmk: cp 'q' ; 'q' - quiet value
|
||||
jr nz,noxmq
|
||||
ex de,hl
|
||||
ld hl,qcount
|
||||
inc (hl) ; bump the count
|
||||
ex de,hl
|
||||
jr xmflp
|
||||
noxmq: cp 'a' ; 'a' - alarm
|
||||
jr nz,noxma
|
||||
ld (beep),a ; set flag to beep on completion
|
||||
jr xmflp
|
||||
noxma: xor 'c' ; 'c' - checksum mode
|
||||
jr nz,xmflp
|
||||
ld (crcmod),a ; set to checksum
|
||||
jr xmflp
|
||||
|
||||
.extern updcrc ; update crc with value in a
|
||||
updcrc:
|
||||
ld c,a ; save byte in c
|
||||
call dou1
|
||||
dou1: ld hl,chksum
|
||||
ld a,c
|
||||
rrca
|
||||
rrca
|
||||
rrca
|
||||
rrca
|
||||
ld c,a
|
||||
xor a
|
||||
rld
|
||||
inc hl
|
||||
rld
|
||||
xor c
|
||||
and 0x0f
|
||||
add a,a
|
||||
push hl
|
||||
ld l,a
|
||||
ld h,0
|
||||
ld de,crctab + 1
|
||||
add hl,de
|
||||
ex de,hl
|
||||
pop hl
|
||||
ld a,(de)
|
||||
dec de
|
||||
xor (hl)
|
||||
ld (hl),a
|
||||
dec hl
|
||||
ld a,(de)
|
||||
xor (hl)
|
||||
ld (hl),a
|
||||
ret
|
||||
|
||||
.extern can3 ; send 5 CAN's to far end to force it to stop
|
||||
can3: ; used to be three, but with Zmodem systems
|
||||
ld b,5 ; sometimes more are needed
|
||||
can3lp: push bc
|
||||
ld a,CAN
|
||||
call modopc
|
||||
pop bc
|
||||
djnz can3lp
|
||||
ret
|
||||
|
||||
.extern chkcan ; called when we get a CAN - checks for a
|
||||
chkcan: ; second right behind it
|
||||
call gettc3 ; wait 3 seconds
|
||||
cp CAN
|
||||
ret nz ; no - didn't get one
|
||||
call diag
|
||||
db 'Cancelled by remote\0'
|
||||
xor a
|
||||
ret
|
||||
|
||||
.extern rnresp ; beef about failure of far end to respond
|
||||
rnresp:
|
||||
call diag
|
||||
db 'Remote not responding\0'
|
||||
ret
|
||||
|
||||
.extern cvtnib ; convert a nibble at the bottom of a to a
|
||||
cvtnib: ; character
|
||||
and 0x0f ; get just the bits we want
|
||||
add a,'0'
|
||||
cp '9' + 1 ; check if it's a digit ok
|
||||
ret c ; yes - return as is
|
||||
add a,0x27 ; else conver to a letter
|
||||
ret
|
||||
|
||||
xabort: call gettc3
|
||||
jr nc,xabort ; let the line cool down
|
||||
call can3
|
||||
jp dabort
|
||||
|
||||
.useg
|
||||
.extern olp
|
||||
olp: ds 1
|
||||
.extern attmps
|
||||
attmps: ds 1
|
||||
.extern closeo
|
||||
closeo: ds 1
|
||||
.extern fatal
|
||||
fatal: ds 1
|
||||
.extern errorf
|
||||
errorf: ds 1
|
||||
.extern batch
|
||||
batch: ds 1
|
||||
.extern secip
|
||||
secip: ds 1
|
||||
.extern eotc
|
||||
eotc: ds 1
|
||||
.extern openfl ; \
|
||||
openfl: ds 1 ; \ Bound
|
||||
.extern sectnm ; /
|
||||
sectnm: ds 2 ; /
|
||||
.extern bufsiz
|
||||
bufsiz: ds 2
|
||||
.extern chksum
|
||||
chksum: ds 2
|
||||
|
||||
.extern expsec
|
||||
expsec: ds 2
|
||||
.extern sntsec
|
||||
sntsec: ds 2
|
||||
.extern xbuff
|
||||
.extern packet
|
||||
xbuff:
|
||||
packet:
|
||||
ds 1024
|
||||
|
||||
.dseg
|
||||
crctab:
|
||||
dw 0x0000, 0x1021
|
||||
dw 0x2042, 0x3063
|
||||
dw 0x4084, 0x50a5
|
||||
dw 0x60c6, 0x70e7
|
||||
dw 0x8108, 0x9129
|
||||
dw 0xa14a, 0xb16b
|
||||
dw 0xc18c, 0xd1ad
|
||||
dw 0xe1ce, 0xf1ef
|
||||
|
Loading…
Reference in New Issue
Block a user