home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol073
/
icopy.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
9KB
|
456 lines
;************************************************************************
; *
; ISIS II TO CPM *
; FILE COPY UTILITY *
; *
; VERSION 2.2 *
; Modified by Rod Whitworth to allow nomination of the *
; drive & file of origin and destination. An input file *
; cannot reside on drive A: and a name must be given. *
; The output file defaults to A:nnnnnnnn.typ (named as *
; in the input). The output drive name is also optional *
; The original program also transferred only whole sectors *
; causing garbage to be placed on end of files: fixed now. *
;************************************************************************
cdisk equ 4 ;logged disk stored here
FALSE EQU 0
TRUE EQU NOT FALSE
LOGICAL EQU TRUE ;SET TRUE IF SECTORS INCREMENTED IN BIOS
ORG 100H
ICOPY: LXI SP,STACK ;SET STACK
LDA CDISK ;WHERE LOGGED
STA ODISK ;SAVED FOR LATER
LDA TFCB
ORA A
JZ EXIT ; NO FILE SPECIFIED
SUI 1
STA DRNUM ;INPUT DRIVE
MOV C,A ;SELECT DISK
LXI D,0 ;IN CASE NOT LOGGED IN
CALL SDSK
CALL VALID ;SEE IF IT'S OK FOR INPUT
CALL HOME ;HOME INPUT DISK
LDA OFCB+1 ;IS THERE A NAME
CPI 20H ;IF NOT IT'S A SPACE & WE CAN
LXI D,TFCB ;USE THE OLD NAME
JZ OTRAN ;BY JUMPING AROUND
LXI D,OFCB ;POINT TO OUTPUT DISK & NAME
OTRAN: LXI H,VFCB ;POINT TO OUR FCB
MVI B,16
CALL MOVE ;PUT IT SAFELY AWAY
LDA OFCB ;FIND THE REAL DESTINATION DISK
STA VFCB ;MAYBE REDUNDANT BUT SO WHAT ??
ORA A ;IS IT DEFAULT ?
JZ STDSK
SUI 1 ;OR DOES IT NEED ADJUSTMENT ?
STDSK: STA DESTN ;READY FOR SET-UP
XRA A
STA VFCB+32 ;SET CURRENT RECORD TO ZERO
LXI D,DIRLNK ;POINT TO DIR LINK BLOCK LINK
LXI H,DBCA ;DIR BCA
CALL GLB ;GET LINK BLOCK
ICL0: LXI H,DBCA ;DIR BCA
CALL GDB ;GET DIR BLOCK
JC NOTF ;NO MORE DIR BLOCKS, ERR
LXI H,DBUF ;DIR BUFFER
SHLD DENT ;SAVE IN POINTER
MVI A,8 ;NUMBER OF ENTRIES/BLOCK
STA DCNT ;SAVE
ICL1: LHLD DENT ;GET DIR ENTRY PTR
MOV A,M ;GET STATUS BYTE
CPI 00 ;ACTIVE?
JNZ ILN1 ;NO, GET NEXT ENTRY
INX H ;POINT TO FN
LXI D,TFCB+1 ;POINT TO ENTERED FN
MVI B,6 ;FN SIZE
CALL FCHK ;TEST FN
JNZ ILN1 ;NO, GET NEXT ENTRY
LHLD DENT ;GET DIR ENTRY ADDR
LXI D,7 ;OFFSET TO EXT.
DAD D ;ADDR OF EXT.
LXI D,TFCB+1+8 ;EXT
MVI B,3 ;SIZE OF EXT.
CALL FCHK ;TEST EXT
JZ ICL2 ;OK, FOUND FILE
ILN1: LHLD DENT ;POINTER TO ENTRY
LXI D,16 ;SIZE OF ENTRY
DAD D ;POINT TO NEXT ENTRY
SHLD DENT
LDA DCNT ;ENTRY COUNTER
DCR A ;DECREMENT
STA DCNT
JNZ ICL1 ;LOOP
JMP ICL0
NOTF: LXI D,MSG1
MVI C,09
CALL CPM
JMP EXIT
IOERR: LXI D,MSG2
MVI C,09
CALL CPM
JMP EXIT
ICL2: LHLD DENT ;GET DIR ENTRY ADDRESS
LXI D,11 ;OFFSET TO BYTE COUNT OF LAST BLOCK
DAD D
MOV A,M
STA LASTX ;# OF BYTES IN LAST TRANSFER
INX H ;POINT TO BLOCK COUNT
MOV E,M
INX H
MOV D,M ;BLOCK COUNT IN DE
XCHG
SHLD BCNT ;SAVE BLOCK COUNT
INX D ;POINT TO LINK BLOCK LINK
LXI H,FBCA ;FILE BCA
CALL GLB ;GET LINK BLOCK
LDA DESTN
MOV C,A ;OUTPUT DISK #
CALL SDSK ;SET DISK
LXI D,VFCB ;POINT TO FCB
MVI C,DELETE ;BYE TO ANY OLD ONE
CALL CPM
LXI D,VFCB
MVI C,CREATE
CALL CPM ;CREATE FILE
CPI 0FFH ;ERROR?
JZ IOERR
ICL3: LXI H,FBCA ;POINT TO BCA
CALL GDB ;GET DATA BLOCK
JC DONE ;FINS
LXI D,FBUF ;COPY FBUF TO TBUF
LXI H,TBUF
LDA XFERC ;TRANSFER SIZE
MOV B,A
CPI 128
CNZ FLAST ;FILL BUFF WITH EOF IF SHORT
CALL MOVE
LDA DESTN
MOV C,A
CALL SDSK ;SET DISK FOR OUTPUT
LXI D,VFCB
MVI C,WRITE
CALL CPM ;WRITE THE BLOCK ON CPM
ORA A
JNZ IOERR
LHLD BCNT ;GET BLOCK COUNT
DCX H ;DECREMENT
SHLD BCNT
MOV A,H
CPI 0 ;TEST FOR DONE
JNZ ICL3 ;NO, LOOP
MOV A,L
CPI 1
JZ CSWAP
CPI 0
JNZ ICL3
DONE: LDA DESTN
MOV C,A
CALL SDSK ;SET DISK FOR OUTPUT
LXI D,VFCB ;FCB
MVI C,CLOSE
CALL CPM
EXIT: LDA ODISK
MOV C,A
CALL SDSK ;FORCE LOGIN TO ORIGINAL DISK
JMP BOOT ;FINISHED
;***************************************;
;
; GLB - GET LINK BLOCK
;
; DE= A(LINK TO LINK BLOCK)
; HL= A(BLOCK CONTROL AREA)
;
;***************************************;
GLB: SHLD BCAP ;SAVE BCA ADDR
CALL SEEKR ;READ LINK BLOCK
LHLD BCAP ;GET BCA ADDR
LXI D,BCBL ;OFFSET TO LINK BUFFER
DAD D
LXI D,TBUF
MVI B,128
CALL MOVE ;COPY TO LINK BUFFER
LHLD BCAP ;GET BCA ADDR
LXI D,BCBL+4 ;OFFSET TO FIRST DATA LINK
XCHG
DAD D ;DE=A(FIRST DATA LINK)
XCHG
LXI B,BCAL ;OFFSET TO LINK PTR
DAD B
MOV M,E
INX H
MOV M,D ;SET LINK PTR
LHLD BCAP ;BCA ADDR
LXI D,BCALC ;LINK COUNT
DAD D
MVI M,62 ;NO OF LINKS
RET
;****************************************:
;
; GDB: GET DATA BLOCK
;
; HL= A(BLOCK CONTROL AREA)
;
;****************************************;
GDB: SHLD BCAP ;SAVE BCA ADDR
LXI D,BCAL ;OFFSET TO LINK BUF
DAD D
MOV E,M
INX H
MOV D,M ;GET LINK ADDR
PUSH D ;SAVE LINK ADDR
LDAX D ;GET LINK BYTE
INX D
MOV C,A
LDAX D ;GET ANOTHER LINK BYTE
ORA C ;TEST FOR ZERO LINK
POP D
JZ GDBE ;END, EXIT
PUSH D ;SAVE D AGAIN
PUSH H
CALL SEEKR ;GET DATA BLOCK
POP H
POP D
INX D
INX D
MOV M,D
DCX H
MOV M,E ;UPDATE LINK PRT
LHLD BCAP ;GET BCA ADDR
LXI D,BCBD ;OFFSET TO DATA BUF
DAD D
LXI D,TBUF
MVI B,128
CALL MOVE ;COPY DATA TO BUF
LHLD BCAP ;GET BCA ADDR
LXI D,BCALC ;LINK COUNT
DAD D
DCR M ;DECREMENT
RNZ ;OK, CONTINUE
LHLD BCAP ;GET BCA ADDR
LXI D,BCBL+2 ;POINT TO LINK BUF
DAD D
MOV E,M ;GET LINK
INX H
MOV D,M
DCX H
MOV E,A
ORA D ;TEST FOR ZERO LINK
JZ GDBE ;END, EXIT
XCHG ;DE = A(NEXT LINK)
LHLD BCAP ;BCA ADDR
CALL GLB ;GET LINK BLOCK
RET
GDBE: STC ;INDICATE EOF
RET
;************************************;
;
; FCHK: FILE ID CHECK
;
; DE = A(ISIS FILE ID)
; HL = A(CPM FILE ID)
; B = SIZE OF FIELD
;
;*************************************;
FCHK: XCHG
FCK1: LDAX D ;GET BYTE
CPI 00 ;SEE IF END OF ID
JNZ FCK2 ;YES, SEE IF END OK
MOV A,M ;GET BYTE
CPI ' ' ;END BOTH
RZ ;DONE
ORA 1
RET ;DONE
FCK2: CMP M ;COMPARE
RNZ ;N,G.
INX D
INX H
DCR B ;DECREMENT COUNT
JNZ FCK1
RET
;***************************************;
;
; SEEKR: SEEK DISK BLOCK
;
; DE = A(LINK)
;
;***************************************;
SEEKR: PUSH D ;SAVE DE
LDA DRNUM
MOV C,A
LXI D,1 ;WE'VE BEEN HERE BEFORE
CALL SDSK
POP D
PUSH D
LDAX D ;GET SECTOR
MOV C,A
CALL SSEC ;SET SECTOR
POP D
PUSH D
INX D
LDAX D ;GET TRACK
MOV C,A
CALL STRK
CALL READ ;READ BLOCK
POP D
RET
;************************************************
; *
; FLAST: SET UP BUFFER FOR LAST BLOCK *
; INITIALISE TO 1AH (CP/M EOF) *
; PRIOR TO TRANSFER OF REAL DATA *
; *
;************************************************
FLAST:
PUSH H
LXI H,TBUF
MVI A,128
EOFL: MVI M,01AH
INX H
DCR A
JNZ EOFL
POP H
RET
CSWAP: ;DOES THE COUNT CORRECTION FOR
;THE LAST BLOCK
LDA LASTX
STA XFERC
JMP ICL3
;*****************************************;
;
; MOVE: MOVE DATA
;
; DE = A (SOURCE)
; HL = A(DEST)
; B = COUNT
;
;******************************************;
MOVE: LDAX D ;GET BYTE
MOV M,A ;STORE BYTE
INX H
INX D ;BUMP PTRS
DCR B ;DECREMENT COUNT
JNZ MOVE
RET
;*******************************************;
;
; CPM INTERFACE ROUTINES
;
;*******************************************;
VALID: ;CHECKS DPB TO SEE IF SS/SD FLOPPY AND EXIT IF NOT
;HL = 0 IF NOT SELECTABLE ELSE -> DPH ADDR
MOV A,H
ORA L
JZ DONE ;GO TO CPM
LXI D,10
DAD D
MOV A,M
INX H
MOV H,M
MOV L,A ;HL -> DPB
MOV A,M
CPI 26
JNZ DONE ;IF NOT 26 SPT
INX H
MOV A,M
ORA A
JNZ DONE ;HIGH BYTE OF SPT
LXI D,4
DAD D
MOV A,M
CPI 242 ;SINGLE DENSITY DSM
JNZ DONE
RET ;PRETTY GOOD CHANCE IT'S OK NOW
SDSK: LHLD 0001H ;GET BIOS ADDR
MVI L,1BH
PCHL
SSEC: LHLD 0001H
MVI L,21H
IF LOGICAL ;USED TO REDUCE THE SECTOR #
DCR C ;IF THE BIOS INCREMENTS IT
ENDIF ;TO 'CORRECT' LOGICAL TO PHYSICAL
PCHL
STRK: LHLD 0001H
MVI L,1EH
PCHL
READ: LHLD 0001H
MVI L,27H
PCHL
HOME: LHLD 0001H
MVI L,18H
PCHL
;******************************************;
;
; BLOCK CONTROL AREA DEFINITIONS
;
;******************************************;
BCA EQU 0
BCAL EQU 0
BCALC EQU BCAL+2
BCBL EQU BCALC+1
BCBD EQU BCBL+128
;******************************************;
;
; DATA
;
;******************************************;
MSG1: DB 'FILE NOT FOUND',0DH,0AH,'$'
MSG2: DB 'I/O ERROR',0DH,0AH,'$'
XFERC: DB 128 ;INITIAL BLOCK SIZE MODIFIED FOR LAST
LASTX: DS 1 ;BYTE COUNT OF LAST RECORD
DRNUM DS 1 ;INPUT DRIVE
DESTN DS 1 ;OUTPUT DRIVE
ODISK DB 0 ;PROBLY A:
DIRLNK: DB 01,01
DENT: DS 2
DCNT: DS 1
BCNT: DS 2
BCAP: DS 2
DS 64
STACK EQU $
DBCA: DS 2
DS 1
DS 128
DBUF: DS 128
FBCA: DS 2
DS 1
DS 128
FBUF: DS 128
VFCB DS 36
TBUF EQU 0080H
TFCB EQU 005CH
OFCB EQU 006CH ;OUTPUT FILE DRIVE AND [NAME]
CPM EQU 0005H
BOOT EQU 0000H
CREATE EQU 22
WRITE EQU 21
CLOSE EQU 16
DELETE EQU 19
END