home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
UTILS
/
FILCPY
/
MOVE.ASM
< prev
next >
Wrap
Assembly Source File
|
2000-06-30
|
7KB
|
331 lines
;
; 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 FC00", ' ;<------
DB 'PRESS RETURN',0
MVI C,RDCON
CALL BDOS ;GET CHAR.
CPI CR ;C/R?
JNZ EXIT
JMP 0FC00H ;COLD BOOT ROM ADDRESS <------
;
;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