; ;**************************************** ;* * ;* * ;* DKCOPY * ;* * ;* A FILE COPY PROGRAM * ;* FOR SINGLE DRIVE SYSTEMS * ;* * ;* * ;**************************************** ; ; ASSEMBLED WITH Z80ASM FROM CPMUG VOL #16 ; ; WRITTEN JAN 24,1981 BY ; ; KEN STEPHENSON ; PHYSICS DIVISION ; ARGONNE NATIONAL LABORATORY ; ARGONNE,IL 60439 ; ; CRLF EQU 0D0AH CR EQU 0DH LF EQU 0AH TPA EQU 0100H BDOS EQU 5 BOOT EQU 0 ; ; ORG TPA LD SP,LSTACK LD DE,SIGNON LD C,9 CALL BDOS ;PRINT SIGNON MESSAGE ; ; RSET LD A,0 ;CLEAR TWO FLAGS LD (AST),A ;ASTERISK IN NAME OR TYPE LD (FIRSTF),A ;FILE COUNTER ; GETFILE LD HL,(FCBBSPT) ;CLEAR OUT LD (HL),0 ;DR FIELD. INC HL ;PUT BLANKS PUSH HL ;INTO POP DE INC DE ;NAME LD BC,11 ;AND LD (HL),20H ;TYPE LDIR ;FIELDS. LD (HL),0 LD BC,30 ;CLEAR OUT REST OF FCB LDIR ; LD E,25H ;OUTPUT LD C,2 ;PROMPT. CALL BDOS ; LD A,1 ;INITIALIZE FOR FILE LD (NAMEPT),A ;NAME FETCH. ; FNAME LD C,1 ;GET CALL BDOS ;CHARACTER. CP 3 ;CHECK FOR CNTL-C JP Z,BOOT CP 8 ;CHECK FOR BACKSPACE JR NZ,NOTBS-$ LD A,(NAMEPT) ;CHECK FOR BEGINNING OF LINE CP 1 JR Z,FNAME-$ DEC A ;NOT BEGINNING OF LINE LD (NAMEPT),A ;DECREMENT NAME POINTER LD E,A ;RESTORE SPACE IN NAME LD D,0 LD HL,(FCBBSPT) ADD HL,DE LD (HL),20H LD E,20H LD C,2 CALL BDOS ;SPACE LD E,8 LD C,2 CALL BDOS ;BACKSPACE JR FNAME-$ NOTBS CP CR JR Z,CKDONE-$ ;IF RETURN, NAME IS IN- ;GO SEE IF DONE. CP 2AH ;CHECK FOR * JR NZ,NOTSTAR-$ LD A,(NAMEPT) ;CHARACTER IS A STAR. CP 9 ;CHECK JR NC,TYPE-$ ;FOR FILE NAME OR TYPE. LD HL,(FCBBSPT) ;FILE NAME-LOAD IN INC HL ;???????? FOR NAME. PUSH HL POP DE INC DE LD BC,7 LD (HL),3FH LDIR LD A,9 ;SET CHARACTER LD (NAMEPT),A ;POINTER TO FILE TYPE. LD A,1 ;TURN ON LD (AST),A ;NAME-STAR FLAG. JR FNAME-$ ;KEEP GOING UNTIL DECIMAL PT. ; TYPE LD HL,(FCBBSPT) ;FORM POINTER LD DE,9 ;IN HL ADD HL,DE ;TO FILE TYPE AREA. LD D,3FH ;LOAD IN LD (HL),D ;??? INC HL ;FOR LD (HL),D ;FILE INC HL ;TYPE. LD (HL),D LD A,12 ;SET CHARACTER POINTER PAST LD (NAMEPT),A ;FILE TYPE AREA. LD A,1 ;TURN ON LD (AST),A ;TYPE-STAR FLAG. JR FNAME-$ ;KEEP GOING UNTIL CARRIAGE RET. ; NOTSTAR CP 2EH ;CHECK FOR DECIMAL PT. JR NZ,NOTDOT-$ LD A,9 ;CHARACTER IS DECIMAL PT. LD (NAMEPT),A ;SET CHAR. PT. TO FILE TYPE. JP FNAME ;GO BACK FOR FILE TYPE. ; NOTDOT LD HL,(FCBBSPT) ;CHARACTER PASSES ALL TRAPS LD DE,(NAMEPT) ;FORM LD D,0 ;POINTER ADD HL,DE ;IN HL. CP 61H ;CHECK FOR LOWER CASE JR C,UPPERC-$ CP 7BH JR NC,UPPERC-$ AND 01011111B UPPERC LD (HL),A ;STORE CHARACTER. INC E ;INCREMENT LD A,E LD (NAMEPT),A ;CHARACTER COUNTER. JP FNAME ;GO BACK FOR ANOTHER CHAR. ; CKDONE LD E,LF ;OUTPUT A LINEFEED LD C,2 CALL BDOS LD HL,(FCBBSPT) ;CHECK FOR BLANK IN INC HL ;FIRST LD A,(HL) ;BYTE CP 20H ;OF NAME. JP Z,WRITEF ;IF SO,THEN DONE WITH READS. ; LD HL,(FCBBSPT) ;MORE FILES TO READ. LD DE,12 ADD HL,DE ;CLEAR OUT SPURIOUS PUSH HL ;CHARACTERS AT POP DE ;END OF FCB. INC DE LD (HL),0 LD BC,20 LDIR LD HL,(FCBBSPT) ;CHECK FOR ? IN NAME ;OR TYPE FIELDS. LD B,11 QLOOP INC HL LD A,(HL) CP '?' JR NZ,NOTQ-$ LD A,1 ;THERE IS A ? IN NAME OR LD (AST),A ;TYPE FIELDS - FLAG FOR ;LOOP ON ALL NAME MATCHES. NOTQ DJNZ QLOOP-$ ;TEST ASTERISK OR ? FLAGS LD A,(AST) CP 1 JP NZ,OPEN ;NO FLAGS-GO OPEN FILE. ; STAR LD DE,80H ;STAR FLAG SET. LD C,26 ;SET DMA ADDRESS TO CALL BDOS ;80H. LD A,(FIRSTF) ;CHECK CP 0 ;FOR FIRST FILE. JR NZ,NOT1ST-$ LD DE,FCBNAME ;1ST FILE. LD HL,(FCBBSPT) ;COPY NAME LD BC,33 ;INTO LDIR ;STORAGE AREA. NOT1ST LD DE,(FCBBSPT) ;COPY NAME LD HL,FCBNAME ;INTO FCB. LD BC,33 LDIR LD A,0 ;ZERO FILE LD (FCOUNT),A ;COUNTER. LD DE,(FCBBSPT) LD C,17 CALL BDOS ;CPM SEARCH FOR FIRST FUNC. CP 255 JR Z,NMATCH-$ SLOOP PUSH AF LD A,(FIRSTF) ;SEE IF LD C,A ;THIS LD A,(FCOUNT) ;FILE CP C ;HAS ALREADY JR Z,GOTFILE-$ ;BEEN STORED. INC A ;YES, GO ON LD (FCOUNT),A ;TO SEARCH FOR POP AF ;NEXT LD C,18 ;FILE CALL BDOS ;CPM SEARCH FOR NEXT FUNC. CP 255 JP Z,RSET JR SLOOP-$ GOTFILE POP AF ;SEARCH WAS SUCCESSFUL ADD A ADD A ;A*32 POINTS ADD A ;TO LOCATION ADD A ;OF FCB IN ADD A ;DMA AREA. LD HL,80H LD D,0 LD E,A ADD HL,DE ;HL POINTS TO FCB AS READ INC HL ;FROM DISK. LD DE,(FCBBSPT) ;COPY NAME INC DE ;INTO NEW LD BC,11 ;FCB AREA. LDIR CALL OUTFCB ;PRINT FILE NAME. LD DE,MATCHED LD C,9 CALL BDOS LD A,(FIRSTF) ;INCREMENT SEARCH INC A ;POINTER. LD (FIRSTF),A JR OPEN-$ ;GO OPEN FILE. ; NMATCH LD DE,NOMATCH ;NO FILE MATCH. LD C,9 ;OUTPUT CALL BDOS ;ERROR MESSAGE. JP RSET ;GO BACK FOR MORE. ; ; OPEN LD DE,(FCBBSPT) ;OPEN FILE. LD C,15 CALL BDOS CP 255 ;CHECK STATUS OF OPEN JR NZ,FILEOK-$ LD DE,NOTOPN LD C,9 ;FILE NOT OPENED-OUTPUT CALL BDOS ;ERROR MESSAGE. JP RSET ;START OVER. ; FILEOK LD DE,(FCBBSPT) ;FILE OPENED SUCCESSFULLY. LD C,35 CALL BDOS ;CPM COMPUTE FILE SIZE FUNC. LD BC,(FCBBSPT) LD HL,34 ;COMPUTE RAM SPACE ADD HL,BC ;LEFT FOR FILES. PUSH HL POP BC LD HL,(BDOS+1) ;FBASE INTO HL OR A SBC HL,BC ;HL CONTAINS RAM SPACE IN BYTES LD C,H LD L,H ;CALCULATE # OF 128 BYTE SCTRS LD H,0 LD B,0 ADD HL,BC DEC HL ;LESS 128 BYTES FOR OVERHEAD. LD IX,(FCBBSPT) LD B,(IX+34) ;BC CONTAINS # LD C,(IX+33) ;RECORDS IN FILE. OR A SBC HL,BC ;COMPARE RAM SPACE WITH DISK JR NC,MEMOK-$ LD DE,SHRTMEM ;NOT ENOUGH MEMORY FOR FILE. LD C,9 CALL BDOS JP RSET ; MEMOK LD HL,(FCBBSPT) ;FORM POINTER TO LD DE,33 ;RECORD ADD HL,DE ;COUNTER. LD (RECNTPT),HL LD (HL),0 ;INITIALIZE COUNTER. INC HL LD (HL),0 INC HL ;NOW HL IS DMA POINTER. LD (DATAPT),HL ; GETREC LD DE,(DATAPT) ;START READ LOOP. LD C,26 ;SET DMA ADDRESS. CALL BDOS LD DE,(FCBBSPT) LD C,20 ;READ A CALL BDOS ;SECTOR. CP 0 ;END OF FILE? JR NZ,ENDFR-$ LD HL,(DATAPT) ;NOT EOF LD DE,128 ;INCREMENT ADD HL,DE ;DMA POINTER. LD (DATAPT),HL LD HL,(RECNTPT) ;INCREMENT LD D,(HL) ;RECORD INC HL ;COUNTER. LD E,(HL) INC DE LD (HL),E DEC HL LD (HL),D JR GETREC-$ ; ENDFR LD A,(NUMFILE) ;INCREMENT FILE INC A ;COUNTER. LD (NUMFILE),A LD HL,(DATAPT) ;CALCULATE LD (FCBBSPT),HL LD A,(AST) ;AS WE IN ASTERISK LOOP? CP 1 JP Z,STAR JP RSET ;NOT STAR LOOP- ;BACK FOR KEYBD INPUT. ; ; WRITEF LD C,29 CALL BDOS LD DE,WMSG LD C,9 CALL BDOS LD E,23H ;KEYBD PROMPT LD C,2 CALL BDOS LD C,1 CALL BDOS CP 3 ;CHECK FOR CNTL-C JP Z,BOOT CP 47H ;WAIT FOR CONSOLE INPUT OF JR Z,GORITE-$ ;G OR g BEFORE STARTING. CP 67H JR Z,GORITE-$ JR WRITEF-$ ;KEYBD ENTRY ERROR. ; GORITE LD DE,NLINE LD C,9 CALL BDOS LD HL,BUFSTRT ;STARTING FCB ADDR. LD (FCBBSPT),HL LD DE,(FCBBSPT) LD C,15 ;TRY TO OPEN A FILE CALL BDOS ;SOLE PURPOSE OF THIS ;IS TO FORCE CPM TO TEST ;FOR A DISK CHANGE. LD C,29 ;RETURN CALL BDOS ;R/O VECTOR. BIT 0,L ;BIT 0 OF L SET MEANS JR NZ,DRVOK-$ ;DISK HAS BEEN CHANGED. LD DE,DCHANGE ;CPM SAYS DISK HAS LD C,9 ;NOT BEEN CHANGED. CALL BDOS LD E,23H LD C,2 CALL BDOS ;KEYBD PROMPT LD C,1 ;LET USER OVERIDE CALL BDOS ;IF HE WANTS. CP 47H JR Z,DRVOK-$ CP 67H JR Z,DRVOK-$ JR WRITEF-$ ;ABORT IN NICK OF TIME- ;GO TRY ANOTHER DISK. DRVOK LD DE,NLINE LD C,9 CALL BDOS LD C,13 ;WRITE ENABLE DISK CALL BDOS FLOOP LD A,(NUMFILE) ;SEE IF MORE FILES TO RITE. CP 0 JP Z,DONE LD DE,(FCBBSPT) ;MORE FILES. LD C,19 ;DELETE PRESENT FILE IF CALL BDOS ;ALREADY ON DISK. ; LD HL,(FCBBSPT) ;CLEAR OUT NON-NAME PART LD DE,12 ADD HL,DE PUSH HL ;OF FCB POP DE INC DE LD (HL),0 LD BC,20 LDIR LD DE,(FCBBSPT) ;CREATE FILE. LD C,22 CALL BDOS CP 255 JR NZ,MAKEOK-$ LD DE,MAKEBAD ;ERROR IN FILE CREATION. LD C,9 CALL BDOS JP DONE ; MAKEOK CALL OUTFCB ;FILE CREATED SUCCESSFULLY LD DE,CREATED LD C,9 CALL BDOS ; LD HL,(FCBBSPT) ;CALCULATE LD DE,33 ;ADDRESS OF ADD HL,DE ;RECORD LD (RECNTPT),HL ;COUNTER. INC HL INC HL ;STARTING ADDR LD (DATAPT),HL ;OF DATA. ; RLOOP LD HL,(RECNTPT) ;SEE IF ALL RECORDS HAVE LD A,(HL) ;BEEN READ. CP 0 JR NZ,MOREREC-$ INC HL LD A,(HL) CP 0 JR NZ,MOREREC-$ LD DE,(FCBBSPT) ;NO MORE RECORDS IN LD C,16 ;THIS FILE. CLOSE FILE. CALL BDOS LD HL,(DATAPT) ;SET NEW FCB ADDR. LD (FCBBSPT),HL LD A,(NUMFILE) ;DECREMENT FILE COUNTER. DEC A LD (NUMFILE),A JR FLOOP-$ ; MOREREC LD DE,(DATAPT) ;SET DMA ADDR. LD C,26 CALL BDOS LD DE,(FCBBSPT) ;WRITE SECTOR. LD C,21 CALL BDOS CP 0 ;CHECK FOR DISK FULL. JR Z,RITEOK-$ LD DE,DISKFUL ;DISK IS FULL. LD C,9 CALL BDOS LD DE,(FCBBSPT) ;DELETE LAST FILE. LD C,19 CALL BDOS JP DONE ; RITEOK LD HL,(RECNTPT) ;DECREMENT LD D,(HL) ;RECORD INC HL ;COUNTER. LD E,(HL) DEC DE LD (HL),E DEC HL LD (HL),D LD HL,(DATAPT) ;INCREMENT DATA POINTER LD DE,128 ADD HL,DE LD (DATAPT),HL JP RLOOP ; DONE JP 0 ;DONE - TRY TO BOOT CPM ; ; ; ; OUTFCB LD HL,(FCBBSPT) ;TRANSFER FILE NAME INC HL LD DE,OUTBUF ;TO BUFFER. LD BC,8 LDIR INC DE ;SAME FOR FILE TYPE. LD BC,3 LDIR LD DE,OUTBUF LD C,9 CALL BDOS ;PRINT STRING RET ; ; DATA AREA ; AST DEFB 0 ;ASTERISK FLAG FIRSTF DEFB 0 ;FILE SEARCH POINTER. FCOUNT DEFB 0 ;FILE COUNTER IN SEARCH. FCBNAME DEFS 33 ;STORAGE FOR FILE NAME,TYPE. ; OUTBUF DEFB ' . IS $' MATCHED DEFB 'MATCHED' DEFW CRLF DEFB '$' CREATED DEFB 'CREATED' DEFW CRLF DEFB '$' ; SIGNON DEFW CRLF DEFB ' COPY ROUTINE FOR SINGLE DRIVE SYSTEMS' DEFW CRLF DEFB LF DEFB ' INSERT READ DISK ' DEFW CRLF DEFB '$' ; DEFS 32 ;LOCAL STACK AREA LSTACK EQU $ ; NOMATCH DEFB ' NO MATCH ' DEFW CRLF DEFB '$' ; NOTOPN DEFB ' FILE COULD NOT BE OPENED ' DEFW CRLF DEFB '$' ; SHRTMEM DEFB ' NOT ENOUGH MEMORY FOR FILE - TRY ANOTHER OR ' DEFB 'TYPE RETURN TO END' DEFW CRLF DEFB '$' WMSG DEFW CRLF DEFB ' LOAD IN WRITE DISK' DEFW CRLF DEFB ' WHEN READY TO GO, TYPE G ' DEFW CRLF DEFB '$' MAKEBAD DEFB ' COULD NOT CREATE FILE' DEFW CRLF DEFB '$' DISKFUL DEFB ' DISK FULL - FILE DELETED' DEFW CRLF DEFB '$' DCHANGE DEFW CRLF DEFB ' CPM SAYS DISK NOT CHANGED ' DEFW CRLF DEFB ' TO OVERIDE - TYPE G OR g ' DEFW CRLF DEFB ' TO ABORT - TYPE ANYTHING ELSE' NLINE DEFW CRLF DEFB '$' ; DATAPT DEFW BUFSTRT+35 RECNTPT DEFW BUFSTRT+33 NAMEPT DEFB 1 FCBBSPT DEFW BUFSTRT NUMFILE DEFB 0 BUFSTRT DEFB 0 ENDLAB END