;****************************************************** ;* * ;* MFT - Multiple File Transfer * ;* (for single drive systems) * ;* * ;* Based on an article in Dr. Dobbs Journal of * ;* Computer Calisthenics & Orthodontia #49, * ;* Box E, Menlo Park, Ca. 94025 * ;* * ;* Vers 5.0 - 2/10/83 by William King (Time-11:32pm) * ;* - Modified the main title (pretty). * ;* - Converted all code to Z-80 so it * ;* could be assembled with "EXASM.COM". * ;* - Optimised code for Z-80 (ie use * ;* LDIR,JR and DJNZ). * ;* - Added check on CP/M version No. * ;* - Using direct console I/O and using * ;* function No.30 (change file attributes)* ;* - Close after a read file bug fixed. * ;* - Error check on opening a previous * ;* output file added. * ;* *** - User response routine added so when * ;* a file exists on the output disk, you * ;* may either erase it or leave it (this * ;* routine includes erasure of R/O files) * ;* - MOVE routine deleted. * ;* - Fixed bug encounted when trying to * ;* copy r/o files (you couldn't!),by * ;* doing AND 07FH on ALL characters put * ;* into the filename table !! * ;* - Fixed filename printing stuff. * ;* - Spread out messages for readability. * ;* - Changed size of filename table from * ;* 64 entries to 128 entries, so large * ;* disk directories can be copied. * ;* - Added explanation of how each entry * ;* in the filename table is constructed. * ;* * ;* (***) = main bulk of code added. * ;* * ;* Vers 4.5 - 10/29/80 - Deleted system disk request * ;* of V4.0 to shorten messages, minor * ;* changes in abort options and other * ;* messages. Moved disk reset of V4.1 to * ;* point before directory search. (CHS) * ;* * ;* Vers 4.4 - 10/28/80 - Modified to bail out with * ;* message if no FCB is specified. * ;* Updates rearranged with most recent * ;* first for reader convenience. * ;* (Charles H. Strom) * ;* * ;* VERS 4.3 - BY LEWIS MOSELEY, JR. 3/22/80 * ;* FIXED BUG WHICH SHOWED UP WHEN MULTIPLE* ;* COPIES WERE MADE OF A MULTIPLE EXTENT * ;* FILE, IN THAT CP/M OPEN THE NEXT EXTENT* ;* USING THE DATA AREA TO SEARCH THE * ;* DIRECTORY, SCREWING UP THE DATA BLOCK * ;* THAT IS THERE. * ;* * ;* VERS 4.2 - BY LEWIS MOSELEY, JR. 2/23/80 * ;* FIXED BUG THAT OCCURRED WHEN ONLY A * ;* SINGLE FILE WAS SPECIFIED AND THAT * ;* FILE WAS NOT FOUND : PROGRAM HUNG IN A * ;* LOOP. * ;* * ;* VERS 4.1 - BY LES FREED AND LEWIS MOSELEY 2/11/80 * ;* ADDED DISK RESET ON DISK CHANGE TO * ;* ALLOW CHANGING DENSITY BETWEEN DISKS * ;* ADDED CTL-C ABORT * ;* * ;* VERS 4.0 - BY LEWIS MOSELEY, JR. 12/79 * ;* ADDED OPTION FOR MULTIPLE OUTPUT * ;* COPIES ADDED REQUEST FOR SYSTEM DISK * ;* BEFORE REBOOT * ;* * ;* l.e. hughes (9/1979) * ;* mycroft labs * ;* atlanta, ga * ;* * ;* MODIFIED - FOR SOL & COMPATABLE COMPUTERS BY * ;* LEWIS MOSELEY, JR. - ATLANTA,GA. * ;* * ;****************************************************** ;* EQUATES * version equ 5 modlev equ 0 entry equ 0005h ; Bdos entry point tfcb equ 005ch ; System file control blk dbuf equ 0080h ; System disk buffer cr equ 0dh lf equ 0ah rcfc equ 01 ; Read console wcfc equ 02 ; Write console consol equ 06 ; Direct console i/o vers equ 12 ; Version number function rdfc equ 13 ; Reset disk offc equ 15 ; Open file cffc equ 16 ; Close file sffc equ 17 ; Search first snfc equ 18 ; Search next dffc equ 19 ; Delete file rrfc equ 20 ; Read record wrfc equ 21 ; Write record mffc equ 22 ; Make file safc equ 26 ; Set address fn equ 01 ; File name offset ft equ 09 ; File type offset ex equ 12 ; Extent number offset nr equ 32 ; Next record offset org 00100h mft: ld sp,stack+64 ld hl,msg1 ; Print 'MFT V5.0' call wasc ld c,vers ; Get version # call entry ld a,l call p,020h ; Vers >= 2.0 ? jr nc,ok1-$ ; Yes,then go on ld hl,badver ; "Sorry you need 2.0" call wasc ok2: ld hl,msgg ; "type ^c" call wasc call racc call p,3 jr nz,ok2-$ jp p,00000h ; Reboot ok1: xor a ; Clear break flags ld (ibflg),a ld (obflg),a ld (ndflg),a ; CLEAR NO DUP FLAG ld a,(tfcb+1) ; If no FCB specified call p,' ' ; Then say so jr nz,ok-$ ld hl,msgk ; And bail out call wasc ; Here jp p,00000h ;* calculate buffer size = fwa(BDOS) - fwa(MBUF) * ok: ld hl,(entry+1) ; Hl = (entry+1) - 6 ld de,-6 add a,hl,de ld a,l and 80h ; Hl = hl mod 128 ld l,a ld de,mbuf ; Hl = hl - fwa(MBUF) ld a,l sub e ld l,a ld a,h sbc a,d ld h,a add a,hl,hl ; Hl = hl / 128 ld l,h ld a,0 ; Don't touch cf adc a,a,0 ld h,a dec hl ; Subtract one ld (space),hl ; Save as buffer size push hll ; Save size ld hl,msg2 ; Write 'Buffer size = ' call wasc pop hll ; Get size back call wdwc ; Print size of buffer ld hl,msg3 ; Write ' sectors' call wasc ;* ask user to mount input disk * mft1: ld hl,msg4 ; "Mount input disk," call wasc call racc ; Read response call p,03 ; CTL-C ? jp p,z,mftl ; ABORT WITH MESSAGE call p,cr ; Loop if anything but CR jr nz,mft1-$ call weolc ; Echo CR,LF call reset ; Adjust density ld a,(ibflg) ; Jump if ibflg set or a jr nz,mft2a-$ ;* copy command line into cbuf * ld hl,dbuf ; Fwa of command line ; Image ld de,cbuf ; Fwa of command buffer ld b,(hl) ; Fetch comm. line length inc hl mft2: ld a,(hl) ; Fetch next byte from cli inc hl ld (de),a ; Store in dbuf inc de dec b ; Decrement count jr nz,mft2-$ ; Loop until zero xor a ; Store zero byte at end ld (de),a ld hl,cbuf ; Reset cbufp ld (cbufp),hl call cfnt ; Create file name table ld hl,fnt ; Reset fnt pointers ld (ifntp),hl ld (ofntp),hl mft2a: ld hl,mbuf ; Reset mbuf pointer ld (mbufp),hl ld hl,(space) ; Reset msize ld (msize),hl ld a,(ibflg) ; Jump if ibflg not set or a jr z,mft3-$ ld a,(neras) ; Get last file not ; Written flag or a jr z,mft2b-$ ; Not set the read more of ; Previously opened file xor a ld (neras),a ld (ibflg),a ld (obflg),a jr mft3-$ mft2b: ld hl,ifcb ; Copy IFCB into TFCB ld de,tfcb ld bc,33 ldir ; Move the stuff xor a ; Clear ibflg ld (ibflg),a inc a ; Set obflg ld (obflg),a ld hl,(ifntp) ; Back ifntp up 4 bytes ld de,-4 add a,hl,de ld (ifntp),hl ld hl,tfcb+fn ; Write filename call wfnc ld hl,msg6 ; Write ' - ' call wasc ld hl,(ifntp) ; DE = ifntp ex de,hl jr mft4-$ ; Continue reading ; Previous file ;* parse off next name from cbuf * mft3: ld hl,(ifntp) ; Fetch input fnt pointer ld a,(hl) ; Jump if end of table call p,0ffh jp p,z,mft9 ld (hl),1 ; Set 'file has been read' ; flag inc hl ld de,tfcb+fn ; Copy filename into tfcb ld bc,11 ldir ; Move the stuff ld (ifntp),hl ; Save input fnt pointer ld hl,tfcb+fn ; Write filename call wfnc ld hl,msg6 ; Write ' - ' call wasc xor a ; Setup tfcb ld (tfcb),a ld (tfcb+ex),a ld (tfcb+nr),a call open ; Open file ld hl,(ifntp) ex de,hl mft4: ld hl,(mbufp) ld a,h ; Copy into fnt entry ld (de),a inc de ld a,l ld (de),a inc de ex de,hl ; Save fnt pointer ld (ifntp),hl ld hl,0 ; File size (in secs.) = 0 ld (fsize),hl ;* read next file from input disk * mft6: ld hl,(mbufp) ex de,hl call setdma call read ; Read next sector or a ; Jump if normal transfer jr z,mft7-$ call p,1 ; Jump if EOF jr z,mft8-$ ld hl,msg8 ; Write 'read error - ' call wasc jr mft8-$ ; Continue as if EOF mft7: ld hl,(mbufp) ; Mbufp = mbufp + 128 ld de,128 add a,hl,de ld (mbufp),hl ld hl,(fsize) ; Fsize = fsize + 1 inc hl ld (fsize),hl ld hl,(msize) ; Decrement msize dec hl ld (msize),hl ld a,h ; Loop if still positive or l jr nz,mft6-$ ld hl,tfcb ; Copy tfcb into ifcb ld de,ifcb ld bc,33 ldir ; Move the stuff ld a,1 ; Set ibflg ld (ibflg),a mft8: ld de,dbuf ; Reset dma pointer call setdma ; Deleted close file from ; Here (don't close after ; A read !!) ld hl,(fsize) ; Write file size call wdwc ld hl,msg9 ; Write ' sectors read' call wasc ;* update fnt, loop * ld hl,(fsize) ; DE = file size ex de,hl ld hl,(ifntp) ; Store file size in fnt ; Entry ld (hl),d inc hl ld (hl),e inc hl ld (ifntp),hl ; Save fnt pointer ld a,(ibflg) ; Loop if ibflg not set or a jp p,z,mft3 ;* FLAG THAT THE MEMORY BUFFER HAS BEEN EXCEEDED, * ;* TELL USER THAT DUPLICATE COPIES CANNOT BE MADE * ld a,(ndflg) ; TOLD HIM ALREADY? or a jr nz,mft9-$ ; JUMP IF SO ld hl,msgh ; IF NOT, TELL HIM call wasc ld a,1 ; SET NDFLG THIS TIME ld (ndflg),a ;* Ask user to mount output disk * mft9: ld hl,msga ; "Mount output disk," call wasc call racc ; Read response call p,03 ; CTL-C? jp p,z,mftl ; ABORT WITH MESSAGE IF SO call p,cr ; Loop if anything but CR jr nz,mft9-$ call weolc ; Echo CR,LF call reset ; Reset disk system, make ; r/w and check density ld a,(obflg) ; Jump if obflg not set or a jr z,mfta-$ ld hl,ofcb ; Copy ofcb into tfcb ld de,tfcb ld bc,33 ldir ; Move the stuff call open ; Open previous file call p,255 ; Previous file present? jr nz,mft9b-$ ; Yes,then ok to go on ld hl,reoper ; "Reopen error!!" call wasc mft9a: ld hl,msgg ; "press ^c to reboot" call wasc call racc ; Get a char call p,03 ; "^C"? jr nz,mft9a-$ ; No,then get proper ans. jp p,00000h ; Reboot mft9b: ld hl,(ofntp) ; Backup output fnt ; pointer 4 bytes ld de,-4 add a,hl,de ld (ofntp),hl ld hl,tfcb+fn ; Write file name call wfnc ld hl,msg6 ; Write ' - ' call wasc jp p,mftb ; Continue writing ; previous file ;* write next file to output disk * mfta: ld hl,(ofntp) ld a,(hl) ; Get file read flag or a ; Last read in file jp p,z,mftf ; Yes,then end of write call p,0ffh ; End of filename table? jp p,z,mftf ; Yes,then go inc hl ld de,tfcb+fn ld bc,11 ldir ; Move the stuff ld (ofntp),hl ld hl,tfcb+fn ; Print "filename" call wfnc ld hl,msg6 ; Print " - " call wasc xor a ld (tfcb),a ld (tfcb+ex),a ld (tfcb+nr),a ;* Start of version 5.0 erase mods * ld de,tfcb call srchf ; Does file already exist? call p,255 jp p,z,mftaa ; No,then normal write ld (save),a ; Save dir pointer ld hl,tfcb ; Copy tfcb into ofcb ld de,ofcb ld bc,33 ldir ; Move the stuff ld hl,msgl ; "file exists. erase?" call wasc look: ld c,consol ; Input char with no echo ld e,0ffh call entry call p,'N' jr z,look1-$ call p,'Y' jr nz,look-$ look1: push af ; Save answer ld c,consol ; Echo the char ld e,a call entry call weolc ; Do cr-lf pop af ; Get answer back call p,'Y' jr z,look5-$ ; If yes then delete file ld a,1 ld (neras),a ; Set last file not ; Written flag ld hl,(ofntp) ; Get fnt pointer inc hl inc hl inc hl inc hl ; Point to next entry look2: push hll ; Save for later inc hl ; Point to next filename ld de,tfcb+fn ; Point to last filename ld b,11 ; Length to test look3: ld a,(de) ; Compare the names call p,(hl) jr nz,look4-$ ; If they are NOT the same ; Then go ahead and use ; The name being compared inc hl inc de djnz look3-$ ; Do whole name ; If here then both names ; Are the same thus don't ; Use this name in fnt. ; Must point to next name ; After this name pop hll ; Get this fnt pointer ld de,16 ; Offset add a,hl,de ld a,(hl) ; Check if this file read or a jp p,z,mftf ; No,not read yet call p,0ffh ; End of table? jp p,z,mftf ; Yes,end of fnt reached jr look2-$ ; Compare next file ; Must keep comparing name ; Until : a no-match ; ; Or end of table or last ; Read file is found. look4: pop hll ; Get fnt pointer back ld (ofntp),hl ; Save it for much later jp p,mfta ; Do next file look5: ld hl,tfcb+fn ; "filename" call wfnc ld hl,msg6 ; " - " call wasc ld a,(save) ; Get dir pointer back and 3 ld l,a ld h,0 add a,hl,hl add a,hl,hl add a,hl,hl add a,hl,hl add a,hl,hl ; Get offset into dir blk. ld de,dbuf+ft ; Point to filetype byte ; In found dir entry. add a,hl,de ld a,(hl) ; 1st filetype byte bit 7,a ; Check for r/o = set jr z,look7-$ ; Not set,then erase ok ; Here if file to be ; Erased is r/o. Ask Q ; If want erase anyway? ld hl,filero ; "file is r/o. Erase?" call wasc look6: ld c,consol ; Get char ld e,0ffh call entry call p,'N' jp p,z,look1 ; Don't erase it call p,'Y' jr nz,look6-$ ld c,consol ; Echo ld e,a call entry call weolc ; Cr-lf ld de,tfcb ld c,30 ; Set file attr. to r/w call entry ld hl,tfcb+fn ; "filename" call wfnc ld hl,msg6 ; " - " call wasc look7: xor a ld (tfcb),a ld (tfcb+ex),a ld (tfcb+nr),a call delt ; Delete existing file ;* End of version 5.0 erase mods * mftaa: ld hl,tfcb ; Copy tfcb into ofcb ld de,ofcb ld bc,33 ldir ; Move the stuff call make call p,255 ; Jump if ok jr nz,mftb-$ ld hl,msgb ; Write 'unable to create' call wasc jp p,mftg mftb: ld hl,(ofntp) ld d,(hl) ; Fetch fwa of file from ; fnt inc hl ld e,(hl) inc hl ex de,hl ld (mbufp),hl ; Save it ex de,hl ld d,(hl) ; Fetch size of file from ; fnt inc hl ld e,(hl) inc hl ex de,hl ld (fsize),hl ; Save it ld (xsize),hl ; Save for printout ex de,hl ld (ofntp),hl ld hl,(fsize) ; Jump if fsize=0 ld a,h or l jr z,mftda-$ mftc: ld hl,(mbufp) ; Set dma address to mbufp ex de,hl call setdma call write ; Write next sector or a ; Jump if ok jr z,mftd-$ ld hl,msgc ; "error writing file" call wasc jp p,mftg mftd: ld hl,(mbufp) ; Mbufp = mbufp + 128 ld de,128 add a,hl,de ld (mbufp),hl ld hl,(fsize) ; Fsize = fsize - 1 dec hl ld (fsize),hl ld a,h ; Loop until zero or l jr nz,mftc-$ mftda: ld hl,tfcb ; Copy tfcb into ofcb ld de,ofcb ld bc,33 ldir ; Move the stuff ld de,dbuf ; Reset dma pointer call setdma call close ; Try to close file call p,255 ; Jump if ok jr nz,mfte-$ ld hl,msgd ; Write 'unable to close' call wasc mfte: ld hl,(xsize) ; Number of sectors done call wdwc ld hl,msge ; Write ' sectors written' call wasc xor a ld (neras),a ; Clear last file not ; Writen flag jp p,mfta mftf: ld a,(ibflg) ; Loop if ibflg set or a jp p,nz,mft1 ;* Terminate program here on irrecoverable error or * ;* when all files have been copied. Must reload * ;* system disk to avoid crash when copying to * ;* someone else's disk. * ;* If normal end, and if buffer has not been * ;* exceeded, give user the option of making another * ;* copy of the same set of files. * mftg: ld hl,msgf ; SEE IF OPTION IS ALLOWED ld a,(ndflg) or a jr nz,mfth-$ ; JUMP IF NOT ALLOWED call wasc ; ELSE TELL ABOUT OPTION mfth: ld hl,msgg ; ASK FOR SYSTEM DISK call wasc call racc ; Wait for response call p,03h ; WARM BOOT IF ^C jp p,z,00000h call p,cr ; ATTEMPT REPEAT IF jr nz,mftg-$ ; LOOP TILL GOOD RESPONSE mftj: call weolc ; ACKNOWLEDGE COMMAND ld a,(ndflg) ; REPEAT ALLOWED? or a jr nz,mftk-$ ; JUMP IF NOT ld hl,fnt ; ELSE RESET FNT POINTER ld (ofntp),hl ld hl,mbuf ; RESET MEM BUF POINTER ld (mbufp),hl xor a ; RESET OUTPUT INTERRUPTED ; FLAG ld (obflg),a jp p,mft9 ; AND DO AGAIN mftk: ld hl,msgh ; CANNOT REPEAT, TELL HIM call wasc jr mftg-$ ; AND WAIT FOR SYSTEM DISK mftl: ld hl,msgj ; ABORT MESSAGE call wasc jp p,00000h ; WARM BOOT ;* subroutines * ; MOVE deleted from here ;* gfn - get file name * gfn: ld a,(hl) or a retz call p,' ' jr nz,gfn0-$ inc hl jr gfn-$ gfn0: ld de,xfcb xor a ld (de),a inc de push dee ld b,11 ld a,' ' gfn6: ld (de),a inc de dec b jr nz,gfn6-$ pop dee ld b,9 gfn1: ld a,(hl) or a jp p,z,gfn4 inc hl call p,' ' jp p,z,gfn4 call p,'.' jr z,gfn2-$ call p,'*' jr z,gfn7-$ ld (de),a inc de dec b jp p,z,gfn5 jr gfn1-$ gfn7: dec b jr z,gfn9-$ ld a,'?' ld (de),a inc de jr gfn7-$ gfn9: ld a,(hl) call p,'.' jr nz,gfn4-$ inc hl gfn2: ld de,xfcb+ft ld b,4 gfn3: ld a,(hl) or a jr z,gfn4-$ inc hl call p,' ' jr z,gfn4-$ call p,'*' jr z,gfn8-$ ld (de),a inc de dec b jr z,gfn5-$ jr gfn3-$ gfn8: dec b jr z,gfn4-$ ld a,'?' ld (de),a inc de jr gfn8-$ gfn4: xor a ret gfn5: scf ret ;* cfnt - create file name table * cfnt: ld hl,fnt ; Reset ifntp ld (ifntp),hl ld (hl),0ffh ; VER 4.2 BUG FIX cfnt1: ld hl,(cbufp) ; Get cbufp ld a,(hl) ; Exit if end of list or a retz call gfn ; Get next afn ld (cbufp),hl ; Save command buffer ptr jr nc,cfnt2-$ ; Jump if filename ok ld hl,msg5 ; "Syntax error in name" call wasc jr cfnt1-$ ; Loop cfnt2: xor a ; Clear xfcb extent field ld (xfcb+ex),a ld de,xfcb ; Search for first occur. call srchf call p,255 ; Jump if found jr nz,cfnt3-$ ld hl,xfcb+fn ; Write filename call wfnc ld hl,msg7 ; Write ' not found' call wasc jr cfnt1-$ ; Loop cfnt3: and 3 ; Index into cbuf ld l,a ld h,0 add a,hl,hl add a,hl,hl add a,hl,hl add a,hl,hl add a,hl,hl ld de,dbuf add a,hl,de ex de,hl ; Copy filename into fnt ld hl,(ifntp) ex de,hl ld b,12 cfnt4: ld a,(hl) and 07fh ; Set bit 7 to 0 !!! ld (de),a inc hl inc de djnz cfnt4-$ ld hl,zeros ; Zero fill rest of entry ld bc,4 ldir ; Move the stuff ex de,hl ld (ifntp),hl ; Save input fnt pointer ld (hl),0ffh ; Insure FF byte at end ld de,xfcb ; Search for next occur. call srchn call p,255 ; Jump if found jr nz,cfnt3-$ jp p,cfnt1 ; Go get next afn ;* wasc - write ascii string to console * wasc: ld a,(hl) or a retz call wacc inc hl jr wasc-$ ;* wfnc - write file name to console * ;* Note: Under SOLOS and CUTER, 01 is the cursor- * ;* left character. * ;* When MFTing a multi-extent file, the extent * ;* character must be filtered out of the file- * ;* name-block to avoid wierd console output. * wfnc: push bcc ld b,8 wfnc1: ld a,(hl) and 07fh call wacc inc hl djnz wfnc1-$ ld a,'.' call wacc ld b,3 wfnc2: ld a,(hl) and 07fh call wacc inc hl djnz wfnc2-$ pop bcc ret ;* weolc - write end of line to console * weolc: push af ld a,cr call wacc ld a,lf call wacc pop af ret ;* wdwc - write decimal word to console * wdwc: push hll push dee push bcc ld b,0 ; Clear 'digit written' ; flag ld de,10000 ; Write 1st digit call wndd ld de,1000 ; Write 2nd digit call wndd ld de,100 ; Write 3rd digit call wndd ld de,10 ; Write 4th digit call wndd ld de,1 ; Write 5th digit ld b,1 ; Force last digit to ; Print call wndd pop bcc pop dee pop hll ret wndd: ld c,0 ; C=0 wndd1: ld a,l ; Hl = hl - de sub e ld l,a ld a,h sbc a,d ld h,a jr c,wndd2-$ ; Jump if < 0 inc c ; C = c + 1 jr wndd1-$ ; Loop wndd2: add a,hl,de ; Hl = hl + de ld a,c ; Jump if c non-zero or c jr nz,wndd4-$ ld a,b ; Jump if digit written or b jr nz,wndd4-$ ld a,' ' ; Write one space jr wacc-$ wndd4: ld b,1 ; Set 'digit written' flag ld a,c ; Encode c into decimal ; ascii add a,a,'0' jr wacc-$ ; Go write it ;* wacc - write ascii character to console * wacc: push hll push dee push bcc push af ld c,wcfc ld e,a call entry pop af pop bcc pop dee pop hll ret ;* racc - read ascii character from console * racc: push hll push dee push bcc ld c,rcfc call entry pop bcc pop dee pop hll ret ;* reset - reset disk system * reset: push hll push dee push bcc ld c,rdfc call entry pop bcc pop dee pop hll ret ;* open - open disk file * open: push hll push dee push bcc ld de,tfcb ld c,offc call entry pop bcc pop dee pop hll ret ;* read - read record from disk file * read: push hll push dee push bcc ld de,tfcb ld c,rrfc call entry pop bcc pop dee pop hll ret ;* close - close disk file * close: push hll push dee push bcc ld de,tfcb ld c,cffc call entry pop bcc pop dee pop hll ret ;* delt - delete disk file * delt: push hll push dee push bcc ld de,tfcb ld c,dffc call entry pop bcc pop dee pop hll ret ;* make - make new disk file * make: push hll push dee push bcc ld de,tfcb ld c,mffc call entry pop bcc pop dee pop hll ret ;* write - write record to file * write: push hll push dee push bcc ;* REVISION 4.3 MODS * ld a,(tfcb+nr) ; LAST RECORD IN EXTENT? call p,7fh jr nz,write1-$ ; NO, CONTINUE ld hl,(mbufp) ; EXISTING DATA AREA ld de,dbuf ; POINT TO SAFE AREA call setdma ; FROM HERE ld bc,80h ; LENGTH TO MOVE ldir ; MOVE DATA AWAY SO... ;* CP/M DOESN'T OVERWRITE THE REAL DATA IN OPENING * ;* NEXT EXTENT * ;* END REVISION 4.3 MODS * write1: ld de,tfcb ld c,wrfc call entry pop bcc pop dee pop hll ret ;* setdma - set dma address * setdma: push hll push dee push bcc ld c,safc call entry pop bcc pop dee pop hll ret ;* srchf - search for first occurance of afn * srchf: push hll push dee push bcc ld c,sffc call entry pop bcc pop dee pop hll ret ;* srchn - search for next occurance of afn * srchn: push hll push dee push bcc ld c,snfc call entry pop bcc pop dee pop hll ret ;* mesages here * msg1: db cr,lf db 'MFT V' db version+'0' ; VERSION # db '.' db modlev+'0' ; MODIFICATION LEVEL db cr,lf db 'Multi-File-Transfer for single ' db 'disk,' db cr,lf db 'With multiple-copy option.' db cr,lf,lf db 0 msg2: db 'Buffer size = ' db 0 msg3: db ' sectors.' db cr,lf,lf db 0 msg4: db 'Mount INPUT disk, type RETURN (or ^C ' db 'to reboot)...' db 0 msg5: db '-- Syntax error in filename --' db cr,lf db 0 msg6: db ' - ' db 0 msg7: db ' not found !' db cr,lf db 0 msg8: db 'read error - ' db 0 msg9: db ' sectors read.' db cr,lf db 0 msga: db 'Mount OUTPUT disk, type RETURN (or ' db '^C to reboot)...' db 0 msgb: db '-- unable to create --' db cr,lf db 0 msgc: db '-- error writing file --' db cr,lf db 0 msgd: db '-- unable to close --' db cr,lf db 0 msge: db ' sectors written.' db cr,lf db 0 msgf: db cr,lf db 'Completed. ' db 'Type RETURN for another copy, OR...' db 0 msgg: db cr,lf db 'Type ^C to reboot.' db cr,lf db 0 msgh: db cr,lf db '++ Memory buffer exceeded, cannot ' db cr,lf db 'make duplicate copies this time ; ' db cr,lf db 'last ouput file is defective ++' db cr,lf,lf db 0 msgj: db cr,lf db '++ PROGRAM ABORTED ++' db cr,lf db 0 msgk: db cr,lf db '-- No file name specified --' db cr,lf db 0 msgl: db 'exists. Erase it (Y/N) ? ' db 0 filero: db 'is a R/O file. Confirm erasure ' db '(Y/N) ? ' db 0 badver: db 'Sorry, you need CP/M version 2.0 or ' db 'higher.' db cr,lf db 0 reoper: db '-- Reopen error , insert correct ' db 'output disk next time --' db cr,lf db 0 zeros: db 0,0,0,0 org ($+15)/16*16 fnt: defs 16*128+1 ; Changed fnt entries from ; 64 to 128 !! stack: defs 64 space: defs 2 ; Available space msize: defs 2 ; Memory size cbuf: defs 80 ; Command buffer cbufp: defs 2 ; Command buffer pointer fsize: defs 2 ; File size in sectors xsize: defs 2 ; File size for printout ifntp: defs 2 ; Input fnt pointer ofntp: defs 2 ; Output fnt pointer mbufp: defs 2 ; Memory buffer pointer ifcb: defs 33 ; Input fcb ofcb: defs 33 ; Output fcb xfcb: defs 33 ; Temporary fcb ibflg: defs 1 ; Input break flag obflg: defs 1 ; Output break flag ndflg: defs 1 ; NO DUPLICATE ALLOWED ; FLAG save: defs 1 ; Temp. store of directory ; Pointer in erase routine neras: defs 1 ; Last output file not ; Written to disk flag ! mbuf equ $ end mft ;****************************************************** ;* * ;* Explanation as to structure of entries in the FNT * ;* ------------------------------------------------- * ;* * ;* ------------------------------------- * ;* |00|01|02|..|..|..|10|11|12|13|14|15| * ;* ------------------------------------- * ;* * ;* 00 = read done flag ; set to 1 if this name has * ;* already been read in. * ;* * ;* 01-08 = filename. * ;* * ;* 09-11 = filetype. * ;* * ;* 12-13 = start address of data for this file. * ;* * ;* 14-15 = length of file in 128 byte sectors. * ;* * ;* Note : 00-15 are offset from start of FNT entry. * ;* * ;******************************************************