;SWAPCOPY.ASM.....a single drive copy program. ; November 1980 ;by John M. Kodis, Buffalo, New York. ; Used with permission of Mr. Kodis. ; ;modified by Jerry W. Haigwood, 4/21/84 for use ; with the AMPRO Little Board (tm) CPU ; ;Revision history: ; ;Version 1.1 8/07/84 Modified to work with 48tpi.com - rbl ; 1.2 10/17/84 Improved disk reset logic - rbl ; 1.3 12/10/85 Modified to copy R/O files - RLH ; 1.3A 1/08/86 Modified to copy R/O files and set ; the destination R/O attribute - RLH ; ; **************************** NOTE ****************************** ; * Version 2.0 and later require AMPRO BIOS Version 2 and later * ; **************************************************************** ; 2.0 1/28/86 Improved SWAPCOPY program - RLH ; 2.1 1/29/86 Added trap for Version 1 BIOS - rbl ; 2.2 1/30/86 Added trap for valid floppy drives only - RLH ; ; ;allows files to be transfered from one diskette to ;another in a system with only a single drive. ; ;allows ambiguous file specifications. ;allows transfer of files larger than available memory, ;and transfer of multiple files in a single pass. ; ;allows use of dissimiliar media (i.e., to copy ;programs from a single density master diskette ;to a double density working diskette). ;self prompting for operator convience ; ;for use with AMPRO 8 bit machines ONLY ; ;developed using CP/M 2.0, but uses only those bdos calls ;which are supported under CP/M 1.4 except BDOS CALL 30 - SET FILE ATTRIBUTES ; ; disk to disk file transfer program. ; ; at the command level, the command: ; ; SWAPCOPY ; ; will copy the file filename.ext from the source diskette ; to destination diskette, prompting as necessary to allow the ; diskettes to be swapped if necessary. ; BOOT EQU 0 ;system reboot BDOS EQU 5 ;bdos entry point MEMTOP EQU 6 ;pointer to start of fbase FCB1 EQU 5CH ;first file name & source fcb FCB2 EQU 6CH ;second file name TPA EQU 100H ;beginning of tpa ; FALSE EQU 0 TRUE EQU 255 ; NUMKEYS EQU 14 CNTRLC EQU 3 ESC EQU 1BH TAB EQU 9 NUL EQU 0 LF EQU 10 CR EQU 13 BELL EQU 7 SECSIZ EQU 128 ;bytes per sector ; ORG TPA ; SWAPCOPY: LXI SP,STACK ;set up local stack space ; SETUP: MVI A,FALSE STA DONE ;we're not done yet STA ONE2GO ;nor do we have a file to go ; LXI H,BUF+EOFO MVI M,TRUE ;set initial eof to true ; LHLD MEMTOP LXI D,-(SECSIZ+FREEO+8) DAD D ;highest availiable dma buffer SHLD BUFTOP ; LXI H,BUF SHLD FPBPNT ;free space starts at buf ; MVI A,1 STA NAMES ;initial next-names count ; ASKUSR: LXI D,MENU ;load the menu MVI C,9 ;print the menu CALL BDOS call cget call dfdev ;print the floppy drive menu jm wrong$bios ;can't use version 1 bios LXI D,MENU2 ;load the continuation menu MVI C,9 ;print the menu CALL BDOS LXI D,SOURINP ;POINT TO SOURCE MESSAGE CALL RESPONSE STA SOURDRV ;SAVE THE DRIVE LETTER dcr a ;change input to real drive STA SDISK ;source disk LXI D,DESTINP ;POINT TO DESTINATION MESSAGE CALL RESPONSE STA DESTDRV ;SAVE THE DRIVE LETTER dcr a ;change input to real drive STA DDISK ;destination disk LXI D,FNMSG ;DISPLAY FILENAME INPUT STRING MVI C,PRINTF CALL BDOS CALL FNINP ;INPUT THE FILE NAME ASKSR: CALL CRLF ;CR & LF THE CRT CALL CRLF LXI D,SOURMX CALL PROMPT ;ask for the source disk CALL RDRST ;reset disk unless source = "e" LDA SDISK ;get the source disk MOV E,A ;move it to e CALL SELDSK ;select it CALL FFNAME ;get the first matching file name CALL ADJPNT CALL FILFPB ;set rdma & wdma pointers, fill in file name MVI A,TRUE STA ONE2GO ;if so, set 'one to go' to true, then copy it ; RDLOOP: LDA FILEOF ANA A JM WR ;start writing when the last file has been read LHLD RDMA CALL FULBUF JC WR ; or when the buffer space has been exhausted ; LHLD EOF MOV A,M ANA A JZ SAMFIL ;if not end-of-file, we're on the same file. ; CALL ADJPNT ;else, this is the start of a new file... CALL FILFPB ;adjust pointers & fill new fpb XRA A LHLD SFEXT MOV M,A ;source file extent := 0 LHLD SFCR MOV M,A ;source file current record := 0 LHLD DFEXT MOV M,A ;dest file extent := 0 LHLD DFCR MOV M,A ;dest file current record := 0 LHLD EOF MOV M,A ;eof := false LHLD MADE MOV M,A ;made := false LHLD OPENED MOV M,A ;opened := false LHLD LAST MOV M,A ;last := false MVI A,TRUE STA FPBUSD ;mark current fpb as used LHLD SFCB CALL OPEN ; SAMFIL: CALL READ LHLD EOF MOV A,M ANA A JZ SAMNAM ;read sectors until eof or buffer full ; NXTNAM: CALL FFNAME ;on eof, find the next name to be considered LXI H,NAMES MOV A,M STA NAMCNT NNLOOP: CALL FNNAME ;find next name... LXI H,NAMCNT DCR M JNZ NNLOOP ;as many times as necessary. LXI H,NAMES INR M ;then bump the count for the next pass ; LDA FILEOF ANA A ;if all matching file names have been copied JM WR ;(or passed over), start writing. MVI A,TRUE STA ONE2GO ;if so, set 'one to go' to true, then copy it LDA FPBUSD ANA A ;if the current fpb is unused, use it JZ SAMNAM LHLD RDMA ;else set up the next fpb, and use it MOV A,M INX H MOV H,M MOV L,A SHLD FPBPNT ;next block starts just past rdma JMP RDLOOP ; SAMNAM: LHLD RDMA CALL BUMP ;rdma := rdma + secsiz JMP RDLOOP ; WR: LDA ONE2GO ;anything for the destination disk? ANA A JZ FINI ;if not, we're done. LXI H,BUF SHLD FPBPNT ;fpbpnt := buf CALL ADJPNT LXI D,DESTMX CALL PROMPT ;prompt(destmx) CALL WRRST ;reset disk unless dest = "e" LDA DDISK MOV E,A CALL SELDSK WRNEXT: LHLD MADE MOV A,M ANA A JNZ A$M ;if already made, don't make it again ; MVI M,TRUE ;if not made, set made := true LHLD OPENED MVI M,TRUE ;then set opened := true, ;************* V1.3A ************* PUSH H PUSH D PUSH B PUSH PSW LHLD DFCB LXI D,RENFCB LXI B,32 CALL LDIR ;TRANSFER LOWERCASE FILENAME TO RENAME FCB LXI H,RENFCB+9 MOV A,M ANI 20H ;CHECK FOR R/O FLAG JZ NORO ;NO R/O FLAG MOV A,M ANI 05FH ;SET UPPERCASE AND INSURE NO R/O FLAG MOV M,A LXI D,RENFCB ;RESET R/O VECTOR MVI C,SETATRF CALL BDOS CPI 4 ;CHECK FOR ERRORS JNC NORO LXI D,RENFCB MVI C,DELETEF CALL BDOS LXI D,DELRO ;DISPLAY DELETED MESSAGE MVI C,PRINTF CALL BDOS NORO: POP PSW POP B POP D POP H ;************* V1.3A ************* CALL MAKE ;then make the file. ; A$M: LHLD OPENED MOV A,M ANA A JNZ A$OP ;if already opened, don't open it again MVI M,TRUE LHLD DFCB CALL OPEN ;if not open, open it & set opened := true ; A$OP: LHLD RDMA MOV E,M INX H MOV D,M ;de gets rdma LHLD WDMA MOV A,E CMP M ;compare least signifigant bytes JNZ NEQUAL INX H MOV A,D CMP M JZ EQUAL ;is wdma equal to rdma? ; NEQUAL: CALL WRITE ;if not, write a sector LHLD WDMA CALL BUMP ;wdma := wdma + secsiz JMP A$OP ; EQUAL: CALL CLOSE ;when wdma = rdma, close the file LHLD EOF MOV A,M ANA A ;done with file? JZ SKPRPT ;if not, don't report the transfer yet. ;******** V 1.3A ******** PUSH H PUSH D PUSH B PUSH PSW LHLD DFCB LXI D,RENFCB LXI B,16 CALL LDIR ;SET UP RENAME SOURCE LHLD DFCB LXI B,16 CALL LDIR ;SET UP DESTINATION FCB ;**** V1.3A - 1/8/86 **** LDA RENFCB+9 ;CHECK FOR R/O SOURCE FILE ANI 20H ;MOVE THE POSSIBLE R/O FLAG INTO CARRY FLAG JZ EQUALJP ;SKIP THE RENAME TO R/O FILE - IT WASN'T ;**** V1.3A - 1/8/86 **** LXI H,RENFCB+25 ;POINT TO RENAME DESTINATION TYPE CHAR 1 MOV A,M ANI 0DFH ;RESET TO UPPER CASE ORI 80H ;SET R/O FLAG MOV M,A LXI D,RENFCB MVI C,RENAMEF CALL BDOS CPI 4 ;CHECK SUCCESS OF RENAME LXI D,RENERR JNC ABORT ;ERROR EQUALJP: POP PSW POP B POP D POP H ;******** V 1.3A ******** LXI D,CPYDMX CALL PRINT ;print 'copied ' LXI H,RENFCB+16 ;V1.3A was LHLD DFCB CALL PFNAME ;print the file name ; SKPRPT: LHLD WDMA CALL FULBUF ;if the whole buffer has been written, JC WREXIT ;try to read another some more in ; LHLD RDMA ;else, set up to write the next file MOV E,M INX H MOV D,M XCHG ;hl points to next fpb SHLD FPBPNT ;set up the file param. block pointer LHLD LAST MOV A,M STA DONE ANA A JNZ FINI ;if the last file has been written, we're done CALL ADJPNT JMP WRNEXT ;else adjust pointers, then write the next file ; WREXIT: LDA DONE ANA A ;shall we exit or read more files? JNZ FINI ;we're done, so exit ; LXI B,FREEO LXI D,BUF LHLD FPBPNT CALL LDIR ;move the last fpb to the start of the buffer ; LXI H,BUF SHLD FPBPNT CALL ADJPNT CALL FILFPB ;set up the pointers at the start of the buffer ; LXI D,SOURMX CALL PROMPT ;ask for the source disk CALL RDRST ;reset disk unless source = "e" LDA SDISK MOV E,A CALL SELDSK JMP RDLOOP ; WRONG$BIOS: LXI D,BIOSMSG CALL ABORT ; FINI: LXI D,NORMAL CALL PRINT ;show copy complete LXI D,SYSTMX CALL PROMPT ;prompt for system disk RST BOOT ;exit to CP/M ; ABORT: CALL PRINT LXI D,SYSTMX CALL PROMPT ;prompt for system disk RST BOOT ;exit to CP/M ; NAMSIZ EQU 12 ;size of a disk file name (1+8+3) FCBSIZ EQU 36 ;size of a file control block SFCBO EQU 0 ;offset to source fcb SFEXTO EQU 12 ;offset to source file extent SCRO EQU 32 ;offset to source file current record DFCBO EQU 36 ;offset to destination file control block DFEXTO EQU 48 ;offset to destination file extent DCRO EQU 68 ;offset to destination file current record RDMAO EQU 72 ;offset to read zone pointer WDMAO EQU 74 ;offset to write zone pointer MADEO EQU 76 ;offset to file-made flag OPENO EQU 77 ;offset to file-open flag EOFO EQU 78 ;offset to end-of-file flag LASTO EQU 79 ;offset to last-file flag FREEO EQU 80 ;offset to start of freespace ; ADJPNT: LHLD FPBPNT ;compute and save the... LXI D,SFEXTO DAD D SHLD SFEXT ;pointer to source file extent LXI D,SCRO-SFEXTO DAD D SHLD SFCR ;pointer to source file current record, LXI D,DFCBO-SCRO DAD D SHLD DFCB ;pointer to dest fcb, LXI D,DFEXTO-DFCBO DAD D SHLD DFEXT ;pointer to dest file extent, LXI D,DCRO-DFEXTO DAD D SHLD DFCR ;pointer to dest file current record, LXI D,RDMAO-DCRO DAD D SHLD RDMA ;pointer to read dma zone, INX H INX H SHLD WDMA ;pointer to write dma zone, INX H INX H SHLD MADE ;pointer to file made flag, INX H SHLD OPENED ;pointer to file-open flag INX H SHLD EOF ;pointer to end-of-file flag, INX H SHLD LAST ;pointer to the 'last-file' flag, INX H SHLD FSPACE ;and the pointer to the start of free space. RET ; FILFPB: LHLD FPBPNT XCHG LHLD FILEOF ;get offset into directory bufffer MVI H,0 DAD H DAD H DAD H DAD H DAD H ;multiply by 32 LXI B,DIRBUF DAD B ;hl points to file name LXI B,NAMSIZ PUSH H PUSH B CALL LDIR ;move file name to source fcb POP B LHLD DFCB XCHG POP H CALL LDIR ;move file name to destination fcb ; ; ***************** V1.3A *************** PUSH H ;MAKE SURE I DON'T DESTROY ANYTHING PUSH D PUSH B PUSH PSW LHLD DFCB LXI D,9 ;SET INCREMENT TO FCB TYPE CHARACTER 1 DAD D MOV A,M RLC ;CHECK FOR R/O BIT SET JNC NORO2 ;NOT A READ ONLY FILE MOV A,M ANI 7FH ;RESET THE R/O BIT ORI 20H ;CHANGE LETTER TO LOWER CASE MOV M,A ;AND PUT IN THE FCB NAME NORO2: POP PSW ;MAKE SURE I DON'T DESTROY ANYTHING POP B POP D POP H ; ***************** V1.3A **************** ; LHLD FSPACE XCHG LHLD RDMA MOV M,E INX H MOV M,D ;point rdma to start of free space INX H MOV M,E INX H MOV M,D ;point wdma to start of free space RET ; BUMP: MVI A,SECSIZ ADD M MOV M,A ;add sector size to l.s. byte of address RNC INX H INR M ;if carry, increment m.s. byte of address RET ; FULBUF: MOV E,M INX H MOV D,M ;de gets address to be compared LHLD BUFTOP MOV A,L SUB E MOV A,H SBB D RET ;return with carry set if @(de) > buftop ; PFNAME: MVI A,8 CALL PATHL ;print 8 characters in the name, MVI E,'.' CALL CO ;print a period, MVI A,3 ;print the 3 characters in the extension. ; PATHL: INX H MOV E,M CALL CO ;print the character @+(hl) DCR A JNZ PATHL ;repeat (a) times RET ; ; system interface routines ; CIF EQU 1 ;console input function # COF EQU 2 PRINTF EQU 9 ;print buffer function # LINEF EQU 10 ;line input function # CSTSF EQU 11 ;get console status function # RESETF EQU 13 ;select & write enable drive a OPENF EQU 15 ;open file function # CLOSEF EQU 16 ;close file function # SFFF EQU 17 ;search for first function # SFNF EQU 18 ;search for next function # DELETEF EQU 19 ;delete file function # READF EQU 20 ;sequential file read WRITEF EQU 21 ;sequential file write MAKEF EQU 22 ;create & open a new file RENAMEF EQU 23 ;V1.3A rename a file DMAF EQU 26 ;set dma address function # SETATRF EQU 30 ;set file attributes *** V2.2 CP/M *** ; OPEN: MVI C,OPENF XCHG CALL BDOS INR A RNZ ;successful open of requested file OPENNG: LXI D,CANTOP JMP ABORT ; CLOSE: MVI C,CLOSEF LHLD DFCB XCHG CALL BDOS LHLD OPENED MVI M,FALSE RET ; READ: LHLD RDMA MOV E,M INX H MOV D,M CALL SETDMA MVI C,READF LHLD FPBPNT XCHG CALL BDOS LHLD EOF MOV M,A ANA A ; RNZ RET ;RETURNS WITH 'Z' FLAG INDICATING STATUS ; WRITE: LHLD WDMA MOV E,M INX H MOV D,M CALL SETDMA MVI C,WRITEF LHLD DFCB XCHG CALL BDOS ANA A RZ CANTWR: LXI D,SPACE JMP ABORT ; MAKE: MVI C,DELETEF LHLD DFCB XCHG CALL BDOS MVI C,MAKEF LHLD DFCB XCHG CALL BDOS INR A RNZ MAKENG: LXI D,WRPROT CALL PRINT LXI D,NODIR JMP ABORT ; SETDMA: MVI C,DMAF JMP BDOS ; WRRST: ;skip reset if destination drive is "e" because 48tpi.com ;will crash if a 48tpi "e" disk is in a 96tpi "a" drive LDA DDISK ;check destination disk number CPI 4 ;is it "e"? RZ MVI C,RESETF JMP BDOS ; RDRST: ;skip reset if source drive is "e" because 48tpi.com ;will crash if a 48tpi "e" disk is in a 96tpi "a" drive LDA SDISK ;check destination disk number CPI 4 ;is it "e"? RZ MVI C,RESETF JMP BDOS ; CRLF: MVI E,CR CALL CO MVI E,LF CO: PUSH H PUSH PSW MVI C,COF CALL BDOS POP PSW POP H RET ; PRINT: MVI C,PRINTF JMP BDOS ; FFNAME: LXI D,DIRBUF CALL SETDMA MVI C,SFFF LXI D,FCB1 CALL BDOS STA FILEOF INR A RNZ LXI D,NOFILE JMP ABORT ; FNNAME: LXI D,DIRBUF CALL SETDMA MVI C,SFNF LXI D,FCB1 CALL BDOS STA FILEOF ADD A SBB A ;a:=255 if fileof=255, else 0 LHLD LAST MOV M,A RET ; PROMPT: CALL PRINT CLEAR: MVI C,CSTSF CALL BDOS ANA A JZ WAIT MVI C,CIF CALL BDOS ;if there's a char waiting, get it & ignore it. JMP CLEAR WAIT: MVI C,CIF CALL BDOS ;get the next char CPI CNTRLC JZ BOOT CPI ESC JZ BOOT ;quit if ctrl-c or escape CPI CR JNZ BADCH ;explain the procedure call crlf RET SELDSK: MVI C,14 ;select disk function CALL BDOS RET BADCH: LXI D,EXPLAN JMP PROMPT ; LDIR: MOV A,M STAX D INX H INX D DCX B MOV A,C ORA B JNZ LDIR RET ;----------------------------------------------------------------------- ; ; CCGET GET SYSTEM BIOS JUMP TABLES ; ; Brings the current BIOS Jump tables starting at WARM BOOT ; to this local area for ease of utility access. ; ; If this BIOS is Version 2.1 or greater, also brings in the ; secondary Jump Table. ; ; Exits with Z set if lower than 2.1 Bios level ; ;--------------------------------------------------------------------- CGET: LHLD 1 ;GET START OF BIOS CODE AREA LXI D,BBOOT ;MOVE TO LOCAL STORAGE MVI B,BLEN ;SET COUNT CALL CGET0 ;MOVE STRING MVI A,0 ;TEST FOR VERSION CALL BGETT ;IF 0, THEN LESS TAHN 1.4 STA BVERS ;SAVE BIOS VERS INX H ;SEE IF HL IS FFFF MOV A,H ORA L RZ ;IF SO, THEN OLD SYSTEM DCX H ;FIX HL SINCE HAS THE TABLE ADDRESS LXI D,BNXTTBL ;SAVE NEXT TABLE MVI B,BSLEN CALL CGET0 MVI A,0FFH ;SET NZ ORA A RET ;TO ID THIS LEVEL CGET0: MOV A,M STAX D INX H INX D DCR B JNZ CGET0 RET DFDEV: lda bvers cpi 20 rm LXI D,D$FDEV$HDR ; Print header mvi c,9 call bdos mvi a,0 ; starting unit # D$NEXT$FDEV: sta unit call bpaget ; Get address of unit id MOV A,M ; Get unit id CPI 01 ; Floppy? JNZ D$BUMP$PTR ; No -- go to the next device inx h ; Get drive # mov a,m ; . ani 03h ; mask out excess bits MOV l,a ; update floppy device number mvi h,0 ; . dad h ; x2 xchg LXI H,FNAMES ; . dad d ; x2 dad d ; x4 dad d ; x6 lxi d,d$fname ; lxi b,6 ; db 0edh,0b0h ; . (LDIR) lxi h,valdrv ; point to the valid drive table mvi d,00h ; prepare to index into storage table mov e,a ; finish index value dad d ; index hl to the table lda unit ; adi 'A' ; sta d$current ; mov m,a ;put the ascii drive letter in the table LXI D,D$FDEV$LIN ; and output the line mvi c,9 call bdos D$BUMP$PTR: lda unit inr a ; Bump to next unit cpi 16 ; Done yet? jm D$NEXT$FDEV ; No -- go do the next one ret unit: db 0 D$FDEV$HDR: DB cr,lf,lf,'FLOPPY DISK ASSIGNMENTS:',CR,LF DB ' CP/M drive Floppy disk',CR,LF DB '--------------------------',CR,LF,'$' D$FDEV$LIN: DB ' ' D$CURRENT: DB 'x ' D$EDISK: DB ' ' D$EBLANK: DB ' ' D$FNAME: DB ' ' DB CR,LF,'$' D$FDEV$HLEN EQU $-D$FDEV$LIN ; Line length FNAMES: DB 'First ' DB 'Second' DB 'Third ' DB 'Fourth' VALDRV: db 00h,00h,00h,00h,'E',00h,00h,00h ;valid drive table db 00h,00h,00h,00h,00h,00h,00h,00h ;null means no drive ; 'E' is forced since it is the virtual drive RESPONSE: MVI C,9 CALL BDOS ;PRINT OUT THE PASSED MESSAGE CONIN: mvi e,0ffh mvi c,6 call bdos ;input the character ani 5fh ;insure upper case character ora a ;anything there? jz conin CPI CNTRLC ;a ctrl-C? JZ BOOT ;get out if so... CPI ESC ;an escape? JZ BOOT ;ditto ; CPI 'A' ;is it a valid drive letter? ; JC CONIN ; CPI 'Q' ;is it in the valid range? ; JNC CONIN lxi h,valdrv ;point to the valid drive table lxi b,16 ;load the max number of loops db 0edh,0b1h ; Z80 CPIR instruction jnz conin ;if no match - enter a new character PUSH PSW ;save the character MOV E,A mvi c,6 call bdos ;output the character POP PSW ;RETURN THE CHARACTER ret FNINP: ;FILE NAME INPUT ROUTINE lxi h,keybuff mvi m,numkeys ;set max buffer size xra a inx h mov m,a ;zero current key count mvi c,linef lxi d,keybuff call bdos ;get the keyboard input lda keybuff+1 ;load the input count ana a lxi d,kbuff0 jz abort ;exit if no file name input lxi h,keybuff+1 inr m ;increment the number of inputs mov e,m mvi d,0 dad d mvi m,cr ;append cr to the end of input lxi h,fcb1 ;point to the file control block xra a ;clear the accumulator mov m,a ;set to default drive lxi h,fcb1+1 ;WRITE SPACES TO FCB1 filename.ext lxi d,fcb1+2 mvi m,' ' mvi b,10 call mldir lxi h,keybuff+2 ;point to the 1st input character lxi d,fcb1+1 ;point to destination in fcb1 mvi c,'.' ;load character to look for mvi b,9 ;load the max count before or at EXT FNILP: shld kpoint ;save input pointer mov a,m ;load the input character cpi '*' ;check for '?' remainder of input line jz fline ;if zero - finish the fcb line cmp c ;check for end of file name jz fniext ;jump to ext input cpi cr jz fndone ;if carriage return - leave remainder spaces call valid ;set to upper case stax d ;load character into destination fcb location inx h inx d dcr b jnz fnilp FNIEXT: lhld kpoint ;restore the keyboard input pointer inx h ;point to first non period mov a,b ;check last counter cpi 0 jnz fnigo mov a,m ;get the next character cpi '.' ;it had better be the dot. lxi d,kgoof jnz abort ;you goofed - sorry, you can do it all again FNIGO: lxi d,fcb1+9 ;point to destination in fcb1 mvi c,'.' ;load character to look for mvi b,3 ;load the max count before or at EXT FNIELP: mov a,m ;load the input character cpi '*' ;check for '?' remainder of input line jz fext ;if zero - finish the fcb line cmp c ;check for end of file name jz fniejp ;skip over fcb1 storage if '.' cpi cr jz fndone ;if carriage return - leave remainder spaces call valid ;set to upper case stax d ;load character into destination fcb location inx d dcr b FNIEJP: inx h mov a,b ana a ;check for zero jnz fnielp ;loop till done FNDONE: RET ; FLINE: push d pop h dcr b ;reduce one for counter call allfile ;copy '?' into fcb1 jp fniext ;input the file extent ; FEXT: push d pop h dcr b ;reduce one for counter call allfile ;copy '?' into fcb1 jp fndone ; FFCB: push d pop h inr b ;add both ext characters inr b call allfile jp fndone ; ALLFILE: ;enters - HL=source & bc=number to transfer mvi a,'?' ;load character for fcb mov m,a ;load 1st character push h pop d inx d ;point to destination location mov c,a mvi c,0 call mldir ;load the remainder of file name with '?" call zfcb ;zero out the remainder of the fcb ret ; ZFCB: lxi h,fcb1+12 ;zeros out the remainder of the fcb xra a ;load character for fcb (zero) mov m,a mvi b,23 lxi d,fcb1+13 call mldir ;load the remainder of file name with '?" ret ; MLDIR: MOV A,M ;same as Z80 LDIR except, this only uses B reg. STAX D INX H INX D DCR B JNZ MLDIR RET ; VALID: cpi 20h ;changes lower case characters to upper case jc badinp ;abort if control character cpi 61h ;< 'a' ? jc v1 cpi 7bh ;< '{' jnc v1 ani 5fh ;create upper case character V1: ret ; BADINP: lxi d,kgoof jp abort ; ; console messages ; SOURINP: DB CR, LF, 'Enter Source Drive? (A thru P) $' SOURMX: DB CR, LF, LF, 'Place SOURCE on ' SOURDRV: DB 'A:, then type $' DESTINP: DB CR, LF, LF, 'Enter Destination Drive? (A thru P) $' DESTMX: DB CR, LF, 'Place DESTINATION on ' DESTDRV: DB 'A:, then type $' SYSTMX: DB 'Insert SYSTEM disk ...then press $' FNMSG: DB CR, LF, 'Enter FILENAME.EXT to copy ... then type $' COPYMX: DB 'Copy $' CPYDMX: DB CR, LF, 'Copied $' QMARK: DB '? $' EXPLAN: DB 'Press to continue, ' DB 'or C to quit.', CR, LF, '$' NORMAL: DB CR, LF, LF, 'Copy complete.', CR, LF, '$' KGOOF: db CR,LF,LF,'Invalid input, check entries and try again',LF,CR,'$' KBUFF0: DB CR, LF, LF, 'No filename input, please try again', CR,LF,'$' NOFILE: DB CR, LF, 'No source files', CR, LF, '$' NODIR: DB CR, LF, 'Directory space exhausted', CR, LF, '$' CANTOP: DB CR, LF, 'Can''t reopen file.', CR, LF, '$' SPACE: DB CR, LF, 'Data space exhausted', CR, LF, '$' WRPROT: DB CR, LF, 'Write protected?', CR, LF, '$' RENERR: DB CR, LF, 'Destination R/O error', CR, LF, '$' DELRO: DB CR, LF, 'Destination R/O file deleted$' BIOSMSG: db CR, LF, 'BIOS Version 2 or later required!', CR, LF, '$' MENU: DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB CR, LF, 'Single Drive Copy Utility for AMPRO Little' DB ' Board and Series 100' VERSION: DB CR, LF, ' Version 2.2' DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB '$' MENU2: DB CR, LF DB ' E User defined' DB CR, LF, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL DB '$' ; ; data areas ; ; ;------------------------------------------------------------------ ; ; REPLICATED BIOS JUMP TABLE FOR EASE OF USAGE. ; ;------------------------------------------------------------------ ; BBOOT DS 3 BCSTS DS 3 BCIN DS 3 BCOUT DS 3 BLST DS 3 BPNCH DS 3 BRDR DS 3 BHOME DS 3 BSEL DS 3 BSTRK DS 3 BSSEC DS 3 BSDMA DS 3 BSRD DS 3 BSWRT DS 3 BLSTS DS 3 BSTRN DS 3 BGETT DS 3 ;GET 2.1 JUMP TABLES BGETE DS 3 BIOINT DS 3 BSCSI DS 3 BLEN EQU $-BBOOT ;LENGTH TO GET ; BNXTTBL: ;VERSION 2.1 > SECONDARY TABLE BSWAP DS 3 BSXBINT DS 3 BPHTBAC DS 3 BPAGET DS 3 DS 3 DS 3 DS 3 DS 3 BSLEN EQU $-BNXTTBL BVERS: DB 0 ;VERSION OF BIOS CODE KPOINT: DS 1 KEYBUFF: ds NUMKEYS+2 SFCB: DS 0 FPBPNT: DS 2 ;pointer to start of the file param. block SFEXT: DS 2 ;pointer to source file extent byte SFCR: DS 2 ;pointer to source file current record byte DFCB: DS 2 ;pointer to destination file control block DFEXT: DS 2 ;pointer to dest file extent byte DFCR: DS 2 ;pointer to dest file current record byte BUFTOP: DS 2 ;pointer to top of free memory RDMA: DS 2 ;pointer to next read dma zone WDMA: DS 2 ;pointer to next write dma zone MADE: DS 2 ;pointer to file made flag RENFCB: DS 32 ;rename fcb buffer OPENED: DS 2 ;pointer to file open flag EOF: DS 2 ;pointer to end of file flag LAST: DS 2 ;pointer to last file flag FSPACE: DS 2 ;pointer to start of free buffer space FILEOF: DS 1 ;file offset. index into dirbuf DONE: DS 1 ;all files copied flag NAMES: DS 1 ;number of the next file to be copied NAMCNT: DS 1 ;copy of 'names'. used as a counter FPBUSD: DS 1 ;current fpb has been used flag ONE2GO: DS 1 ;there is a file to be transfered flag SDISK: DB 0 ;source disk-default to A DDISK: DB 1 ;destination disk-default to A ; DS 64 ;32 level stack STACK: DS 0 ; DIRBUF: DS SECSIZ ;buffer for searching the directory ; ASKBUF: DS 129 ;buffer for response to query ; BUF: DS 0 ;buffer starts here and extends to fbase ; END SWAPCOPY