; ; MOVE.ASM ; V2.1 ; (revised 6/12/80) ; ;USED TO TRANSFER FILES FROM ONE DISK TO ANOTHER ;ON A 1 DISK SYSTEM, BY READING THE FILE INTO MEMORY. ;ISSUES ERROR MSG IF FILE WON'T FIT. ALSO USEFUL FOR ;TRANSFERRING ONE FILE TO MULTIPLE DISKS. WORKS WITH ;ANY DRIVE - A, B, C, OR D. ; ;*************************************************** ;* NOTE: CHECK COMMENTS AT LABEL 'EXIT:' REGARDING * ;* REBOOT WHEN EXITING THIS PROGRAM. * ;*************************************************** ; ;07/23/78 ORIGINALLY WRITTEN BY WARD CHRISTENSEN ;10/20/78 MODIFY TO WRITE MULTIPLE TIMES ; (FOR EXAMPLE TO MOVE STAT.COM TO 5 NEW DISKS) ;02/24/79 MODIFY TO STORE TO EITHER A: OR B:, AS ; MOVE IS MUCH QUICKER THAN PIP FOR PEOPLE ; WITH 2 DRIVE SYSTEMS. ;05/27/79 MODIFY TO CHECK FOR NO FILE NAME AND TO ; ZERO OUT DISK NAME SO IT WON'T OVERULE THIS ; PROGRAM. BY KEITH PETERSEN, W8SDZ. ;08/19/79 REMOVE MACROS TO ALLOW ASSEMBLY WITH ; ASM.COM. ADD CONDITIONAL ASSEMBLY FOR CP/M ; ON H8 OR TRS-80. (KBP) ;08/20/79 FIX TEST TO PROTECT BDOS (WAS WRONG WHEN ; ALTCPM OPTION CHOSEN). (KBP). ;11/27/79 FIX DMA PROBLEM FOR MULTIPLE WRITES. ; ELIMINATE EXTRA PUSH-POPS. (KBP). ;12/04/79 FIX ERROR IN RESETTING DMA TO NORMAL ; (Thanks to Ward Christensen) (KBP) ;04/20/80 MODIFIED TO WORK WITH EITHER CP/M 1.4 OR CP/M-2. ; EARLIER VERSION COPIED FILE ATTRIBUTES WHICH PREVENTED ; MOVING R/O FILES AND MADE CP/M-2 FILES INACCESSABLE ; UNDER 1.4. (KBP) ;06/12/80 MODIFIED TO REMOVE ATTRIBUTES ON ALL 11 CHARACTERS ; OF FCB NAME. (KBP) ; STDCPM EQU 1 ;TRUE FOR STANDARD CP/M ALTCPM EQU 0 ;TRUE FOR H8 OR TRS-80 ; BASE SET 0 ; IF ALTCPM ;H8 OR TRS-80 BASE SET 4200H ENDIF ;ALTCPM ; CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED ; ORG BASE+100H ; START LDA FCB+1 ;SEE IF FILE NAME THERE CPI ' ' ;NONE? RZ ;IF NONE, RETURN TO CP/M LXI SP,STACK XRA A ;ZERO DISK NAME SO IT WON'T STA FCB ;OVERULE COMMANDS IN THIS PGM. CALL ILPRT DB 'MOVE.COM V2.1, 6/12/80' DB CR,LF,0 ; SRCMSG CALL ILPRT DB 'MOUNT SOURCE DISK, TYPE: A, B, C, OR D ',0 CALL GETDISK ;GET DISK NAME JC SRCMSG ;INVALID ANSWER, ASK AGAIN ; ;GOT DISK, OPEN THE INPUT FILE ; LXI D,FCB MVI C,OPEN CALL BDOS INR A ;WAS THE OPEN OK? JNZ OPENOK ;YES ; ;OPEN WAS BAD, EXIT WITH ERROR MESSAGE. ; CALL ERXIT DB '++NO SUCH FILE++',CR,LF,'$' ; OPENOK LXI D,BUFF ;POINT TO BUFFER READLP PUSH D ;SAVE BUFFER ADDRESS MVI C,STDMA CALL BDOS ;READ A SECTOR LXI D,FCB MVI C,READ CALL BDOS POP D ;GET DMA ADDR ORA A ;OK? JNZ EOF ;NOT OK, MUST BE EOF LHLD FCT ;LOAD SECTOR COUNT FOR FILE INX H ;BUMP IT SHLD FCT ;SAVE IT BACK LXI H,80H ;LENGTH OF 1 SECT. DAD D ;CALC NEXT BUFF ADDR XCHG ;PUT IT BACK IN DE ;OUT OF MEMORY? LDA BASE+7 ;GET BDOS PAGE POINTER SUI 2 ;MAKE SURE CMP D ;ABOUT TO HIT BDOS? JNC READLP ;NO, LOOP ; ;FILE IS TOO BIG - EXIT PRINTING ERROR MSG. ; CALL ERXIT DB '++FILE WON''T FIT IN MEMORY++$' ; ;GOT RETURN CODE ON READ, SEE IF ERROR OR EOF ; EOF LHLD FCT ;GET SECTOR COUNT SHLD SAVEFCT ;SAVE IT FOR MULTIPLE WRITES ;A HAS RETURN CODE FROM READ DCR A ;EOF? JZ DESTMSG ;YES, ASK FOR DEST. DISK ; ;READ ERROR - EXIT WITH MSG ; CALL ERXIT DB '++READ ERROR++$' ; ;FILE READ INTO MEMORY. ASK FOR DEST. DISK ; DESTMSG LXI D,BASE+80H ;RESET DMA TO NORMAL MVI C,STDMA CALL BDOS CALL ILPRT DB 'C/R TO END, ',CR,LF DB 'MOUNT DEST. DISK, TYPE: A, B, C, OR D ',0 CALL GETDISK ;GET A OR B JC DESTMSG ;NEITHER, ASK AGAIN LHLD SAVEFCT ;GET SAVED COUNT SHLD FCT ;SAVE FOR DECREMENT ; ;INIT FOR WRITING THE FILE ; XRA A STA FCBEXT ;ZERO EXTENT # STA FCBSNO ;ZERO SECTOR # ; ;REMOVE ALL FILE ATTRIBUTES LXI H,FCB+1 ;POINT TO FILE NAME.TYPE MVI B,11 ;NUMBER OF CHARACTERS ; ZFCBLP MOV A,M ;GET CHAR ANI 7FH ;ZERO OUT ATTRIBUTE MOV M,A ;RESTORE CHAR TO FCB INX H DCR B ;ONE LESS CHARACTER JNZ ZFCBLP ; ;ERASE ANY FILE BY SAME NAME LXI D,FCB MVI C,ERASE CALL BDOS ; ;MAKE THE FILE LXI D,FCB MVI C,MAKE CALL BDOS INR A JZ BADMAKE ;MAYBE DIRECTORY IS FULL? ; ;WRITE THE FILE TO DISK ; LXI H,BUFF ;POINT TO BUFFER SHLD BUFPTR WRLP LHLD BUFPTR LXI D,BASE+80H CALL MOVE128 SHLD BUFPTR ;SAVE THE NEW BUF ADDR ;WRITE THE SECTOR LXI D,FCB MVI C,WRITE CALL BDOS ORA A ;WAS THE WRITE SUCCESSFUL? JNZ WRERR ;NO, EXIT W/ERROR MSG LHLD FCT ;GET FILE'S SECTOR COUNT DCX H ;DECREMENT IT SHLD FCT ;SAVE IT BACK MOV A,H ORA L ;ZERO? JNZ WRLP ;NO, LOOP ;CLOSE THE FILE LXI D,FCB MVI C,CLOSE CALL BDOS CALL ILPRT ;PRINT THE FOLLOWING: DB '++DONE++',CR,LF,0 JMP DESTMSG ; ;GOT A WRITE ERROR - EXIT W/ERROR MSG. ; WRERR CALL ERXIT DB '++WRITE ERROR$' ; ;COULDN'T MAKE THE FILE, EXIT W/ERROR MSG. ; BADMAKE CALL ERXIT DB '++CAN''T MAKE OUTPUT FILE$' ; ;INLINE PRINT ROUTINE - CALL ILPRT FOLLOWED ; BY MESSAGE (ENDING IN 0) ; ILPRT MVI A,CR ;CR.. CALL TYPE MVI A,LF ;LF FIRST. CALL TYPE XTHL ;SAVE HL, GET MSG ADDR ; ILPLP MOV A,M ;GET CHAR OF MSG CALL TYPE ;TYPE IT INX H ;POINT TO NEXT CHAR MOV A,M ;GET IT ORA A ;IS IT END OF MSG? JNZ ILPLP ;NO, LOOP INX H ;SKIP THE 0 XTHL ;RESTORE HL, STACK RET ADDR RET ;..AND RETURN ; ;TYPE CHAR IN A ; TYPE PUSH B PUSH D PUSH H MOV E,A ;FOR TYPE MVI C,WRCON CALL BDOS POP H POP D POP B RET ; ;EXIT WITH ERROR MESSAGE ; ERXIT MVI A,CR CALL TYPE MVI A,LF CALL TYPE POP D ;GET MSG ADDR MVI C,PRINT CALL BDOS ; ;EXIT: ASSUMES DISK IN A: MAY NOW BE DIFFERENT ;SYSTEM SIZE, SO WARM BOOT WOULD NOT WORK. ;JUMPS TO COLD BOOT EPROM ENTRY POINT. ;IF SUCH AN ENTRY POINT IS NOT AVAILABLE, ;CHANGE TO JMP 0000. THIS WILL WORK IF YOU ;ARE WARM-BOOTING THE SAME SIZED SYSTEM AS ;BEFORE. ; EXIT CALL ILPRT DB CR,LF,'RE-BOOTING ' DB 'VIA "JMP 0000", ' ;<------ DB 'PRESS RETURN',0 MVI C,RDCON CALL BDOS ;GET CHAR. CPI CR ;C/R? JNZ EXIT JMP 00000H ;COLD BOOT ROM ADDRESS <------ ; (CHANGED TO WARM BOOT) ;MOVE 128 CHARACTERS ; MOVE128 MVI B,128 ;SET MOVE COUNT ; ;MOVE FROM (HL) TO (DE) LENGTH IN (B) ; MOVE MOV A,M ;GET A CHAR STAX D ;STORE IT INX H ;TO NEXT "FROM" INX D ;TO NEXT "TO" DCR B ;MORE? JNZ MOVE ;..YES, LOOP RET ;..NO, RETURN ; ;ROUTINE TO GET DISK NUMBER (A, B, C, D) THEN ;RESET THE DISK AND LOG IN THAT DISK. ; GETDISK MVI C,RDCON CALL BDOS ;GET CHAR. CPI CR ;JUST RETURN? JZ EXIT ;YES, ALL DONE PUSH PSW ;SAVE CHAR ;RESET DISK, KILLING R/O STATUS MVI C,RESETDK CALL BDOS POP PSW ;GET DISK ANI 5FH ;MAKE UPPER CASE SUI 'A' ;CALC DISK MOV E,A ;SETUP FOR SELECT CPI 4 ;A-D? CMC ;CY ON = BAD RC ;ERROR RETURN ;LOG IN THE APPROPRIATE DISK SELDISK MVI C,SELDK CALL BDOS ORA A ;SHOW NO ERROR RET ; FCT DW 0 ;FILE COUNT SAVEFCT DW 0 ;SAVED FILE COUNT BUFPTR DS 2 ;BUFFER POINTER FOR WRITE ; DS 64 ;STACK AREA STACK EQU $ BUFF EQU $ ; ;BDOS/CBIOS EQUATES ; RDCON EQU 1 WRCON EQU 2 PRINT EQU 9 RESETDK EQU 13 SELDK EQU 14 OPEN EQU 15 CLOSE EQU 16 ERASE EQU 19 READ EQU 20 WRITE EQU 21 MAKE EQU 22 STDMA EQU 26 BDOS EQU BASE+5 FCB EQU BASE+5CH FCBEXT EQU FCB+12 FCBSNO EQU FCB+32 ; END