home *** CD-ROM | disk | FTP | other *** search
- ; 10/12/79: 1055
- ; P.P.H. LEE,
- ; ROYAL MELBOURNE INSTITUTE OF TECHNOLOGY,
- ; APPLIED PHYSICS DEPARTMENT,
- ; 124 LATROBE STREET, MELBOURNE,
- ; VICTORIA 3000, AUSTRALIA.
-
- ; PROGRAM TO TRANSFER A CP/M FILE IN DRIVE A: TO AN
- ; ICOM FDOS II DISK ON DRIVE B:
- ; TO USE THE PROGRAM, TYPE CPM-FDOS NFN, WHERE NFN IS AN
- ; EXISTING CP/M FILE THAT IS TO BE TRANSFERED TO THE FDOS
- ; DISKETE ON DRIVE B:. THE PROGRAM WILL ASK FOR THE NEW
- ; FDOS FILENAME, WHICH MUST BE 5 CHRACTERS LONG MAXIMUM,
- ; WITHOUT DRIVE NUMBER (IT ASSUMES DRIVE #1 ALLWAYS),
- ; FOLLOWED BY A <CR>.
- ; AT THE COMPLETION OF THE TRANSFER, IT WILL REBOOT BACK
- ; TO CP/M.
- ; WARNING: AN FDOS II INITIALIZED DISKETTE MUST BE IN
- ; DRIVE B:.
- ; ALSO THIS PROGRAM DOES NOT CHECK FOR DUPLICATE
- ; FILENAMES.
-
- ; EXTERNAL LINKAGES:
- BDOS EQU 5 ; CP/M BDOS VECTOR
- BOOT EQU 0 ; CP/M WARM BOOT
- PBUF EQU 9 ; CP/M PRINT BUFFER CODE
- RDBUF EQU 10 ; CP/M READ BUFFER CODE
- DRSEL EQU 14 ; CP/M DRIVE SELECT CODE
- OPEN EQU 15 ; CP/M OPEN FILE CODE
- READ EQU 20 ; CP/M READ NEXT SECTOR CODE
- STDMA EQU 26 ; CP/M SET DMA ADDRESS CODE
- TFCB EQU 5CH ; CP/M DEFAULT FCB ADDRESS
- ISIZE EQU 0C434H ; FDOS II INPUT FILE SIZE
- ITRK EQU 0C436H ; FDOS II INPUT TRAK NUMBER
- ISCTR EQU 0C437H ; FDOS II INPUT SECTOR NUMBER
- ICNTR EQU 0C438H ; FDOS II INPUT COUNTER
- OUNIT EQU 0C432H ; FDOS II OUTPUT DRIVE NO.
- OSIZE EQU 0C439H ; FDOS II OUTPUT FILE SIZE
- OTRK EQU 0C43BH ; FDOS II OUTPUT TRAK NUMBER
- OSCTR EQU 0C43CH ; FDOS II OUTPUT SECTOR NUMBER
- OCNTR EQU 0C43DH ; FDOS II OUTPUT COUNTER
- FREAD EQU 0C033H ; FDOS II READ BYTE
- FWRT EQU 0C036H ; FDOS II WRITE BYTE INTO FILE
- RSTRV EQU 0C030H ; FDOS II RESTORE INPUT POINTERS
-
- ORG 100H ; SET TO BASE OF TPA
-
- LXI SP,STACK ; SET STACK POINTER
- LXI D,AFLNM ; ASK FOR FDOS FILENAME
- MVI C,PBUF
- CALL BDOS
- LXI H,TBUF ; GET FDOS FILENAME
- LXI B,0620H ; INTO OFLNM
- MOV M,B ; BUT FIRST SET LENGHT
- INX H ; AND CLEAR IT
- FNAME: MOV M,C ; WITH SPACES
- INX H
- DCR B
- JNZ FNAME
- LXI D,TBUF ; NOW GET IT
- MVI C,RDBUF ; USING BDOS
- CALL BDOS ; READ BUFFER
- MVI A,1 ; SET FDOS II OUTPUT
- STA OUNIT ; TO DRIVE #1(B:)
- CALL OPFLS ; OPEN FDOS FILE
- ORA A ; OK?
- JNZ FULL ; BRIF NOT
- LXI D,TFCB ; OPEN CP/M FILE
- MVI C,OPEN
- CALL BDOS
- CPI 0FFH ; CHECK FOR ERROR
- JNZ GET ; BRIF NO ERROR
- LXI D,ERMSG ; ELSE PRINT ERROR MESSAGE
- MVI C,PBUF
- CALL BDOS
- JMP BOOT ; AND REBOOT
- GET: LXI H,TBUF-128 ; GET BUFFER ADDRESS
- MVI A,128 ; SET BUFFER SIZE TO 128 SECTORS
- GET1: STA TBCNT ; SAVE IT IN BUFFER COUNT
- LXI D,128 ; CALCULATE NEXT DMA ADDRESS
- DAD D
- SHLD TBDMA ; SAVE IT
- XCHG ; PUT IN DE
- MVI C,STDMA ; AND SET IT
- CALL BDOS
- LXI D,TFCB ; SET ADDRESS OF FCB
- MVI C,READ ; READ A SECTOR TO BUFFER
- CALL BDOS
- ORA A ; CHECK FOR E-O-F
- JNZ GET2 ; BRIF IS
- LHLD TBDMA ; GET LAST DMA ADDRESS
- LDA TBCNT ; GET SECTOR COUNT
- DCR A ; SUBTACT ONE
- JNZ GET1 ; BRIF NOT FINISHED
- LXI H,TBUF+(128*128) ; SET END OF BUFFER
- SHLD TBDMA ; ADDRESS
- JMP LOAD
- GET2: MVI A,0FFH ; SET TB FLAG
- STA TBFLG
- LOAD: LHLD TBDMA ; GET END OF BUFFER ADDRESS
- XCHG ; TO DE
- LXI H,TBUF ; GET START OF BUFFER TO HL
- LOAD1: MOV A,H ; CHECK IF
- CMP D ; END OF
- JNZ LOAD2
- MOV A,L ; BUFFER HAS BEEN
- CMP E ; REACHED
- JZ LOAD3 ; BRIF IS
- LOAD2: MOV C,M ; GET BYTE FROM BUFFER
- CALL FWRT ; WRITE IT TO FDOS FILE
- INX H ; POINT NEXT
- JMP LOAD1
- LOAD3: LDA TBFLG ; GET FLAG
- ORA A ; CHECK IT
- JZ GET ; GET NEXT LOAD IF SOME MORE
- CALL CLFLS ; ELSE CLOSE FDOS FILE
- JMP BOOT ; AND REBOOT CP/M
-
- FULL: LXI D,DSKFL ; PRINT ERROR MESSAGE
- MVI C,PBUF
- CALL BDOS
- JMP BOOT ; AND REBOOT CP/M
-
- ; MESSAGES:
- AFLNM: DB 'FDOS II NEW FILENAME: $'
- ERMSG: DB '* NO SUCH CP/M FILE *',0DH,0AH,'$'
- DSKFL: DB '* FDOS II DISK FULL *',0DH,0AH,'$'
-
- ; SUBROUTINE TO SET ITRK, ISCTR, ISIZE & ICNTR READY TO
- ; START READING THE DIRECTORY TRAK OF AN FDOS II
- ; DISKETTE.
-
- INDEX: LXI H,24 ; 23 SECTORS
- SHLD ISIZE ; STORE IN ISIZE
- LXI H,ITRK ; POINT TO ITRK
- MVI M,0 ; TRAK # 0
- INX H
- LDA OUNIT ; GET OUTPUT DRIVE NO.
- INDX2: RRC ; ROTATE TO 2 MSB
- RRC
- ORI 03H ; INCORPORATE SECTOR # 3
- MOV M,A ; LOAD ISCTR
- INX H ; POINT TO ICNTR
- MVI M,0 ; RESET ICNTR
- RET
-
- ; SUBROUTINE TO FIND THE END OF DIRECTORY MARK IN THE
- ; DIRECTORY TRACK OF THE DISKETTE.
- ; RETURNS WITH ISCTR, OSCTR, ITRK, OTRK, ISIZE & OSIZE
- ; POINTING TO THE START OF THE FCB THAT CONTAINS THE
- ; EOD MARK.
-
- EOD: CALL CLEAR ; CLEAR INPUT BUFFER
- XRA A ; SET FLAG TO OUTPUT
- STA OTRK ; SET OTRK TO INDEX
- CALL INDEX
- EOD1: MVI D,11 ; SET 11 FCB
- EOD2: MVI E,5 ; SKIP FILENAME
- CALL SKIPR
- CALL FREAD ; GET ATTRIBUTE
- CPI 0FFH ; EOD?
- JZ EOD3 ; BRIF IS
- MVI E,5 ; SKIP REST OF FCB
- CALL SKIPR
- DCR D ; DECREMENT FCB COUNT
- JNZ EOD2 ; BRIF STILL SOME MORE IN SECTOR
- MVI E,7 ; ELSE SKIP 7 BYTE TAIL
- CALL SKIPR
- JMP EOD1
- EOD3: CALL CLEAR ; CLEAR INPUT BUFFER
- LDA ISCTR ; DECREMENT SECTOR NUMBER
- STA OSCTR ; SET OSCTR
- DCR A
- STA ISCTR
- LHLD ISIZE ; INCREMENT SIZE
- INX H
- SHLD ISIZE ; AND REPLACE
- SHLD OSIZE ; SET OSIZE
- MVI A,11 ; COMPUTE FCB NUMBER
- SUB D
- MOV D,A ; SAVE RESULT IN D
- RZ ; RIF FIRST FCB ON SECTOR
- EOD4: MVI E,11 ; ELSE SKIP R/W TO IT
- CALL SKIPW
- DCR D
- JNZ EOD4 ; LOOP UNTIL THERE
- RET
-
- ; SUBROUTINE TO SKIP READING N NUMBER OF BYTES,
- ; WHERE N IS IN E REGISTER.
-
- SKIPR: CALL FREAD
- DCR E
- JNZ SKIPR
- RET
-
- ; SUBROUTINE TO READ & WRITE BACK N NUMBER OF BYTES,
- ; WHERE N IS IN E REGISTER.
-
- SKIPW: PUSH B ; SAVE BC
- SKPW1: CALL FREAD ; READ BYTE
- MOV C,A ; AND WRITE OUT
- CALL FWRT
- DCR E ; DECREMENT COUNT
- JNZ SKPW1
- POP B ; RESTORE BC
- RET
-
- ; SUBROUTINE TO CLEAR THE INPUT BUFFER
- CLEAR: LDA ICNTR ; GET ICNTR
- ORA A ; TEST IT
- RZ ; RET IF EMPTY
- CALL FREAD ; DUMMY READ
- JMP CLEAR ; LOOP
-
-
- ; SUBROUTINE TO FIND THE END OF DIRECTORY FILE CONTROL
- ; BLOCK IN THE DIRECTORY TRACK OF THE DISKETTE, GET THE
- ; NEW FILE STARTING ADDRESS AND COMPUTE ITS MAXIMUM SIZE.
- ; IT WILL THEN LOAD THE FILENAME, ADDRESS AND MAXIMUM
- ; SIZE INTO THE FCB, LEAVING THE EOD MARK WHERE
- ; IT IS. THE ADDRESS AND MAXIMUM SIZE WILL ALSO BE
- ; LOADED INTO OTRK, OSCTR, OSIZE AND OCNTR RESET TO ZERO.
- ; EXPECTS FILENAME & DRIVE NUMBER IN OFLNM & OUNIT.
- ; REGISTERS USED: ALL
-
- OPFLS: XRA A ; RESET OCNTR
- STA OCNTR
- CALL EOD ; FIND END OF DIRECTORY FCB
- MVI E,6 ; SKIP READ FILENAME & EOD MARK
- CALL SKIPR
- MVI E,5 ; WRITE FILENAME ONTO FCB
- LXI H,OFLNM
- OPFL2: MOV C,M ; GET CHARACTER
- CALL FWRT
- INX H ; POINT NEXT
- DCR E
- JNZ OPFL2 ; LOOP UNTIL ALL DONE
- MVI C,0FFH ; REPLACE EOD MARK
- CALL FWRT
- CALL FREAD ; GET TRACK NUMBER
- MOV B,A ; SAVE IT IN B
- MOV C,A ; AND REPLACE
- CALL FWRT
- CALL FREAD ; GET SECTOR NUMBER
- MOV C,A ; SAVE IT IN C
- PUSH B ; SAVE BOTH IN STACK
- CALL FWRT ; AND REPLACE SECTOR NUMBER
- CALL FREAD ; SKIP READ
- CALL FREAD ; THE SIZE
- POP B ; RETRIEVE ADDRESS FROM STACK
- PUSH B ; AND RESAVE IT
- LXI H,2000 ; TOTAL SIZE + 1 - 3
- DCR C ; SECTOR NUMBER START FROM 1
- MOV A,C ; SUBTRACT SECTOR NUMBER
- CMA
- MOV E,A
- MVI D,0FFH ; BY GETTING IT'S 2'S COMPLEMENT
- INX D ; IN DE
- DAD D ; AND DOUBLE ADD WITH HL
- LXI D,-26 ; NOW SUBTRACT THE TRACKS
- OPFL7: DAD D ; SUBTRACT 1 TRACK (26 SECTORS)
- DCR B ; DECREMENT TRACK NUMBER
- JNZ OPFL7 ; LOOP UNTIL ALL DONE
- MOV C,H ; WRITE MAX SIZE ONTO FCB
- CALL FWRT
- MOV C,L
- CALL FWRT
- CALL SCOPY ; COPY THE REST OF THE SECTOR
- DCX H ; GET ACTUAL SIZE
- MOV A,H ; CHECK FOR ZERO SIZE
- ORA L ; IE. DISK IS FULL
- JZ OPFL9 ; BRIF IS
- SHLD OSIZE ; ELSE SET OSIZE TO ACTUAL SIZE
- LXI H,OTRK ; POINT TO OTRK
- POP B ; RESTORE TRACK SECTOR ADDRESS
- MOV M,B ; AND SET OTRK
- INX H ; POINT TO OSCTR
- MOV A,M ; GET THE DRIVE
- ANI 0C0H ; NUMBER ONLY
- ORA C ; INCORPORATE SECTOR NUMBER
- MOV M,A ; AND SET IT
- INX H ; POINT TO OCNTR
- MVI M,0 ; AND RESET IT
- CALL RSTRV ; RESTORE INPUT FILE
- XRA A ; CLEAR FLAG
- RET
-
- OPFL9: MVI A,0FFH ; SET FLAG
- RET
-
- ; SUBROUTINE TO CLOSE AN OUTPUT FILE, IE. PAD UP
- ; THE LAST SECTOR IF NECCESSARY, COMPUTE THE
- ; FILE SIZE AND THEN UPDATE THE FILE DIRECTORY
- ; REGISTERS USED: ALL
-
- CLFLS: LDA OCNTR ; PAD UP REST OF SECTOR WITH 00H
- ORA A
- JZ CLFL1 ; BRIF ALL DONE
- MVI C,0
- CALL FWRT
- JMP CLFLS
- CLFL1: LHLD OSIZE ; SAVE LAST OSIZE
- PUSH H ; IN STACK FOR LATER
- CALL EOD ; FIND EOD
- MVI E,5 ; SKIP THE FILENAME
- CALL SKIPW
- CALL FREAD ; DISCARD EOD MARK
- MVI C,0 ; SET TO 0 ATTRIBUTE
- CALL FWRT
- CALL FREAD ; GET TRACK NUMBER
- MOV B,A ; SAVE IT IN B
- MOV C,A ; AND REPLACE
- CALL FWRT
- CALL FREAD ; GET SECTOR NUMBER
- MOV C,A ; AND SAVE IT IN C
- POP D ; RETRIEVE OSIZE
- PUSH B ; SAVE ADDRESS IN STACK
- PUSH D ; RESAVE OSIZE ON TOP OF STACK
- CALL FWRT ; AND REPLACE SECTOR
- CALL FREAD ; GET MAX SIZE
- MOV H,A ; INTO HL
- CALL FREAD
- MOV L,A
- POP D ; GET OSIZE TO DE
- MOV A,D ; GET 2'S COMPLEMENT OF IT
- CMA
- MOV D,A
- MOV A,E
- CMA
- MOV E,A
- INX D
- DAD D ; COMPUTE FILE SIZE
- MOV A,H ; CHECK FOR EMPTY FILE
- ORA A
- JNZ CLFL2 ; BRIF NOT
- MOV A,L
- CPI 2 ; MINIMUM FILE SIZE = 2
- JNC CLFL2 ; BRIF NOT MINIMUM
- INX H ; ELSE ADD 1
- CLFL2: MOV C,H ; AND WRITE IT
- CALL FWRT
- MOV C,L
- CALL FWRT
- POP B ; GET STARTING ADDRESS
- CLFL3: DCX H ; COMPUTE NEXT FILE STARTING
- MOV A,L ; ADDRESS
- ORA A ; BY INCREMENTING THE ADDRESS
- JNZ CLFL4 ; WHILE DECREMENTING THE SIZE
- MOV A,H
- ORA A
- JNZ CLFL4
- JMP CLFL5
- CLFL4: INR C ; INCREMENT SECTOR NUMBER
- MOV A,C ; CHECK IF NEW TRACK
- CPI 27
- JC CLFL3 ; BRIF NOT
- INR B ; ELSE INCREMENT TRACK NUMBER
- MVI C,1 ; AND RESET SECTOR NUMBER
- JMP CLFL3
- CLFL5: PUSH B ; SAVE NEW ADDRESS IN STACK
- MVI E,1 ; CHECK IF THAT WAS THE
- LDA ICNTR
- CPI 19 ; LAST FCB ON SECTOR
- JNC CLFL6 ; BRIF NOT
- MVI E,8 ; ELSE ADJUST FOR TAIL
- CLFL6: CALL SKIPW
- MVI E,8 ; SKIP READ NEW FCB UP TO SIZE
- CALL SKIPR
- MVI E,5
- CLFL7: MVI C,'*' ; PUT 5 ASTERISK FILENAME
- CALL FWRT
- DCR E
- JNZ CLFL7 ; LOOP UNTIL ALL DONE
- MVI C,0FFH ; PUT NEW EOD MARK
- CALL FWRT
- POP D ; RETRIEVE NEW ADDRESS
- MOV C,D ; PUT THEM IN
- CALL FWRT
- MOV C,E
- CALL FWRT
-
- ; SUBROUTINE TO COPY THE SECTOR UNTIL ICNTR = 0
-
- SCOPY: LDA ICNTR ; GET ICNTR
- ORA A ; TEST IT
- MOV E,A ; SAVE IT IN E
- RZ ; RET IF ALREADY ZERO
- JMP SKIPW ; NOW DO IT
-
-
- ; STORAGE AREA:
- TBCNT: DS 1 ; SECTOR COUNT
- TBFLG: DB 0 ; E-O-F FLAG: 00 = SOME MORE
- ; FF = NO MORE
- TBDMA: DS 2 ; DMA/END OF BUFFER ADDRESS
- STACK EQU $+64 ; STACK AREA
- TBUF EQU STACK
- OFLNM EQU TBUF+2 ; FDOS II OUTPUT FILENAME
- END
-