1
0
Fork 0
qterm/source/SRUTIL.Z

468 lines
11 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; 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