home *** CD-ROM | disk | FTP | other *** search
- ;===================================================================
- ; MICRO RESOURCES CP/M -- MTX FILE TRANSFER PROGRAM
- ; FOR USE WITH ICOM 3812 DD CP/M 1.4
- ;===================================================================
- ;
- ;
- ; THIS PROGRAM IS A UTILITY TO TRANSFER FILES FROM PCC 2000 MTX
- ; DOUBLE DENSITY DISKS TO CP/M DISKS OR TO TRANSFER A CP/M
- ; FILE TO A PCC 2000 MTX DOUBLE DENSITY DISK. A PROVISION HAS
- ; ALSO BEEN INCLUDED TO ALLOW EXAMINATION OF THE DIRECTORY OF
- ; THE MTX DISKETTE. THE OPERATION OF THIS PROGRAM ASSUMES
- ; THAT A CP/M SYSTEM DISK IS PRESENT IN DRIVE A: AND THAT THE
- ; MTX DATA DISK IS IN DRIVE B:. THE BIOS PRIMITIVES OF THE CP/M
- ; SYSTEM ARE ACCESSED DIRECTLY TO ALLOW READING AND WRITING
- ; OF THE DOUBLE DENSITY MTX DISK WITH IT'S 2 TO 1 LOGICAL
- ; TO PHYSICAL SECTOR MAPPING. NOTE THAT THIS SOFTWARE IS
- ; SPECIFICALLY TAYLORED TO FUNCTION THROUGH THE BIOS VECTORS
- ; OF THE LIFEBOAT IMPLEMENTATION OF CP/M 1.4 ON AN ICOM 3812
- ; DOUBLE DENSITY DISK SYSTEM.
- ;
- ; THIS PROGRAM DOES NOT PACK THE FILES OF THE MTX DISK
- ; WHEN CREATING NEW FILES UPON TRANSFER FROM A CP/M FILE.
- ; SUBSEQUENT PACKING MAY DONE UPON THE DESTINATION MTX/PCC 2000
- ; SYSTEM.
- ;
- ; THE DIRECTORIES OF EITHER DISK WILL BE SCANNED FOR FILES
- ; OF SIMILAR NAMES BEFORE A TRANSFER IS ACTUALLY MADE. A PROMPT
- ; QUESTION WILL INDICATE WHEN THE FILE ALREADY EXISTS. IN THE
- ; CASE OF THE CP/M DISK THE INDICATED FILE MAY BE ERASED IF
- ; DESIRED. WITH THE MTX DISK A FILE WILL NOT BE DELETED
- ; AND THE NAME OF THE SOURCE FILE ON THE CP/M DISK WILL HAVE
- ; TO BE CHANGED TO A NAME NOT CURRENTLY ON THE MTX DISK.
- ; FILE NAMES OF MTX FILES ARE A MAXIMUM OF 6 ASCII CHARACTERS
- ; IN LENGTH SO THE CP/M FILE TRANSFERRED TO THE MTX DISK
- ; WILL HAVE ITS NAME TRUNCATED TO THE FIRST SIX CHARACTERS.
- ; THE MTX FILE TYPE WILL ALWAYS BE SET TO 00 AS AN INDEXED
- ; FILE TYPE. RECORD SIZE OF A MTX DESTINATION FILE WILL BE
- ; SET TO 128 BYTES. FOR MTX DESTINATION FILES THAT ARE AN
- ; ODD NUMBER OF 128 BYTE RECORDS THE LAST HALF IS BACK
- ; FILLED WITH AN ARBITRARY CHOICE OF ZEROS.
- ;
- ; FOR FILES TRANSFERRED TO CP/M FROM MTX DISKS THE FILE
- ; TYPE WILL BE CHECKED AND IF THE SOURCE TYPE IS NOT AN
- ; INDEXED FILE THEN THE TRANSFER TO CP/M WILL NOT BE
- ; MADE.
- ;
- ; THIS PROGRAM BUFFERS CP/M SECTOR READS UP 156 IN
- ; LENGTH TO MAKE THE TRANSFER MORE EFFICIENT.
- ;
- ;
- ;
- ;
- ;*****************************************************************
- ;
- ;THIS SOFTWARE IS PROTECTED UNDER THE FOLLOWING COPYRIGHT
- ;AND MAY NOT BE REPRODUCED OR COPIED IN ANY FORM WITHOUT
- ;SPECIFIC PERMISSION FROM MICRO RESOURCES.
- ;
- ;
- ; COPYRIGHT (C) 1980
- ;
- ;
- ; MICRO RESOURCES
- ; MICHAEL J. KARAS
- ; 2468 HANSEN CT.
- ; SIMI VALLEY, CA 93065
- ; (805) 527-7922
- ;
- ;ANY QUESTIONS ABOUT THIS PROGRAM OR ITS APPLICATION
- ;CAN BE DIRECTED TO THE ABOVE ADDRESS OR TELEPHONE NUMBER.
- ;
- ;*********************************************************************
- ;
- WBOOT EQU 00 ;CP/M WARM BOOT ENTRY ADDRESS
- ;
- ERRLIM EQU 10 ;MAX ALLOWABLE ERRORS
- ;
- ;DEFINE ASCII CHARACTERS USED
- ;
- LF EQU 10 ;LINEFEED
- CR EQU 13 ;CARRIAGE RETURN
- ;
- ;
- ;START OF EXECUTABLE CODE
- ;
- ORG 100H
- CALL START ;GO PRINT ID
- DB 'MICRO RESOURCES FILE TRANSFER UTILITY '
- DB CR,LF,' ICOM 3812 CP/M <----> PCC 2000 MTX'
- DB CR,LF,' VER 1.1 11/7/80'
- DB CR,LF,'$'
- ;
- DB 'COPYRIGHT 1980 MICRO RESOURCES'
- DB '2468 HANSEN CT.'
- DB 'SIMI VALLEY, CA 93065'
- DB '(805) 527-7922'
- ;
- START:
- POP D ;GET ID MESSAGE
- MVI C,PRINT
- CALL BDOS ;PRINT ID MESSAGE
- ;
- ;INIT PRIVATE STACK
- ;
- LXI H,0 ;HL=0
- DAD SP ;HL=STACK FROM CP/M
- SHLD STACK ;..SAVE IT
- LXI SP,STACK ;SP=MY STACK
- ;
- ;INITIALIZE THE CP/M FILE BUFFERING PARAMETERS
- ;
- MVI A,00H
- STA SECINBF ;ZERO SEC IN BUFFER COUNTER
- STA EOFLG ;RESET CP/M END OF FILE FLAG
- LXI H,DBUF ;INITIALIZE BUFFER POINTER
- SHLD SECPTR
- ;
- ;INITIALIZE THE JMPS TO CP/M BIOS
- ;
- CALL INITADR
- ;
- ;SAVE PROGRAM OPTION
- ;
- CALL PROCOPT
- ;
- ;MOVE THE FILENAME FROM FCB 2 TO FCB 1
- ;
- CALL MOVEFCB
- ;
- ;JMP TO APPROPRIATE FUNCTION
- ;
- LDA OPTION ;GET PROGRAM OPTION
- ;
- CPI 'R' ;READ MTX FILE?
- JZ MTXRD
- ;
- CPI 'W' ;WRITE MTX FILE?
- JZ MTXWR
- ;
- CPI 'D' ;LOOK AT MTX DIRECTORY
- JZ MTXDIR
- ;
- CPI 'H' ;GO TO HELP FILE PRINTOUT?
- JZ HELP
- ;
- ;INVALID OPTION
- ;
- JMP BADOPT
- ;
- ;
- ;
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * *
- * MTXDIR: LISTS MTX DIRECTORY TO CONSOLE *
- * *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;
- ;
- ;THE DIRECTORY OF THE DOUBLE DENSITY MTX
- ;DISK IN DRIVE B: IS LISTED TO THE CONSOLE IN
- ;A SINGLE COLUMN FORMAT. CONSOLE I/O IS DONE
- ;THROUGH CP/M SO THAT THE CTL-S AND CTL-P
- ;FUNCTIONS WILL WORK. THE LISTING ALSO STOPS
- ;AFTER EACH 16 ENTRIES HAVE BEEN TYPED
- ;
- MTXDIR:
- CALL ILPRT ;PRINT THE DIRECTORY HEADER LABEL
- DB CR,LF,CR,LF,' MTX DISK DIRECTORY'
- DB CR,LF,CR,LF
- DB 'FILENAME TYPE RECORD RECORD START END ',CR,LF
- DB ' COUNT SIZE SECTOR SECTOR',CR,LF
- DB '------------------------------------------',CR,LF,0
- ;
- MVI A,016 ;SET PRINT LOOP COUNT
- STA LISTCNT
- MVI A,00 ;SET SCAN FOR FIRST ENTRY
- JMP MDIR2 ;JUMP INTO LOOP
- MDIR1:
- MVI A,01 ;SET SCAN CODE FOR NEXT ENTRY
- MDIR2:
- CALL MDIRSC ;SCAN FOR NEXT DIRECTORY ENTRY
- ORA A ;SET FLAGES FOR RETURN CODE
- JNZ MDEREX ;GO EXIT FOR FULL DISK DIRECTORY
- LDA MDENT ;GET FIRST CHAR OF DERECTORY ENTRY
- CPI 0FFH ;MUST BE AT END OF THE LIST
- JZ MDIREX
- CPI 000H ;CHECK IF THIS ENTRY IS EMPTY
- JZ MDIR1 ;SKIP PRINT IF SO
- CALL PRTDIR ;PRINT THIS ENTRY
- ;
- LDA LISTCNT ;GET LIST LINE COUNT
- DCR A ;DECREMENT IT
- STA LISTCNT ;STORE NEW COUNT BACK
- JNZ MDIR1 ;GO TO DO NEXT ENTRY
- ;
- CALL ILPRT ;GIVE THE GUY A CHANCE TO STOP A LONG DIRECTORY
- DB 1,CR,LF,0
- ;
- MVI A,016 ;RESET PRINT LOOP COUNT
- STA LISTCNT
- JMP MDIR1 ;GO START ON 16 MORE ENTRIES
- ;
- MDIREX:
- CALL ILPRT ;PRINT END OF LIST MESSAGE
- DB CR,LF,CR,LF,'END OF MTX DISK DIRECTORY',CR,LF,0
- MDIREX1:
- MVI C,00H ;RESTORE SELECT OF DRIVE A:
- CALL SELDSK ;DIRECT BIOS ACCESS
- JMP EXIT ;DONE WITH DIRECTORY
- ;
- MDEREX:
- CALL ILPRT ;PRINT DISK FULL MESSAGE
- DB CR,LF,'++MTX DISK DIRECTORY SPACE FULL++',CR,LF,0
- ;
- JMP MDIREX1
- ;
- ;
- ;
- ;
- ;SCAN MTX DIRECTORY ROUTINE
- ; ROUTINE ENTRY IS CODED TO ALLOW VARIABLE FUNCTIONS
- ; CODE IS PASSED IN THE A REGISTER
- ; CODES AS FOLLOWS:
- ; 00=OPEN SCAN FROM BEGINNING WITH LOGICAL SECTOR 1
- ; 01=GET NEXT DIRECTORY ENTRY
- ;
- ; RETURN VALUE IS THE FIRST OR NEXT ENTRY AS SPECIFIED BY THE
- ; FUNCTION CODE AND IS PASSED IN BUFFER "MDENT" WHICH IS 16
- ; BYTES LONG.
- ;
- ; THIS ROUTINE SCANS AND RETURNS ALL POSSIBLE ENTRIES
- ; AND WHEN END OF LOGICAL SECTOR 25 IS ENCOUNTERED AN
- ; 0FFH CODE IS RETURNED IN THE ACCUMULATOR. ELSE A 00H
- ; CODE IS RETURNED.
- ;
- ;
- ;
- MDIRSC:
- ORA A ;SET FLAGS FOR FUNCTION CHECK
- JNZ NEXTENT ;FOR NON-ZERO CODE JUST GET NEXT ENTRY
- ;
- ;SETUP FOR BEGINNING OF SCAN
- MVI A,000H ;SETUP START SECTOR OF DIRECTORY-1
- STA MDIRSEC
- MVI A,016 ;SET CURRENT SUBSCAN COUNT TO MAX
- STA DIRSECI
- ;
- NEXTENT:
- LDA DIRSECI ;GET SECTOR INDEX
- CPI 016 ;AT MAXIMUM ENTRY?
- JNZ SAMSEC ;NO STAY WITH THIS SECTOR
- LXI H,MDIRSEC
- INR M ;INCREMENT CURRENT SECTOR NUMBER
- MOV A,M ;GET THE SECTOR NUMBER
- CPI 026 ;CHECK FOR THE LAST SECTOR
- JNZ NXTSEC ;GO AROUND THE END OF TRACK EXIT
- ;
- MVI A,0FFH ;SETUP EXIT FOR END OF DIRECTORY SPACE
- RET
- ;
- NXTSEC:
- MOV L,A
- MVI H,00H
- CALL MRDSEC ;GO READ MTX SECTOR
- LXI H,MTXBUF ;MOVE INPUT BUFFER
- LXI D,DIRBUF ;..TO DIRECTORY BUFFER
- MVI B,00H ;SET COUNT FOR FULL 256
- CALL MOVE
- MVI A,00
- STA DIRSECI ;SET SECTOR INDEX TO MINIMUM
- ;
- SAMSEC:
- LXI H,DIRSECI
- MOV B,M ;GET THE INDEX
- INR M ;INCR THE SECTOR INDEX
- LXI H,DIRBUF ;POINT TO THE MTX DIRECTORY BUFFER
- LXI D,016 ;LENGTH OF AN ENTRY
- MOV A,B
- CPI 00H ;CHECK FOR ILLEGAL ZERO LOOP COUNT
- JZ SAMSEC2
- SAMSEC1:
- DAD D ;LOOP TO MAKE OFFSET INDEX
- DCR B
- JNZ SAMSEC1
- SAMSEC2:
- LXI D,MDENT ;POINT TO ENTRY PASS BUFFER
- MVI B,016 ;SETUP LENGTH OF DIRECTORY ENTRY
- CALL MOVE ;GO MOVE A DIRECTORY ENTRY
- LXI H,MDENT ;SETUP TO STRIP MTX MBS'S FROM FILE NAME
- MOV A,M ;SEE IF FIRST BYTE IS 0FFH
- CPI 0FFH ;IF SO WE SKIP MSB STRIP
- JZ ENDRET
- MVI B,06H ;CHARACTER COUNT
- SAMSEC3:
- MOV A,M ;GET CHARACTER OF NAME
- ANI 07FH ;STRIP MTX STRING CRAP
- MOV M,A
- INX H
- DCR B ;DEC NAME BYTE COUNT
- JNZ SAMSEC3
- ;
- ENDRET:
- MVI A,00H ;SET NORMAL RETURN FLAG
- RET
- ;
- ;
- ;
- ;
- ;DIRECTORY SCAN POINTER PARAMETERS
- ;
- ;
- MDIRSEC DB 00 ;CURRENT DIRECTORY SECTOR NUMBER
- DIRSECI DB 00 ;INDEX OF SCAN INTO CURRENT DIRECTORY SECTOR
- DIRBUF DS 256 ;256 BYTE DIRECTORY ENTRY BUFFER
- LISTCNT DB 00 ;DIRECTORY LIST ENTRY COUNT
- ;
- ;
- ;
- ;PRINT DIRECTORY ENTRY SUBROUTINE
- ;
- ;
- PRTDIR:
- LXI H,MDENT ;POINT TO DIRECTORY ENTRY BUFFER
- MVI A,'B'
- CALL CTYPE ;PRINT OUT DRIVE DESIGNATOR
- MVI A,':'
- CALL CTYPE
- MVI B,06 ;FILE NAME CHARACTER COUNT
- NAMLP:
- MOV A,M ;GET NAME CHARACTER
- CALL CTYPE
- INX H ;INCREMENT BUFFER POINTER
- DCR B
- JNZ NAMLP ;GO FOR NEXT NAME CHAR
- ;
- CALL SP3 ;THREE SPACES
- MOV A,M ;GET TYPE BYTE
- CALL HEXO ;SHOW IT
- INX H ;INCREMENT THE BUFFER POINTER
- ;
- INX H ;SKIP THE KEY SIZE FIELD
- ;
- CALL SP2 ;TWO SPACES
- MOV D,M ;GET HIGH RECORD COUNT BYTE
- INX H
- MOV E,M ;GET LOW RECORD COUNT BYTE
- INX H
- PUSH H ;SAVE STRING POINTER
- CALL DECPRT ;GO PRINT RECORD COUNT
- POP H
- ;
- CALL SP2 ;TWO SPACES
- MOV D,M ;GET HIGH RECORD SIZE BYTE
- INX H
- MOV E,M ;GET LOW RECORD SIZE BYTE
- INX H
- PUSH H ;SAVE STRING POINTER
- CALL DECPRT ;GO PRINT RECORD SIZE
- POP H
- ;
- CALL SP2 ;TWO SPACES
- MOV D,M ;GET HIGH START SECTOR BYTE
- INX H
- MOV E,M ;GET LOW START SECTOR BYTE
- INX H
- PUSH H ;SAVE STRING POINTER
- CALL DECPRT ;GO PRINT START SECTOR COUNT
- POP H
- ;
- CALL SP2 ;TWO SPACES
- MOV D,M ;GET HIGH END SECTOR BYTE
- INX H
- MOV E,M ;GET LOW END SECTOR BYTE
- DCX D ;SET THE ENDING SECTOR TO REAL VALUE
- CALL DECPRT ;GO PRINT ENDING SECTOR COUNT
- ;
- CALL CRLF ;GET READY FOR NEXT LINE
- RET
- ;
- ;
- ;CONVERT AND PRINT A TWO BYTE VALUE AT CONSOLE IN DECIMAL
- ;
- DECPRT:
- XCHG ;HL=WORD TO PRINT
- LXI D,STRBUF ;POINT TO A CONVERT BUFFER
- CALL BINASC ;CONVERT TO DECIMAL ASCII
- MVI B,05H ;BYTE COUNT PRINT STRING
- LXI H,STRBUF ;POINT TO THE PRINT BUFFER
- DECPRT1:
- MOV A,M ;GET PARAMETER CHARACTER
- PUSH H
- CALL CTYPE ;PRINT AT CONSOLE
- POP H
- INX H ;INCREMENT STRING POINTER
- DCR B ;DEC BYTE COUNT
- JNZ DECPRT1 ;DONE WITH FIVE CHAR YET
- RET
- ;
- ;
- ;DECIMAL PRINTING ROUTINE TEMPORARY BUFFER STRING SPACE
- ;
- STRBUF:
- DS 14 ;RESERVE SOME BYTES FOR BUFFER
- ;
- ;
- ;CONSOLE SPACE PRINTING ROUTINE
- ;
- SP5:
- MVI A,' ' ;5 SPACES
- CALL CTYPE
- SP4:
- MVI A,' ' ;4 SPACES
- CALL CTYPE
- SP3:
- MVI A,' ' ;3 SPACES
- CALL CTYPE
- SP2:
- MVI A,' ' ;2 SPACES
- CALL CTYPE
- SP1:
- MVI A,' ' ;1 SPACE
- CALL CTYPE
- RET
- ;
- ;
- ;
- ;
- * * * * * * * * * * * * * * * * * * * * *
- * *
- * MTXWR: COPIES FILE TO MTX *
- * *
- * * * * * * * * * * * * * * * * * * * * *
- ;
- ;THE CP/M FILE SPECIFIED IN THE COMMAND
- ;IS TRANSFERRED TO THE MTX DISK IN DRIVE B:
- ;
- MTXWR:
- CALL OPENFIL ;OPEN THE FILE
- LXI H,0000H ;SET INITIAL RECORD COUNT TO ZERO
- SHLD RECCNT
- MVI H,26 ;SET MAX UTILIZED SECTOR TO 26
- ;..MTX STARTS FILES AT LOGICAL SECTOR 26
- SHLD MAXSEC ;STORE AWAY
- MVI A,00H
- STA MTXEOF ;CLEAR MTX EOF FLAG
- MVI A,00H ;SETUP FOR DIRECTORY SCAN
- JMP SCAN2 ;JUMP INTO LOOP
- SCAN1:
- MVI A,01H ;SET SCAN CODE FOR NEXT ENTRY
- SCAN2:
- CALL MDIRSC ;SCAN FOR NEXT DIRECTORY ENTRY
- ORA A ;SET FLAGS FOR RETURN CODE
- JNZ MDIRFUL ;EXIT FOR FULL DIRECTORY
- ;
- MVI B,06 ;SETUP FOR COMPARE OF FILE NAMES
- LXI D,FCB+1 ;..FOR 6 CHAR FROM CP/M FCB
- LXI H,MDENT ;..TO MTX DIRECTORY ENTRY
- CALL COMPARE ;GO DO THE COMPARE
- ORA A ;CHECK RETURN FLAG
- JNZ FEXEX ;EXIT WITH FILE EXISTS MESSAGE
- ;
- LDA MDENT ;FIRST BYTE OF NAME "FF" IF END
- CPI 0FFH ;ARE WE AT END OF LIST?
- JZ SCAN3 ;IF AT END THEN BALE OUT OF LOOP
- ;
- LHLD MAXSEC ;SET TO UPDATE MAX USED SECTOR IF NEEDED
- XCHG
- LHLD MDENT+14
- MOV A,L ;COMPARE HIGH BYTE OF THIS ONE AND CURRENT MAX
- CMP E
- JC SCAN1 ;NO UPDATE NEEDED
- JNZ UDTMAX ;IF HIGH BYTE GREATER THEN UPDATE MAX
- MOV A,H ;COMPARE LOW BYTES OF THIS ONE AND CURRENT MAX
- CMP D
- JC SCAN1 ;NO UPDATE IF HIGHS EQUAL AND LOW NOT BIGGER
- UDTMAX:
- SHLD MAXSEC ;STORE NEW BIG SEC NUM AT MAX SEC LOC
- JMP SCAN1 ;GO DO MORE DIRECTORY ENTRIES
- ;
- SCAN3:
- MVI B,06 ;MOVE FILE NAME INTO MTX DIRECTORY ENTRY
- LXI H,FCB+1
- LXI D,MDENT
- SCANAP:
- MOV A,M ;GET CHAR FROM FCB AREA
- ORI 080H ;PUT ON TOP BIT FOR MTX COMPATIBILITY
- STAX D ;PUT IN NEW DIRECTORY ENTRY
- INX H ;BUMP POINTERS
- INX D
- DCR B ;DEC NAME BYTE COUNT
- JNZ SCANAP
- ;
- MVI A,00 ;SET THE NEW FILE TYPE TO ZERO AS INDEXED FILE
- STA MDENT+6
- STA MDENT+7 ;SET KEYSIZE FIELD TO ZERO
- STA MDENT+10 ;SET HIGH BYTE OF RECORD SIZE TO ZERO
- MVI A,080H
- STA MDENT+11 ;SET RECORD SIZE TO 128 BYTES AS CP/M
- ;SECTOR SIZE
- LHLD MAXSEC ;GET CURRENT MAX SECTOR AND PUT AS START
- SHLD MDENT+12
- ;
- SHLD MDENT+14 ;SET INITIAL END SECTOR
- MFILWLP:
- CALL RDSECT ;READ A SECTOR FROM CP/M
- JC UPDATE ;UPDATE MTX DIRECTORY IF DONE
- LHLD RECCNT ;INC RECORD COUNT
- CALL MTXINC
- SHLD RECCNT
- LXI H,080H ;MOVE SECTOR FROM CPM AREA
- LXI D,MTXBUF
- CALL MOVE128
- CALL RDSECT ;READ ANOTHER SECTOR FROM CP/M
- JC UPDAFIL ;UPDATE MTX DIRECTORY IF DONE
- LHLD RECCNT ;INC RECORD COUNT
- CALL MTXINC
- SHLD RECCNT
- LXI H,080H ;MOVE SECTOR FROM CP/M AREA
- LXI D,MTXBUF+128
- CALL MOVE128
- WRTENT:
- LXI H,MDENT+14 ;POINT TO SECTOR TO BE WRITTEN
- MOV D,M
- INX H
- MOV E,M
- ;
- LXI H,07B8H ;CHECK IF DISK FULL
- MOV A,H
- CMP D
- JNZ NOTFUL
- MOV A,L
- CMP E
- JZ DSKFUL ;EXIT WITH MESSAGE IF DISK IS FULL
- ;
- NOTFUL:
- XCHG ;HL=LOGICAL SECTOR TO WRITE
- CALL MWRSEC ;GO WRITE CURRENT MTX SECTOR
- LHLD MDENT+14 ;INCREMENT END SECTOR
- CALL MTXINC
- SHLD MDENT+14
- ;
- LDA MTXEOF ;SEE IF WE GOT TO END BEFORE
- ORA A
- JNZ UPDATE ;GO TO UPDATE DIRECTORY IF END
- ;
- JMP MFILWLP ;GO TO GET THE NEXT SECTOR FROM CP/M
- ;
- ;
- ;CP/M EOF ENCOUNTERED ON MIDDLE OF SECTOR NEEDS FILLING TO END
- ; WE ARBITRARILY CHOOSE TO FILL WITH ZEROS.
- ;
- UPDAFIL:
- LXI H,MTXBUF+128 ;POINT TO SECOND HALF OF BUFFER
- MVI B,128 ;SET FILL COUNT
- SHFILL:
- MVI M,00H ;PUT IN A ZERO
- INX H ;BUMP POINTER
- DCR B ;DEC BYTE COUNT
- JNZ SHFILL ;MORE TO DO?
- ;
- MVI A,0FFH ;SET END OF FILE FLAG
- STA MTXEOF
- JMP WRTENT ;GO WRITE SECTOR
- ;
- ;FILE WRITTEN, NOW UPDATE THE DIRECTORY
- ;
- UPDATE:
- XRA A ;INITIALIZE TWO SECTOR UPDATE FLAG
- STA U2SEC
- ;
- LHLD RECCNT ;PUT RECORD COUNT INTO DIR ENTRY
- MOV A,H ;CHECK IF THERE WAS NO CP/M FILE SIZE
- ORA L
- JZ NOSIZF ;EXIT IF FILE FIZE IS ZERO
- SHLD MDENT+8
- ;
- LXI H,DIRBUF ;MOVE DIRECTORY SECTOR TO OUTPUT BUFFER
- LXI D,MTXBUF
- MVI B,00H ;SET THE COUNT FOR FULL 256 BYTE MOVE
- CALL MOVE
- LDA DIRSECI ;GET DIRECTORY SECTOR INDEX
- LXI H,MTXBUF-16
- LXI D,16 ;MAKE INSERT POINTER FOR NEW ENTRY
- UPDAT:
- DAD D
- DCR A
- JNZ UPDAT
- ;
- XCHG ;PUT INSERT POINTER IN DE
- LXI H,MDENT ;POINT TO NEW DIRECTORY ENTRY
- MVI B,16 ;LENGTH OF DIRECTORY ENTRY
- CALL MOVE ;MOVE INTO OUTPUT BUFFER
- LDA DIRSECI ;SEE IF NEW ENTRY IS LAST IN SECTOR
- CPI 016
- JNZ ONESEC ;JUMP TO PUT END ENTRY IN THIS SECTOR
- ;
- MVI A,0FFH ;SET U2SEC FLAG
- STA U2SEC
- JMP WDIRSEC ;GO WRITE CURRENT SECTOR
- ;
- ONESEC:
- MVI A,0FFH ;PUT "FF"ed OUT ENTRY INTO THIS SECTOR
- MVI B,16 ;ENTRY LENGTH-- DE OK FROM PREVIOUS MOVE
- ONESEC1:
- STAX D ;PUT FF IN ENTRY
- INX D ;INC FF'ING POINTER
- DCR B ;DEC BYTE COUNTER
- JNZ ONESEC1
- ;
- WDIRSEC:
- LDA MDIRSEC ;GET THE DIRECTORY SECTOR NUMBER
- MVI H,0 ;MAKE TWO BYTE LOGICAL SECTOR NUMBER
- MOV L,A
- CALL MWRSEC ;GO WRITE THE SECTOR OF DIRECTORY
- LDA U2SEC ;CHECK IF WE SHOULD UPDATE TWO SECTORS
- ORA A
- JNZ GETSEC ;IF SO GO PREPARE FOR IT
- ;
- JMP DONE ;ALL DONE
- ;
- GETSEC:
- XRA A
- STA U2SEC ;RESET UPDATE TWO SECTORS FLAG
- LDA MDIRSEC ;GET CURRENT DIRECTORY SECTOR NUMBER
- INR A
- STA MDIRSEC ;STORE THIS NEW ONE AWAY
- CPI 01BH ;SEE IF DIRECTORY FULL HERE
- JZ UDFULL ;GO PRINT EXIT MESSAGE
- ;
- MVI H,0 ;MAKE TWO BYTE SECTOR NUMBER
- MOV L,A
- CALL MRDSEC ;GO READ NEXT SECTOR
- ;
- LXI D,MTXBUF ;POINT TO START OF DIRECTORY SECTOR
- JMP ONESEC ;GO END THE PROCESS OF UPDATE ON SECOND SEC
- ;
- ;
- ;SUBROUTINE TO INCREMENT A REVERSE ORDER TWO BYTE PAIR
- ;
- MTXINC:
- MOV A,H ;SET TO INCREMENT END SECTOR
- MOV H,L
- MOV L,A
- INX H ;INC THE END SECTOR
- MOV A,H
- MOV H,L
- MOV L,A
- RET
- ;
- ;
- ;EXIT POINT FROM WRITE IF MTX DIRECTORY IS FULL UPON UPDATE
- ;
- UDFULL:
- CALL ILPRT ;PRINT DIRECTORY FULL MESSAGE
- DB CR,LF,'++MTX DIRECTORY FULL UPON UPDATE++'
- DB CR,LF,'++TRANSFERRED FILE EXISTS ON DISK++',CR,LF,0
- JMP EXIT
- ;
- ;
- ;EXIT POINT FROM WRITE IF MTX DIRECTORY IS FULL
- ;
- MDIRFUL:
- CALL ILPRT ;PRINT DIRECTORY FULL MESSAGE
- DB CR,LF,'++MTX DIRECTORY MUST BE FULL++',CR,LF,0
- JMP EXIT
- ;
- ;
- ;EXIT POINT FROM WRITE IF NOTHING IN CP/M FILE
- ;
- NOSIZF:
- CALL ILPRT ;PRINT NO SIZE TO CP/M FILE
- DB CR,LF,'++CP/M FILE EMPTY-NO MTX FILE CREATED++',CR,LF,0
- JMP EXIT
- ;
- ;
- ;EXIT POINT FROM WRITE IF MTX DISK GETS FULL
- ;
- DSKFUL:
- CALL ILPRT ;PRINT DISK FULL MESSAGE
- DB CR,LF,'++FILE TOO BIG - MTX DISK FULL++'
- DB CR,LF,'++DIRECTORY NOT UPDATED WITH NEW FILE++',CR,LF,0
- JMP EXIT
- ;
- ;EXIT POINT FROM WRITE IF MTX FILE ALREADY EXISTS
- ;
- FEXEX:
- CALL ILPRT
- DB CR,LF,'++MTX FILE ALREADY EXISTS++'
- DB CR,LF,'++CHANGE NAME OF SOURCE FILE ON CP/M++',CR,LF,0
- JMP EXIT
- ;
- ;
- ;
- ;
- ;PARAMETER STORAGE AREA FOR MTX WRITE ROUTINE
- ;
- U2SEC DB 00 ;USED TO SEE IF TWO SECTORS S/B SET IN DIR
- MAXSEC DW 00 ;STORAGE FOR MAXIMUM USED LOGICAL SECTOR
- MTXEOF DB 00 ;FLAG TO INDICATE IF END OF MTX FILE
- RECCNT DW 00 ;CURRENT MTX FILE SIZE IN 128 BYTE RECORDS
- ;
- ;
- ;
- * * * * * * * * * * * * * * * * * * * * *
- * *
- * MTXRD: COPY FILE FROM MTX *
- * *
- * * * * * * * * * * * * * * * * * * * * *
- ;
- ;FETCHES AN MTX FILE AND THEN WRITES
- ;IT TO A CP/M FILE ON DRIVE A:
- ;
- MTXRD:
- CALL ERASFIL ;ERASE THE CP/M FILE
- CALL MAKEFIL ;..THEN MAKE NEW
- MVI A,00 ;SET SCAN FOR FIRST ENTRY
- JMP FIND2 ;JUMP INTO LOOP
- FIND1:
- MVI A,01 ;SET SCAN CODE FOR NEXT ENTRY
- FIND2:
- CALL MDIRSC ;SCAN FOR NEXT DIRECTORY ENTRY
- ORA A ;SET FLAGES FOR RETURN CODE
- JNZ MDNFEX ;GO EXIT FOR NOT FOUND MTX FILE
- LDA MDENT ;FIRST CHAR OF FILE NAME
- CPI 0FFH ;MUST BE AT END OF THE LIST IF "FF"
- JZ MDNFEX ;GO EXIT FOR NOT FOUND MTX FILE
- MVI B,06H ;SETUP FOR COMPARE FILE NAMES
- LXI D,FCB+1 ;..FOR 6 CHAR FROM FCB TO
- LXI H,MDENT ;..MTX DIRECTORY ENTRY
- CALL COMPARE ;GO COMPARE
- ORA A ;CHECK THE RETURN FLAG
- JZ FIND1 ;NO NAME MATCH IF ZERO
- ;
- ;FOUND FILE ON MTX DISK
- ;
- RMTXLP:
- LDA MDENT+6
- CPI 000H ;CKECK IF SOURCE FILE IS OF INDEXED TYPE
- JNZ NINDX ;EXIT WITH ERROR IF NOT INDEXED FILE
- ;
- LXI H,MDENT+12 ;GET LOGICAL SECTOR NUMBER
- MOV D,M ;..HIGH BYTE
- INX H
- MOV E,M ;..LOW BYTE
- INX D ;INCREMENT SECTOR FOR NEXT TIME
- MOV M,E ;STORE BACK AWAY
- DCX H
- MOV M,D
- DCX D ;GET BACK NUMBER OF ONE WE WANT
- XCHG ;LOGICAL SECTOR COUNT TO HL
- CALL MRDSEC ;GO READ IT FROM MTX DISK
- ;
- LXI H,MTXBUF ;MOVE 1ST HALF TO CP/M AREA
- LXI D,080H ;..TO 128 BYTE PASS BUFFER FOR CP/M
- CALL MOVE128
- CALL WRSECT ;MOVE DATA TO CP/M QUEUE
- ;
- LXI H,MTXBUF+128 ;MOVE 2ND HALF TO CP/M AREA
- LXI D,080H ;..TO 128 BYTE PASS BUFFER FOR CP/M
- CALL MOVE128
- CALL WRSECT ;MOVE 2ND HALF DATA TO CP/M QUEUE
- ;
- LHLD MDENT+12 ;GET CURRENT INCREMENTED LOGICAL SECTOR
- XCHG ;TO (DE). NOTE HI/LOW ORDER WRONG
- LHLD MDENT+14 ;GET DIRECTORY ENTRY 1+ ENDING SECTOR TO (HL)
- MOV A,H ;COMPARE LOW BYTES OF SECTOR NUMBERS
- CMP D
- JNZ RMTXLP ;BOTH MUST COMPARE FOR EQUALITY
- MOV A,L ;NOW COMPARE HIGH BYTES OF SECTOR NUMBERS
- CMP E
- JNZ RMTXLP ;AGAIN NO COMPARE SO MORE TO READ
- ;
- ;GOT EOF ON SECTOR - FLUSH BUFFERS, END
- ;
- CALL WRBLOCK ;WRITE THE LAST BLOCK
- CALL CLOSFIL ;CLOSE THE FILE
- JMP DONE ;GO PRINT END OF TRANSFER MESSAGE
- ;
- ;
- ;
- MDNFEX:
- CALL ILPRT ;PRINT MTX FILE NOT FOUND
- DB CR,LF,'++MTX FILE NOT FOUND++',CR,LF,0
- JMP EXIT
- ;
- ;
- ;
- NINDX:
- CALL ILPRT ;PRINT MTX FILE TYPE NOT INDEXED TYPE
- DB CR,LF,'++MTX FILE NOT AN INDEXED FILE++',CR,LF,0
- JMP EXIT
- ;
- ;
- ;
- * * * * * * * * * * * * * * * * * * * * *
- * *
- * SUBROUTINES *
- * *
- * * * * * * * * * * * * * * * * * * * * *
- ;
- ;
- ;
- ;----> ERASFIL: ERASE THE INCOMING FILE.
- ;
- ;IF IT EXISTS, ASK IF IT MAY BE ERASED.
- ;
- ERASFIL:
- LXI D,FCB ;POINT TO CTL BLOCK
- MVI C,SRCHF ;SEE IF IT..
- CALL BDOS ;..EXISTS
- INR A ;FOUND?
- RZ ;..NO, RETURN
- CALL ILPRT ;PRINT:
- DB '++CP/M FILE EXISTS, TYPE Y TO ERASE: ',0
- CALL KEYIN ;GET A CHARACTER FROM CONSOLE
- ANI 5FH ;MAKE UPPER CASE
- CPI 'Y' ;WANT ERASED?
- JNZ EXIT ;QUIT IF NOT ERASE
- CALL CRLF ;BACK TO START OF LINE
- ;
- ;ERASE OLD FILE
- ;
- LXI D,FCB ;POINT TO FCB
- MVI C,ERASE ;GET BDOS FNC
- CALL BDOS ;DO THE ERASE
- RET ;FROM "ERASFIL"
- ;
- ;----> MAKEFIL: MAKES THE FILE TO BE RECEIVED
- ;
- MAKEFIL:
- LXI D,FCB ;POINT TO FCB
- MVI C,MAKE ;GET BDOS FNC
- CALL BDOS ;TO THE MAKE
- INR A ;FF=BAD?
- RNZ ;OPEN OK
- ;
- ;DIRECTORY FULL - CAN'T MAKE FILE
- ;
- CALL ERXIT
- DB '++ERROR - CANNOT MAKE FILE++',CR,LF
- DB '++DIRECTORY MUST BE FULL++',CR,LF,'$'
- ;
- ;----> OPENFIL: OPENS THE FILE TO BE SENT
- ;
- OPENFIL:
- LXI D,FCB ;POINT TO FILE
- MVI C,OPEN ;GET FUNCTION
- CALL BDOS ;OPEN IT
- INR A ;OPEN OK?
- RNZ ;FILE OPENED OK
- CALL ERXIT ;..NO, ABORT
- DB '++CANNOT OPEN CP/M FILE++',CR,LF,'$'
- ;
- ;
- ;----> CLOSFIL: CLOSES THE RECEIVED FILE
- ;
- CLOSFIL:
- LXI D,FCB ;POINT TO FILE
- MVI C,CLOSE ;GET FUNCTION
- CALL BDOS ;CLOSE IT
- INR A ;CLOSE OK?
- RNZ ;..YES, RETURN
- CALL ERXIT ;..NO, ABORT
- DB '++CANNOT CLOSE CP/M FILE++',CR,LF,'$'
- ;
- ;----> RDSECT: READS A SECTOR
- ;
- ;FOR SPEED, THIS ROUTINE BUFFERS UP 156
- ;SECTORS AT A TIME.
- ;
- RDSECT:
- LDA SECINBF ;GET # SECT IN BUFF.
- DCR A ;DECREMENT..
- STA SECINBF ;..IT
- CPI 0FFH ;CHECK IF SECTOR COUNT UNDERFLOWS
- JZ RDBLOCK ;EXHAUSTED? NEED MORE.
- LHLD SECPTR ;GET POINTER
- LXI D,80H ;TO DATA
- CALL MOVE128 ;MOVE TO BUFFER
- SHLD SECPTR ;SAVE BUFFER POINTER
- STC
- CMC ;CLEAR CARRY SO EOF NOT INDICATED
- ;ON NORMAL RETURN
- RET ;FROM "READSEC"
- ;
- ;BUFFER IS EMPTY - READ IN ANOTHER BLOCK OF 156
- ;
- RDBLOCK:
- LDA EOFLG ;GET EOF FLAG
- CPI 1 ;IS IT SET?
- STC ;TO SHOW EOF
- RZ ;GOT EOF
- MVI C,00H ;SELECT DRIVE A:
- CALL SELDSK
- MVI C,0 ;SECTORS IN BLOCK
- LXI D,DBUF ;TO DISK BUFFER
- RDSECLP:
- PUSH B
- PUSH D
- MVI C,STDMA ;SET DMA..
- CALL BDOS ;..ADDR
- LXI D,FCB
- MVI C,READ
- CALL BDOS
- POP D
- POP B
- ORA A ;READ OK?
- JZ RDSECOK ;YES
- DCR A ;EOF?
- JZ REOF ;GOT EOF
- ;
- ;READ ERROR
- ;
- CALL ERXIT
- DB '++CP/M FILE READ ERROR++',CR,LF,'$'
- ;
- RDSECOK:
- LXI H,80H
- DAD D ;TO NEXT BUFF
- XCHG ;BUFF TO DE
- INR C ;MORE SECTORS?
- MOV A,C ;GET COUNT
- CPI 156 ;DONE?
- JZ RDBFULL ;..YES, BUF IS FULL
- JMP RDSECLP ;READ MORE
- ;
- REOF:
- MVI A,1
- STA EOFLG ;SET EOF FLAG
- MOV A,C
- ;
- ;BUFFER IS FULL, OR GOT EOF
- ;
- RDBFULL:
- STA SECINBF ;STORE SECTOR COUNT
- LXI H,DBUF ;INIT BUFFER..
- SHLD SECPTR ;..POINTER
- LXI D,80H ;RESET..
- MVI C,STDMA ;..DMA..
- CALL BDOS ;..ADDR
- JMP RDSECT ;PASS SECT TO CALLER
- ;
- ;----> WRSECT: WRITE A SECTOR
- ;
- ;WRITES THE SECTOR INTO A BUFFER. WHEN 156
- ;HAVE BEEN WRITTEN, WRITES THE BLOCK TO DISK.
- ;
- ;ENTRY POINT "WRBLOCK" FLUSHES THE BUFFER AT EOF.
- ;
- WRSECT:
- LHLD SECPTR ;GET BUFF ADDR
- XCHG ;TO DE FOR MOVE
- LXI H,80H ;FROM HERE
- CALL MOVE128 ;MOVE TO BUFFER
- XCHG ;SAVE NEXT..
- SHLD SECPTR ;..BLOCK POINTER
- LDA SECINBF ;BUMP THE..
- INR A ;..SECTOR #..
- STA SECINBF ;..IN THE BUFF
- CPI 156 ;HAVE WE 156?
- RNZ ;NO, RETURN
- ;
- ;----> WRBLOCK: WRITES A BLOCK TO DISK
- ;
- WRBLOCK:
- LDA SECINBF ;# SECT IN BUFFER
- ORA A ;0 MEANS END OF FILE
- RZ ;NONE TO WRITE
- PUSH PSW ;SAVE SECINBUF
- MVI C,00H ;SELECT DISK DRIVE A:
- CALL SELDSK
- POP PSW ;GET SECINBUF BACK
- MOV C,A ;SAVE COUNT
- LXI D,DBUF ;POINT TO DISK BUFF
- DKWRLP:
- PUSH H
- PUSH D
- PUSH B
- MVI C,STDMA ;SET DMA
- CALL BDOS ;TO BUFFER
- LXI D,FCB ;THEN WRITE
- MVI C,WRITE ;..THE..
- CALL BDOS ;..BLOCK
- POP B
- POP D
- POP H
- ORA A
- JNZ WRERR ;OOPS, ERROR
- LXI H,80H ;LENGTH OF 1 SECT
- DAD D ;HL= NEXT BUFF
- XCHG ;TO DE FOR SETDMA
- DCR C ;MORE SECTORS?
- JNZ DKWRLP ;..YES, LOOP
- XRA A ;GET A ZERO
- STA SECINBF ;RESET # OF SECTORS
- LXI H,DBUF ;RESET BUFFER..
- SHLD SECPTR ;..POINTER
- RET
- ;
- WRERR:
- CALL ERXIT ;EXIT W/MSG:
-
- DB '++ERROR WRITING CP/M FILE++',CR,LF,'$'
- ;
- ;
- ;
- ;----> PROCOPT: PROCESS COMMAND OPTIONS
- ;
- ;SAVES THE PROGRAM OPTION IN 'OPTION';
- ;
- PROCOPT:
- LXI D,FCB+1 ;TO PROGRAM OPT.
- LDAX D ;GET OPTION
- STA OPTION ;SAVE IT
- RET ;FROM 'PROCOPT'
- ;
- ;DONE - CLOSE UP SHOP
- ;
- DONE:
- CALL ILPRT
- DB CR,LF,'TRANSFER COMPLETE'
- DB CR,LF,0
- ;
- JMP EXIT ;DONE, GO BACK
- ;
- ;
- ;ROUTINE MOVES THE FILENAME FROM THE SECOND FCB
- ;TO THE FIRST
- ;
- MOVEFCB:
- LXI H,FCB+16 ;FROM
- LXI D,FCB ;TO
- MVI B,16 ;LEN
- CALL MOVE ;DO THE MOVE
- XRA A ;GET 0
- STA FCBSNO ;ZERO SECTOR #
- STA FCB ;..AND DRIVE DESIGNATOR
- STA FCBEXT ;..AND EXTENT
- RET
- ;
- ;
- ; MTX DOUBLE DENSITY FLOPPY DISK ACCESS ROUTINE FOR DRIVE B:
- ; ON AN ICOM 3812 RUNNING LIFEBOAT CP/M VER 1.4
- ;
- ;
- ;
- ;----> MRDSEC: READS A GIVEN SECTOR ACCORDING
- ; TO MTX CONVENTION. REGISTER PAIR (HL)
- ; CONTAINS THE LOGICAL SECTOR NUMBER.
- ;
- MRDSEC:
- CALL MTXSCAL ;GET OURSELVES A TRACK AND SECTOR
- PUSH H ;SAVE SECTOR NUMBER
- PUSH B ;SAVE TRACK NUMBER
- MVI C,01H ;LETS SELECT B: FOR MTX ACCESS
- CALL SELDSK ;LET BIOS SELECT DISK
- POP B ;GET TRACK NUMBER FOR NEXT CALL
- MOV C,B
- CALL SETTRK ;HAVE BIOS HANDLE TRACK SEEK
- LXI B,MTXBUF ;SET DMA ADDRESS FOR BUFFER
- CALL SETDMA
- POP H ;GET SECTOR NUMBER
- MOV C,L ;PUT FOR BIOS
- PUSH B ;SAVE FOR 2ND 128 BYTES
- CALL SETSEC ;BIOS POINT TO FIRST HALF
- CALL RDSEC ;READ THE SECTOR INTO BUFFER
- ORA A ;LOOK TO SEE IF READ ERROR
- JNZ MRDER ;TELL OF MTX READ ERROR
- LXI B,MTXBUF+128
- CALL SETDMA ;FIX DMA ADDR FOR 2ND HALF
- POP B ;FIX FOR SEC +1 TO GET 2ND HALF
- INR C
- CALL SETSEC
- CALL RDSEC ;READ 2ND HALF
- ORA A ;LOOK AGAIN TO SEE IF READ ERROR
- JNZ MRDER
- RET ;GO BACK IF NO ERRORS DETECTED
- ;
- ;MTX DISK READ ERROR
- ;
- MRDER:
- CALL ERXIT
- DB '++MTX DISK READ ERROR++$'
- ;
- ;
- ;----> MWRSEC: WRITES A GIVEN SECTOR ACCORDING
- ; TO MTX CONVENTION. REGISTER PAIR (HL)
- ; CONTAINS THE LOGICAL SECTOR NUMBER.
- ;
- ;
- MWRSEC:
- CALL MTXSCAL ;GET OURSELVES A TRACK AND SECTOR
- PUSH H ;SAVE SECTOR NUMBER
- PUSH B ;SAVE TRACK NUMBER
- MVI C,01H ;LETS SELECT B: FOR MTX ACCESS
- CALL SELDSK ;LET BIOS SELECT DISK
- POP B ;GET TRACK NUMBER FOR NEXT CALL
- MOV C,B
- CALL SETTRK ;HAVE BIOS HANDLE TRACK SEEK
- LXI B,MTXBUF ;SET DMA ADDRESS FOR BUFFER
- CALL SETDMA
- POP H ;GET SECTOR NUMBER
- MOV C,L ;PUT FOR BIOS
- PUSH B ;SAVE FOR 2ND 128 BYTES
- CALL SETSEC ;BIOS POINT TO FIRST HALF
- CALL WRTSEC ;WRITE THE SECTOR FROM BUFFER
- ORA A ;LOOK TO SEE IF WRITE ERROR
- JNZ MWRER ;TELL OF MTX WRITE ERROR
- LXI B,MTXBUF+128
- CALL SETDMA ;FIX DMA ADDR FOR 2ND HALF
- POP B ;FIX FOR SEC +1 TO GET 2ND HALF
- INR C
- CALL SETSEC
- CALL WRTSEC ;WRITE 2ND HALF
- ORA A ;LOOK AGAIN TO SEE IF WRITE ERROR
- JNZ MWRER
- RET ;GO BACK IF NO ERRORS DETECTED
- ;
- ;MTX DISK WRITE ERROR
- ;
- MWRER:
- CALL ERXIT
- DB '++MTX DISK WRITE ERROR++$'
- ;
- ;
- ;----> MTXSCAL: TRANSLATES MTX LOGICAL SECTOR TO
- ; TRACK AND PHYSICAL SECTOR NUMBERS
- ;
- ; ENTRY WITH DOUBLE BYTE LOGICAL SECTOR
- ; NUMBER IN (HL).
- ; EXIT WITH TRACK IN (B) AND PHYSICAL SECTOR
- ; IN (L)
- ;
- ; NOTE THAT THE SUBSEQUENT ROUTINE WILL HAVE
- ; READ SECTORS (L) AND (L+1) TO OBTAIN ALL OF
- ; THE MTX SECTORS DATA.
- ;
- MTXSCAL:
- LXI D,-26 ;SET TO CALCULATE TRACK NUMBER
- MVI B,00H ;INITIAL TRACK COUNTER
- TRCLP1:
- INR B ;TRACK LOOP COUNTER INCREMENT
- DAD D ;SUBTRACT SECTOR NUMBERS MOD 26
- JC TRCLP1 ;LOOP IN SUBTRACT TILL WE UNDERFLOW
- ;
- LXI D,26 ;SET THE HL PAIR TO REAL LOGICAL SECTOR
- ; ON THIS TRACK
- DAD D
- ;
- XCHG ;PUT LOGICAL SECTOR IN DE FOR NOW
- LXI H,TRANTBL ;GET BASE OF TRANSLATION TABLE
- DAD D ;INDEX INTO TABLE
- MOV L,M ;GET PHYSICAL NUMBER
- RET
- ;
- ;
- ;MTX LOGICAL TO PHYSICAL SECTOR TRANSLATION TABLE
- ; TABLE ENTRIES ARE IN LOGICAL ORDER
- ; TRACK LOGICAL SECTOR ZERO MAPS TO PHYSICAL #1
- ; ALSO NOTE THAT THIS TABLE ASSUMES THAT DISK
- ; SOFTWARE THINKS TRACK HAS 52 128 BYTE SECTORS
- ;
- TRANTBL:
- DB 1
- DB 5
- DB 9
- DB 13
- DB 17
- DB 21
- DB 25
- DB 29
- DB 33
- DB 37
- DB 41
- DB 45
- DB 49
- DB 3
- DB 7
- DB 11
- DB 15
- DB 19
- DB 23
- DB 27
- DB 31
- DB 35
- DB 39
- DB 43
- DB 47
- DB 51
- ;
- ;
- ;----> INITADR: INIT'S CP/M BDOS ADDRESSES
- ;
- ;THIS ROUTINE FILLS IN THE ADDRESSES OF VARIOUS
- ;JUMP VECTOR ENTRY POINTS SO THAT CP/M BDOS
- ;IS BYPASSED WHILE ACCESSING THE MTX DISK
- ;IN DRIVE B: SO THAT THE MODIFIED LOGICAL
- ;SECTORING MAY BE USED.
- ;
- INITADR:
- LHLD 1 ;GET WARM BOOT ADDR
- LXI D,015H ;OFFSET TO HOME VECTOR
- DAD D ;TO HOME DISK ROUTINE
- SHLD HOME+1 ;SET INTERNAL HOME VECTOR
- LXI D,003H ;OFFSET TO NEXT VECTOR
- DAD D ;TO SELECT DISK ROUTINE
- SHLD SELDSK+1 ;SET INTERNAL SELDSK VECTOR
- DAD D ;TO SET TRACK ROUTINE
- SHLD SETTRK+1 ;SET INTERNAL SETTRK VECTOR
- DAD D ;TO SET SECTOR ROUTINE
- SHLD SETSEC+1 ;SET INTERNAL SETSEC VECTOR
- DAD D ;TO SET DMA ADDRESS ROUTINE
- SHLD SETDMA+1 ;SET INTERNAL SETDMA VECTOR
- DAD D ;TO READ SECTOR ROUTINE
- SHLD RDSEC+1 ;SET INTERNAL READ VECTOR
- DAD D ;TO WRITE SECTOR ROUTINE
- SHLD WRTSEC+1 ;SET INTERNAL WRITE VECTOR
- ;
- RET
- ;
- ;
- ;----> ENTRY POINTS FOR BIOS DISK ACCESS PRIMATIVES-ADDRESSES SETUP AT INIT
- ;
- HOME:
- JMP $-$ ;HOME DISK INTERNAL VECTOR
- SELDSK:
- JMP $-$ ;SELECT DISK INTERNAL VECTOR
- SETTRK:
- JMP $-$ ;SET TRACK INTERNAL VECTOR
- SETSEC:
- JMP $-$ ;SET SECTOR INTERNAL VECTOR
- SETDMA:
- JMP $-$ ;SET DMA ADDRESS INTERNAL VECTOR
- RDSEC:
- JMP $-$ ;READ SECTOR INTERNAL VECTOR
- WRTSEC:
- JMP $-$ ;WRITE SECTOR INTERNAL VECTOR
- ;
- ;
- ;
- ;SETUP A DATA BUFFER FOR MTX SECTOR WHICH IS 256 BYTES LONG
- ;IT TAKES TWO CP/M 1.4 128 BYTE SECTOR READS TO FILL THE
- ;MTX LOGICAL SECTOR BUFFER.
- ;
- DS 20 ;DUMMY BUFFER PAD
- MTXBUF:
- DS 256 ;MTX READ DATA BUFFER
- DS 20 ;BUFFER PAD
- ;
- ;
- ;
- ;
- ;----> KEYIN: GETS A KEY CODE IN FROM CONSOLE
- ;
- KEYIN:
- PUSH B ;SAVE..
- PUSH D ;..ALL..
- PUSH H ;..REGS
- MVI C,RDCON ;GET CONSOLE CHARACTER FUNCTION CODE
- CALL BDOS ;GET CHARACTER
- MOV A,E
- POP H ;RESTORE..
- POP D ;..ALL..
- POP B ;..REGS
- RET
- ;
- ;
- ;----> CTYPE: TYPES VIA CP/M SO TABS ARE EXPANDED
- ;
- CTYPE:
- PUSH B ;SAVE..
- PUSH D ;..ALL..
- PUSH H ;..REGS
- MOV E,A ;CHAR TO E
- MVI C,WRCON ;GET BDOS FNC
- CALL BDOS ;PRIN THE CHR
- POP H ;RESTORE..
- POP D ;..ALL..
- POP B ;..REGS
- RET ;FROM "CTYPE"
- ;
- CRLF:
- MVI A,CR
- CALL CTYPE
- MVI A,LF
- CALL CTYPE
- RET
- ;
- ;
- ;HEX OUTPUT
- ;
- HEXO:
- PUSH PSW ;SAVE FOR RIGHT DIGIT
- RAR ;RIGHT..
- RAR ;..JUSTIFY..
- RAR ;..LEFT..
- RAR ;..DIGIT..
- CALL NIBBL ;PRINT LEFT DIGIT
- POP PSW ;RESTORE RIGHT
- CALL NIBBL ;PRINT RIGHT DIGIT
- RET
- ;
- ;
- NIBBL:
- ANI 0FH ;ISOLATE DIGIT
- CPI 10 ;IS IS <10?
- JC ISNUM ;YES, NOT ALPHA
- ADI 7 ;ADD ALPHA BIAS
- ISNUM:
- ADI '0' ;MAKE PRINTABLE
- CALL CTYPE ;..THEN TYPE IT
- RET
- ;
- ;
- ;----> ILPRT: INLINE PRINT OF MSG
- ;
- ;THE CALL TO ILPRT IS FOLLOWED BY A MESSAGE,
- ;BINARY 0 AS THE END. BINARY 1 MAY BE USED TO
- ;PAUSE (MESSAGE 'PRESS RETURN TO CONTINUE')
- ;
- ILPRT:
- XTHL ;SAVE HL, GET HL=MSG
- ILPLP:
- MOV A,M ;GET CHAR
- ORA A ;END OF MSG?
- JZ ILPRET ;..YES, RETURN
- CPI 1 ;PAUSE?
- JZ ILPAUSE ;..YES
- CALL CTYPE ;TYPE THE CHARACTER OF MESSAGE
- ILPNEXT:
- INX H ;TO NEXT CHAR
- JMP ILPLP ;LOOP
- ;
- ;PAUSE WHILE TYPING HELP SO INFO DOESN'T
- ; SCROLL OFF OF VIDEO SCREENS
- ;
- ILPAUSE:
- CALL ILPRT ;PRINT:
-
- DB CR,LF,'PRESS RETURN TO CONTINUE OR ^C TO EXIT'
- DB CR,LF,0
- CALL KEYIN ;GET ANY CHAR
- CPI 'C'-40H ;REBOOT?
- JZ EXIT ;YES.
- JMP ILPNEXT ;LOOP
- ;
- ILPRET:
- XTHL ;RESTORE HL
- RET ; & RETURN ADDR PAST MESSAGE
- ;
- ;----> PRTMSG: PRINTS MSG POINTED TO BY (DE)
- ;
- ;A '$' IS THE ENDING DELIMITER FOR THE PRINT.
- ;NO REGISTERS SAVED.
- ;
- PRTMSG:
- MVI C,PRINT ;GET BDOS FNC
- JMP BDOS ;PRINT MESSAGE, RETURN
- ;
- ;----> ERXIT: EXIT PRINTING MSG FOLLOWING CALL
- ;
- ERXIT:
- POP D ;GET MESSAGE
- CALL PRTMSG ;PRINT IT
- ;
- EXIT:
- MVI C,00H ;SET SELECTED UNIT BACK TO A:
- CALL SELDSK
- LXI D,080H ;RESET DEFAULT DMA ADDRESS FOR EXIT
- MVI C,STDMA
- CALL BDOS
- LHLD STACK ;GET ORIGINAL STACK
- SPHL ;RESTORE IT
- JMP WBOOT ;GO DO A WARM BOOT OF CP/M SO THIS
- ;THING WILL WORK IN A SUBMIT FILE
- ;
- ;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
- ;
- ;
- ;COMPARE FROM (HL) TO (DE) FOR (B) BYTES
- ;RETURN WITH A REGISTER:
- ; =00 IF NO COMPARE
- ; =FF IF VALID COMPARE
- ;
- COMPARE:
- LDAX D ;GET A CHAR
- CMP M ;CHECK AGAINST OTHER
- JNZ COMFAL ;GO EXIT FOR FAIL
- INX H ;INCREMENT COMPARE POINTERS
- INX D
- DCR B ;DECREMENT CHAR COUNT
- JNZ COMPARE ;MORE?
- MVI A,0FFH ;EXIT FOR GOOD COMPARE
- RET
- COMFAL:
- XRA A ;EXIT FOR NON COMPARE
- RET
- ;
- ;
- ;----> BINASC: CONVERTS A 16 BIT BINARY NUMBER TO ASCII
- ; INPUT NUMBER ASSUMED TO BE IN HL AND
- ; OUTPUT ASCII 5 CHARACTER BUFFER IS POINTED
- ; TO BY DE. MAXIMUM NUMBER FOR CONVERSION IS
- ; THE EQUIVALENT OF 16 BITS BINARY.
- ;
- BINASC:
- PUSH PSW ;SAVE REGISTERS
- PUSH B
- PUSH D
- LXI B,004H ;FIX DE TO POINT TO END OF BUFFER
- XCHG
- DAD B
- XCHG
- PUSH D ;SAVE ASCII POINTER
- MVI A,05H ;GET A DIGIT COUNT
- STA DIGCNT
- NDIG:
- LXI B,-10 ;RADIX FOR CONVERSION
- LXI D,-1 ;THIS BECOMES NO DIVIDED BY RADIX
- DX:
- DAD B ;SUBTRACT 10
- INX D
- JC DX
- LXI B,10
- DAD B ;ADD RADIX BACK IN ONCE
- XCHG
- MOV A,E
- ADI '0' ;CONVERT FROM BCD TO ASCII
- POP D ;GET ASCII BUFFER POINTER
- STAX D ;STORE ASCII CHARACTER
- DCX D ;ADJUST ASCII POINTER
- LDA DIGCNT ;CHECK IF CONVERSION DONE
- DCR A
- JZ DDIG ;EXIT IF DONE
- STA DIGCNT
- PUSH D ;SAVE ASCII POINTER
- JMP NDIG ;GO DO NEXT DIGIT
- DDIG:
- POP D ;RESTORE REGISTERS
- POP B
- POP PSW
- RET
- ;
- ;
- ;BINASC ROUTINE STORAGE ALLOCATIONS
- ;
- DIGCNT DB 00 ;PLACE TO STORE ASCII DIGIT COUNT
- ;
- ;
- ;
- ;
- ; ----------------
- ;
- ;PROGRAM DATA AREA SPACE ALLOCATIONS
- ;
- OPTION DB 0 ;PROGRAM OPTION
- ;
- ;
- ;FOLLOWING 3 USED BY THE CP/M DISK BUFFERING ROUTINES
- ;
- EOFLG DB 0 ;EOF FLAG (1=TRUE)
- SECPTR DW DBUF
- SECINBF DB 0 ;# OF SECTORS IN BUFFER
- ;
- ;
- ;MTX FILE HANDLER PARAMETER STORAGE LOCATIONS
- ;
- DS 20
- MDENT DS 16 ;TEMPORARY STORAGE FOR A DIRECTORY ENTRY
- DS 20
- ;
- ;
- ;SETUP A STACK AREA
- ;
- DS 400 ;STACK AREA
- STACK DS 2 ;STACK POINTER
- ;
- ;+++++++++
- ;+++++++++
- ;++
- ;++ NOTE: THE FOLLOWING DISK DATA BUFFERS ARE ALLOCATED
- ;++ OVER THE HELP FILE AND NON DISK I/O SOFTWARE
- ;++
- ;+++++++++
- ;+++++++++
- ;
- ;
- ;16 SECTOR CP/M DISK BUFFER
- ;
- DS 20
- DBUF EQU $+1 ;16 SECTOR CP/M DISK BUFFER
- ;
- ;INVALID COMMAND
- ;
- BADOPT:
- PUSH PSW ;SAVE BAD OPTION
- MVI A,'['
- CALL CTYPE
- POP PSW
- CALL CTYPE
- CALL ILPRT ;EXIT W/ERROR
- DB '] INVALID OPTION FOR PROGRAM SELECTION '
- DB 'COMMAND - ',CR,LF
- DB 'PRESS CTL-C TO ABORT',1,0
- ;
- HELP:
- CALL ILPRT
- DB CR,LF,CR,LF,'FORMAT FOR COMMAND IS:',CR,LF,CR,LF
- DB 'MTX # FILENAME',CR,LF,CR,LF
- DB 'WHERE # IS A 1 CHARACTER PROGRAM OPTION,',CR,LF
- DB 'PROGRAM OPTIONS:',CR,LF
- DB ' R TO READ AN MTX FILE FROM B:',CR,LF
- DB ' W TO WRITE AN MTX FILE TO B:',CR,LF
- DB ' D TO VIEW THE MTX DIRECTORY ON B:',CR,LF
- DB ' H TO PRINT THIS HELP FILE',CR,LF,CR,LF,0
- JMP EXIT
- ;
- ;
- ; BDOS EQUATES (VERSION 2)
- ;
- RDCON EQU 1
- WRCON EQU 2
- PRINT EQU 9
- CONST EQU 11 ;CONSOLE STAT
- OPEN EQU 15 ;0FFH=NOT FOUND
- CLOSE EQU 16 ; " "
- SRCHF EQU 17 ; " "
- SRCHN EQU 18 ; " "
- ERASE EQU 19 ;NO RET CODE
- READ EQU 20 ;0=OK, 1=EOF
- WRITE EQU 21 ;0=OK, 1ERR, 2=?, 0FFH=NO DIR SPC
- MAKE EQU 22 ;0FFH=BAD
- REN EQU 23 ;0FFH=BAD
- STDMA EQU 26 ;SET DMA
- BDOS EQU 5
- REIPL EQU 0
- FCB EQU 5CH ;SYSTEM FCB
- FCBEXT EQU FCB+12 ;FILE EXTENT
- FCBSNO EQU FCB+32 ;SECTOR #
- FCB2 EQU 6CH ;SECOND FCB
- END
-