;**************************************** ; ; ISIS II TO CPM ; FILE COPY UTILITY ; ; VERSION 1.1 ; MODIFIED VERSION ; ORIGINAL WOULD NOT COPY A FILE LONGER THAN 16K ; BECAUSE OF IMPROPERLY SETTING THE LINKS ; THIS VERSION HAS BEEN TESTED ON LARGER THAN 16K ; FILES AND SHOULD WORK WITH ANY SIZE FILE BUT HAS ; NOT BEEN TESTED ON FILES > 48K. ; ;**************************************** ORG 100H ICOPY: LXI SP,STACK ;SET STACK MVI C,1 ;SELECT DISK 1 CALL SDSK CALL HOME ;HOME DISK 1 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 EXIT: MVI C,0 CALL SDSK ;SET DISK 0 JMP BOOT ICL2: LHLD DENT ;GET DIR ENTRY ADDRESS LXI D,12 ;OFFSET TO COUNT DAD D 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 MVI C,0 CALL SDSK ;SET DISK A LXI D,TFCB ;POINT TO FCB 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 MVI B,128 CALL MOVE MVI C,0 CALL SDSK ;SET DISK A LXI D,TFCB 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 ORA L ;TEST FOR DONE JNZ ICL3 ;NO, LOOP DONE: MVI C,0 CALL SDSK ;SET DISK A LXI D,TFCB ;FCB MVI C,CLOSE CALL CPM 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 A,E ORA D ;TEST FOR ZERO LINK JZ GDBE2 ;END, EXIT XCHG ;DE = A(NEXT LINK) LHLD BCAP ;BCA ADDR CALL GLB ;GET LINK BLOCK RET GDBE: STC ;INDICATE EOF RET GDBE2: LXI D,FBUF ;COPY FBUF TO TBUF LXI H,TBUF MVI B,128 CALL MOVE MVI C,0 CALL SDSK ;SET DISK A LXI D,TFCB MVI C,WRITE CALL CPM ORA A JNZ IOERR JMP GDBE ; ;**************************************; ; 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 MVI C,1 ;SET DISK B 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 ;*****************************************; ; ; 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 ; ;*******************************************; SDSK: LHLD 0001H ;GET BIOS ADDR MVI L,1BH PCHL SSEC: LHLD 0001H MVI L,21H 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,'$' 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 TBUF EQU 0080H TFCB EQU 005CH CPM EQU 0005H BOOT EQU 0000H CREATE EQU 22 WRITE EQU 21 CLOSE EQU 16 END