home *** CD-ROM | disk | FTP | other *** search
- ;************************************************************************
- ; *
- ; 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
-