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