aboutsummaryrefslogtreecommitdiff
path: root/src/cpswld.asm
diff options
context:
space:
mode:
authorJeff Armstrong <jeff@approximatrix.com>2026-10-25 17:42:06 -0400
committerJeff Armstrong <jeff@approximatrix.com>2026-10-25 17:42:06 -0400
commitebb2ff2af569d5822b70ee555a32d27cf7494816 (patch)
tree7ac5e7b3fa73f7a8d996129086932ecce66374ad /src/cpswld.asm
downloadkermit-80-main.tar.gz
kermit-80-main.zip
Initial import of 4.11HEADmain
Diffstat (limited to 'src/cpswld.asm')
-rw-r--r--src/cpswld.asm222
1 files changed, 222 insertions, 0 deletions
diff --git a/src/cpswld.asm b/src/cpswld.asm
new file mode 100644
index 0000000..8be6558
--- /dev/null
+++ b/src/cpswld.asm
@@ -0,0 +1,222 @@
+; CPSWLD.ASM
+; KERMIT - (Celtic for "FREE")
+;
+; This is the CP/M-80 implementation of the Columbia University
+; KERMIT file transfer protocol.
+;
+; Version 4.0
+;
+; Copyright June 1981,1982,1983,1984
+; Columbia University
+;
+; Originally written by Bill Catchings of the Columbia University Center for
+; Computing Activities, 612 W. 115th St., New York, NY 10025.
+;
+; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,
+; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many
+; others.
+;
+; Multi-file access subroutine. Allows processing of multiple files
+; (i.e., *.ASM) from disk. This routine builds the proper name in the
+; FCB each time it is called. This command would be used in such pro-
+; grams such as modem transfer, tape save, etc. in which you want to
+; process single or multiple files.
+; Note that it will fail if more than 256 entries match the wildcard.
+;
+; revision history:
+; edit 4: June 20, 1986, by OBSchou. Added stuff at top and tail of routine
+; to support multiple FCBs. If the routine get to mfn01 (Search for next)
+; then the next file found gets its fcb added to the buffer. Once no
+; more files have been found, the mfflg3 flag is set non-zero.
+; The first thing to test on entry is whether a disk access
+; is needed. Either way, the routine should return the next file name
+; in the fcb, or return with the carry flag set if there are no more
+; files to do. Once there is a carry flag set for the return, all
+; temporary flags are reset. Get all that?
+;
+; edit 3: July 27, 1984
+; support LASM: remove exclamation points, link to CP4CMD.
+;
+; edit 2: June 7, 1984 (CJC)
+; formatting and documentation; add module version string; redo movfcb,
+; in preparation for moving DMA buffer (later...).
+;
+; edit 1: May, 1984 (CJC)
+; extracted from CPMBASE.M80 version 3.9; modifications are described
+; in the accompanying .UPD file.
+;
+wldver: db 'CPSWLD.ASM (4) 20-Jun-86$'
+
+; The FCB will be set up with the next name, ready to do normal
+; processing (OPEN, READ, etc.) when routine is called.
+;
+; Carry is set if no more names can be found
+;
+; MFFLG1 is count/switch [0 for first time thru, pos for all others]
+; MFFLG2 is counted down for each successive GETNEXT file call
+; MFFLG3 is set to the last remaining FCBs buffered once Search for next
+; file fails with files in the buffer.
+;
+; Technique used is to repeat SFIRST/SNEXT sequence N+1 times for each
+; successive call, till sequence fails. CP/M does NOT allow disk-handling
+; between SFIRST and SNEXT.
+; called by: send, seof, dir
+
+mfname: ora a ; clear carry
+ push b ;Save registers
+ push d
+ push h
+ jmp mfnam0 ; skip over the next bit (which is entered from elsewhere)
+
+;[4] Get the FCB counter and see if we have any fcbs already.
+mfnam1: lxi h,fcb0
+ shld xfcbptr ; reset the pointer if we are to return an FCB
+
+mfnam0: lda fcbcnt
+ ana a ; if none, then we may have to get some from disk
+ jz mfn00 ; see later on
+ lhld xfcbptr ; we have some, so give the next one to the user
+ lxi d,fcb ; move from (hl) to (de) for length bc
+ lxi b,12
+ call mover
+ xra a
+ sta fcbext ; clear fcb extents and such
+ sta fcbrno ; like record number
+ lhld xfcbptr ; point to next fcb
+ lxi d,fcblen
+ dad d ; yup
+ shld xfcbptr
+ lda fcbcnt
+ dcr a
+ sta fcbcnt ; decrease the number of fcbs we have
+ xra a ; clear carry
+ jmp mffix1 ; and exit as if were all done
+
+mfn00: lda mfflg3 ; no more FCBs for the user, any more on disk?
+ ana a
+ jnz mffix2 ; no, then set the carry flag to say so.
+ lxi h,fcb0 ; now reset the fcb pointers and counter
+ shld xfcbptr
+ xra a
+ sta fcbcnt
+;[4] end of this addition. See below as well.
+
+
+ mvi c,setdma ;Init DMA addr, FCB
+ lxi d,80H
+ call bdos
+ xra a ;A = 0
+ sta fcbext ;clear extension
+ lda mfflg1 ;find out if "second" call in row
+ ora a
+ jnz mfn01 ;Were here before
+ sta mfflg2
+ lxi h,fcb
+ lxi d,mfreq
+ lxi b,12
+ call mover ;.from FCB to MFREQ
+ mvi c,SFIRST ;Search first
+ lxi d,fcb
+ call bdos
+ jmp mfn02 ;and check results
+
+mfn01: dcr a
+ sta mfflg2 ;store down-counter
+ lxi h,mfreq ;SFIRST REQ name
+ lxi d,fcb
+ lxi b,12
+ call mover ;.from MFREQ to FCB
+ mvi c,sfirst ;Search first old one,we got it before
+ lxi d,fcb
+ call bdos ;no error's expected -we got that before
+mfn01a:
+ mvi c,snext ;Search next
+ call bdos
+mfn02: push psw
+ lda mfflg2 ;get "repeat file counter"
+ ora a
+ jz mfn02a ;if zero, check if SNEXT had ERROR
+ dcr a ;count down
+ sta mfflg2 ;store back
+ pop psw ;no error-check, we got it before
+ jmp mfn01a ;next SNEXT
+
+mfn02a: pop psw
+ ora a
+ jm mffi2a ;No (more) found
+ call movfcb ;move data to fcb
+ lda mfreq ;the original disk-designator
+ sta fcb ;back into fcb
+ lda mfflg1 ;get file-flag
+ inr a ;increment
+ sta mfflg1 ;and store for next go-around
+ mvi a,0 ;Setup FCB
+ sta fcbext ;clean up FCB for OPEN etc
+ sta fcbrno
+ lhld xfcbptr ;[4] like here
+ xchg
+ lxi h,fcb ;[4] from fcb space
+ lxi b,12
+ call mover
+ lhld xfcbptr ;[4] now lets update the pointers
+ lxi d,fcblen
+ dad d
+ shld xfcbptr ;[4] new pointer
+ lda fcbcnt ;[4] now the fcb counter
+ inr a
+ sta fcbcnt
+ cpi maxfcb ;[4] any more spare space?
+ jp mfnam1 ;[4] nope, so get first fcb and return
+ lxi d,fcb ; else restore the file to serach for
+ lxi h,mfreq
+ lxi b,12 ; copy the original fcb to fcb
+ call mover
+ jmp mfn01a ; and look for next match.
+
+mffix1: pop h ;restore registers
+ pop d
+ pop b
+ ret ;and return
+
+mffi2a:
+ sta mfflg3 ;[4] no more FCBs from disks to be had, but
+ lda fcbcnt ;[4]we have some in the buffer, havet we?
+ ana a
+ jnz mfnam1 ;[4] yes, so all's ok. Get an fcb and return,
+
+mffix2: xra a
+ sta mfflg3 ;[4] clear the new flag (=no more fcbs at all)
+ sta mfflg2 ;[4] may as well do the others, as we're not comming again
+ sta mfflg1 ;[4]
+ stc ;set carry
+ jmp mffix1 ;return with CARRY set
+
+; copy directory entry to FCB
+; called with A/ entry number in directory (0-3)
+; directory block in DMA buffer (buff)
+
+movfcb: add a
+ add a
+ add a
+ add a
+ add a ;* 32
+ mov c,a ; copy offset to bc
+ mvi b,0 ; (high byte is zero)
+ lxi h,buff ; get start of disk buffer
+ dad b ; calculate start of directory entry
+ lxi d,fcb
+ lxi b,12
+ call mover
+ ret
+
+; Data storage for MFNAME (multi-file access)
+mfreq: DS 12 ;Requested name
+mfflg1: DB 0 ;First time thru flag for MFNAME
+mfflg2: DB 0 ;Down counter for MFNAME
+mfflg3: DB 0 ;[4] Non zero if no more FCBs from disk,
+ ;[4] but we still have some in buffer
+;
+IF lasm
+ LINK CPSCMD
+ENDIF;lasm
+