home *** CD-ROM | disk | FTP | other *** search
- ;
- ; TITLE CP/M SPEED-UP BY DISK I/O BUFFERING
- ; FILENAME FAST.ASM
- ; AUTHOR Robert A. Van Valzah 12/25/78
- ; LAST REVISED 8-Oct-1981 David Bennett
- ; REASON Upgrade to CP/M 2.0 compatibility
- ;
- ;
- ; \\\\\\\\\\\\\\\\\ /////////////////
- ; >>>>>>>>>>>>>>>>> E Q U A T E S <<<<<<<<<<<<<<<<<
- ; ///////////////// \\\\\\\\\\\\\\\\\
- ;
- BASE EQU 100H ;ORG FOR THIS ASSEMBLY OF FAST
- VERS EQU 201 ;FAST VERSION NUMBER
- ;
- ; CP/M SYSTEM ENTRY POINTS AND RAM EQUATES
- ;
- BOOT EQU 0 ;ADDRESS OF WARM BOOT VECTOR
- CURDSK EQU 4 ;ADDRESS OF CURRENTLY LOGGED DRIVE
- BDOS EQU 5 ;ADDRESS OF BDOS ENTRY VECTOR
- DBUF EQU 80H ;BUFFER USED FOR COMMAND LINE HOLDING
- TPA EQU 100H ;TRANSIENT PROGRAM AREA
- ;
- ; GLOBAL EQUATES
- ;
- SECLEN EQU 80H ;LENGTH OF A SECTOR IN BYTES
- DIRTRK EQU 2 ;TRACK WHICH HOLDS DIRECTORY
- ;
- ; TOKEN VALUE EQUATES
- ;
- SENTTOK EQU 1 ;TOKEN SHOWING DRIVE & TRACK INFO SENT
- UPDTTOK EQU 1 ;TOKEN SHOWING SECTOR GETS WRITTEN
- ONLNTOK EQU 3 ;TOKEN SHOWING THAT A DRIVE IS 'ON LINE'
- ;
- ; ASCII CHARACTER EQUATES
- ;
- CR EQU 13 ;CARRIAGE RETURN
- LF EQU 10 ;LINE FEED
- ;
- ; BDOS FUNCTION NUMBER EQUATES
- ;
- READ EQU 20 ;READ A RECORD FROM A FILE
- OPEN EQU 15 ;OPEN A FILE FOR READING
- SETDMA EQU 26 ;CHANGE DMA ADDRESS
- PAGE
- ;
- ;
- ; \\\\\\\\\\\\\\\\ ////////////////
- ; >>>>>>>>>>>>>>>> M A C R O S <<<<<<<<<<<<<<<<
- ; //////////////// \\\\\\\\\\\\\\\\
- ;
- $-MACRO
- ;
- ; THE CPM MACRO CALLS BDOS TO EXECUTE THE FUNCTION PASSED
- ; AS THE FIRST ARGUMENT. THE SECOND ARGUMENT IS THE
- ; 'INFORMATION' TO PASSED TO CP/M (IF ANY).
- ;
- CPM MACRO FUNC,INFO
- MVI C,FUNC
- IF NOT NUL INFO
- LXI D,INFO
- ENDIF
- CALL BDOS
- ENDM
- PAGE
- ;
- ; \\\\\\\\\\\\\\\\ F A S T ////////////////
- ; >>>>>>>>>>>>>>>> I N I T <<<<<<<<<<<<<<<<
- ; //////////////// M O D U L E \\\\\\\\\\\\\\\\
- ;
- ;
- ; THIS MODULE MAY BE COMPLETELY OVERLAID ONCE FAST HAS BEEN
- ; SUCCESSFULLY INSTALLED IN THE SYSTEM. IT BECOMES PART OF
- ; THE TPA.
- ;
- ;
- ; CONTROL IS TRANSFERED TO THIS ADDRESS (THE BASE OF FAST)
- ; UPON COMPLETION OF THE PACKUP MODULE. HERE, WE INSTALL
- ; FAST AND LOAD THE TRANSIENT.
- ;
- ORG BASE
- JMP FASTNTRY ;JUMP AROUND FIRST PARAMETER BLOCK
- ;
- ; THIS IS THE FIRST (OF TWO) PARAMETER PASSING BLOCKS.
- ; INFORMATION IS PASSED BETWEEN THE FAST AND PACKUP MODULES.
- ; ANY CHANGES MADE TO THIS BLOCK MUST ALSO BE MADE TO THE
- ; CORRESPONDING BLOCK IN THE PACKUP MODULE.
- ;
- ;**************************************************************
- ; *
- LEN: ; *
- DW CODELEN ;RELOCATION LENGTH *
- ; *
- FCB: ;FCB USED TO LOAD COM FILE *
- DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; *
- DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; *
- ; *
- ;**************************************************************
- ;
- ; END OF FIRST PARAMETER BLOCK
- ;
- FASTNTRY:
- LXI SP,STACK ;USE LOCAL STACK SPACE
- CALL LINKUP ;INSTALL FAST BY LINKING TO CP/M
- LDA CURDSK ;INIT DDB POINTERS TO CURRENT DRIVE
- MOV C,A
- CALL FSETDSK
- CALL LOADTRAN ;LOAD THE TRANSIENT
- CALL MSGP ;PRINT FAST SIGNON MESSAGE
- DB 'Alfred Hospital FAST '
- ;DEFINE VERSION NUMBER IN ASCII
- DB '0'+vers/100
- db '.'
- DB '0'+(VERS/10) mod 10
- DB '0'+VERS MOD 10
- DB CR, LF+80H
- JMP BEGINE ;BEGIN EXECUTION OF TRANSIENT
- PAGE
- ;
- ; LINKUP INSTALLS FAST IN A CP/M SYSTEM IN TWO STEPS.
- ; INTERNALLY REFERENCED ROUTINE.
- ; FIRST, THE EXISTING BIOS JUMP TABLE IS SAVED AND IT IS
- ; REPLACED WITH A JUMP TABLE INTO FAST, AND
- ; SECOND, THE BDOS VECTOR IS MODIFIED TO JUMP TO THE BASE OF
- ; FAST, WHICH, IN TURN, JUMPS TO THE REAL BDOS. THUS,
- ; TRANSIENTS THINK THE TPA ENDS BELOW FAST INSTEAD OF BELOW
- ; BDOS.
- ;
- LINKUP:
- ; STEP 1
- LDA BOOT+2 ;GET BIOS BASE ADDRESS INTO DE
- MOV D,A
- MVI E,0
- PUSH D ;SAVE FOR SECOND PART OF TRANSFER
- LXI H,SAVEJMP
- MVI C,jtablen ;length of jump table
- CALL XF1 ;MOVE FROM BIOS INTO SAVEJMP
- ;REPLACE OLD TABLE WITH LINK TO FAST
- LXI D,FASTLINK
- POP H
- MVI C,jtablen
- CALL XF1 ;MOVE FROM FAST LINK INTO BIOS
- ; STEP 2
- LHLD BDOS+1 ;GET CURRENT BDOS BASE ADDRESS
- SHLD NEWBVECT+1 ;COPY IT INTO THE NEW BDOS VECTOR
- LXI H,NEWBVECT ;MODIFY BDOS VECTOR TO JMP TO
- SHLD BDOS+1 ;NEW BDOS VECTOR
- RET
- ;
- ; LOADTRAN LOAD THE TRANSIENT NAMED IN THE ARGUMENT TO FAST
- ; INTO THE TPA WITH CHECKING FOR OVERLAY (LOAD ERROR -
- ; TRANSIENT TOO BIG OR TPA TOO SMALL).
- ; RETURNS ONLY IF LOAD WENT OK. BAILS OUT WITH ERROR MESSAGE
- ; VIA UNLINK OTHERWISE.
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- LOADTRAN:
- LXI D,TPA ;SET DMA ADDRESS INTO TPA FOR OPEN
- PUSH D ;SAVE DMA ADDRESS FOR INCREMENTING
- CPM SETDMA
- CPM OPEN,FCB ;OPEN THE COM FILE
- INR A ;WAS OPEN SUCCESSFULL?
- JZ NOCMERR ;NO - ISSUE NO COM FILE ERROR
- READSEC:
- POP D ;GET DMA ADDRESS FROM STACK
- PUSH D ;AND SAVE BACK FOR LATER
- MVI A,HIGH (BASE-100H) ;MAX ALLOWABLE DMA ADDRESS
- CMP D ;IS COM FILE TOO BIG?
- JC LOADERR ;YES - ISSUE LOAD ERROR
- CPM SETDMA ;PASS DMA ADDRESS TO CP/M
- POP D ;INCREMENT DMA ADDRESS BY ONE SECTOR
- LXI H,SECLEN
- DAD D
- PUSH H ;PUT NEW DMA ADDRESS BACK
- CPM READ,FCB ;READ A SECTOR FROM COM FILE INTO TPA
- ORA A ;WAS READ OK?
- JZ READSEC ;YES - KEEP READING
- ;NOPE - ALL DONE LOADING
- CPM SETDMA,DBUF ;SET DMA ADDRESS LIKE CCP WOULD
- POP B ;CLEAN GARBAGE DMA ADDRESS OFF STACK
- RET
- ;
- LOADERR:
- CALL MSGP ;PRINT LOAD ERROR MESSAGE
- DB 'OUT OF MEMOR', 'Y'+80H
- JMP UNLINK ;RETURN TO CP/M
- ;
- NOCMERR:
- CALL MSGP ;PRINT 'NO COM FILE'
- DB 'NO COM FIL', 'E'+80H
- JMP UNLINK ;RETURN TO CP/M
- ;
- ; END OF INIT MODULE
- PAGE
- ;
- ; \\\\\\\\\\\\\\\\ ////////////////
- ; >>>>>>>>>>>>>>>> F A S T <<<<<<<<<<<<<<<<
- ; //////////////// M O D U L E \\\\\\\\\\\\\\\\
- ;
- ;
- ; THIS MODULE CONTAINS THE ACTUAL DISK I/O BUFFERING CODE.
- ;
- ; THIS ADDRESS BECOMES THE NEW TOP OF THE TPA.
- ;
- ORG (($-1) OR 255) + 1 ;ORG TO PAGE BOUNDRY
- DS 6 ;SO BDOS VECTOR ADDRESS = XXX6
- NEWBVECT:
- JMP $-$ ;ADDRESS WILL BE MODIFIED BY LINKUP
- ;
- ; DDB ADDRESS BUFFERS. EACH BUFFER IS FOUR W-O-R-D-S LONG,
- ; ONE WORD FOR THE ADDRESS OF THE BUFFER FOR EACH OF FOUR
- ; POSSIBLE DRIVES. IF THERE IS NO DDB FOR A GIVEN DRIVE,
- ; THE DDB ADDRESS IS ZERO.
- ;
- RDBUF DW 0, 0, 0, 0
- WRBUF DW 0, 0, 0, 0
- DIRBUF DW 0, 0, 0, 0
- ;
- ; 8-10-81 upgrade to CP/M compatibility
- ; when off-line disc is first used, BIOS routine SETDSK is called
- ; CP/M 2.x BIOS returns a vital parameter in HL, which must be
- ; passed back to BDOS. It is stored here for that purpose.
- ;
- online dw 0, 0, 0, 0 ; stored HL return from SETDSK
- ;
- ; USER PATCHABLE MEMORY HIT (ERROR) ROUTINE
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- MEMHIT:
- PUSH D ! PUSH B ;SAVE REGISTERS
- CALL MSGP
- DB 'MEMORY HI', 'T'+80H
- POP B ! POP D
- RET
- ;
- FASTLINK: ;JMP TABLE TO REPLACE EXISTING BIOS'S
- JMP UNLINK ;FOR EITHER BOOT, REMOVE FAST AND BOOT
- JMP UNLINK
- JMP CCONST ;JUST PASS ALL CHARACTER I/O THRU
- JMP FCONIN ;EXCEPT CONSOLE IN
- JMP CCONOUT
- JMP CLIST
- JMP CPUNCH
- JMP CREADER
- JMP FHOME ;USE FAST HOME INSTEAD OF BIOS
- JMP FSETDSK ;USE FAST SET DISK
- JMP FSETTRK ;USE FAST SET TRACK
- JMP FSETSEC ;USE FAST SET SECTOR
- JMP FSETDMA ;USE FAST SET DMA
- JMP FREAD ;USE FAST READ SECTOR
- JMP FWRITE ;USE FAST WRITE SECTOR
- jtablen equ $-fastlink
- ;
- ;
- BEGINE: ;ENTRY POINT FROM INIT TO EXEC. TRANS.
- CALL TPA ;EXECUTE TRANS.
- ;IF HE RETURNS, FALL THRU TO UNLINK
- ;
- ; UNLINK IS THE COMPLIMENTARY ROUTINE TO LINKUP. IT RESTORES
- ; THE BIOS JUMP TABLE AND THE BDOS VECTOR TO THEIR STATES
- ; BEFORE FAST WAS INSTALLED (BY LINKUP).
- ; INTERNALLY AND EXTERNALLY REFERENCED ROUTINE.
- ;
- UNLINK:
- LXI SP,STACK ;SETUP LOCAL STACK
- ;RETURN BIOS VECTORS UNHARMED
- LXI D,SAVEJMP
- LDA BOOT+2 ;GET BIOS BASE INTO DE
- MOV H,A
- MVI L,0
- MVI C,jtablen ;length of jump table
- CALL XF1 ;MOVE FROM SAVEJMP TO BIOS BASE
- LHLD NEWBVECT+1 ;GET REAL BDOS VECTOR ADDRESS
- SHLD BDOS+1 ;STORE IT INTO REAL BDOS VECTOR
- CALL CLOSE ;EMPTY ANY DDB'S WHICH MAY HAVE DATA
- CALL MSGP ;PRINT FAST SIGN OFF MESSAGE
- DB CR, LF
- DB 'FAST terminate', 'd'+80H
- JMP BOOT ;AND REBOOT
- ;
- ; FAST CONSOLE IN
- ; EXTERNALLY REFERENCED ROUTINE
- ; WRITES ALL SECTORS WAITING TO BE WRITTEN SO THAT USER
- ; CAN'T GET HIMSELF INTO TROUBLE BY REMOVING THE DISK
- ; EXTERNALLY REFERENCED ROUTINE.
- ;
- FCONIN:
- CALL CLOSE ;WRITE ALL DDB'S
- JMP CCONIN ;NOW DO THE CONSOLE INPUT
- ;
- ; FAST HOME ROUTINE
- ; INTERNALLY AND EXTERNALLY REFERENCED
- ;
- FHOME:
- MVI C,0 ;JUST PASS 0 TO FAST SET TRACK
- ;FALL THRU
- ;
- ; FAST SET TRACK
- ; EXTERNALLY REFERENCED ROUTINE
- ; REQUESTED TRACK IS JUST STORED AWAY UNTIL
- ; A READ OR WRITE REQUEST COMES IN.
- ;
- FSETTRK:
- MOV A,C ;GET REQUEST TO REG A
- STA REQTRK ;STORE IT
- RET
- ;
- ; FAST SET SECTOR
- ; EXTERNALLY REFERENCED ROUTINE
- ; THE REQUESTED SECTOR IS JUST
- ; STORED AWAY UNTIL A READ OR WRITE COMES IN.
- ;
- FSETSEC:
- MOV A,C ;GET REQUESTED SECTOR TO REG A
- STA REQSEC ;STORE IT
- RET
- ;
- ; FAST SET DMA ADDRESS
- ; EXTERNALLY REFERENCED ROUTINE.
- ;
- FSETDMA:
- MOV H,B ;REQUESTED DMA ADR INTO HL
- MOV L,C
- SHLD REQDMA ;SAVE IT
- RET
- ;
- ; FAST SET DISK DRIVE
- ; EXTERNALLY REFERENCED ROUTINE
- ;
- FSETDSK:
- MOV E,C ;SAVE DRIVE FOR ON LINE CODE
- MOV A,C ;GET REQUESTED DRIVE
- STA REQDSK ;SAVE FOR PASS THRU
- ADD A
- MOV C,A ;FORM word INDEX IN REG BC
- MVI B,0
- LXI H,DIRBUF ;GET NEW DIR DDB POINTER
- CALL INDXIND
- SHLD DIRADR ;AND SAVE IT
- LXI H,RDBUF ;GET NEW READ TRACK DDB POINTER
- CALL INDXIND
- SHLD RDADR ;AND SAVE IT
- LXI H,WRBUF ;GET NEW WRITE TRACK DDB POINTER
- CALL INDXIND
- SHLD WRADR
- LXI H,ONLINE ;BASE OF 'ON LINE' VECTOR
- call indxind
- MOV A,h ;IS THIS DRIVE ON LINE?
- ORA l
- RNZ ;->yes, return to BDOS with HL set
- ; get this drive on-line
- push b ;preserve word index into table
- mov c,e
- CALL CSETDSK ;first, really select it
- pop b
- mov a,h ;check the return in HL
- ora l
- rz ;->zero is error, return to BDOS with HL zero
- push h ;ok, save (HL)
- lxi h,online;..in online table
- dad b ;..word-indexed by drive number
- pop b
- mov m,c
- inx h
- mov m,b
- push b ;we still need this for later
- lda reqdsk ;get disc again, home it
- mov c,a
- CALL CHOME
- LHLD DIRADR ;AND READ THE DIRECTORY IF IT IS BUFFERED
- call RDDDB
- pop h
- ret ;return to BDOS with HL set
- ;
- ; FAST READ SECTOR
- ; EXTERNALLY REFERENCED ROUTINE.
- ;
- FREAD:
- LHLD RDADR ;GET ADDRESS OF READ TRACK DDB
- CALL GETSEC ;TRY TO FIND SECTOR IN READ DDB
- RC ;FOUND IT
- LHLD DIRADR ;TRY TO FIND SECTOR IN DIRECTORY DDB
- CALL GETSEC
- RC ;FOUND IT
- LHLD WRADR ;TRY TO FIND SECTOR IN WRITE DDB
- CALL GETWSEC
- RC ;FOUND IT
- LHLD RDADR ;SEE IF THERE IS A READ TRACK BUFFER
- MOV A,H
- ORA L
- JZ RDPASS ;NO - THEN JUST PASS THE READ THRU
- LDA REQTRK ;YES - SEE IF READING FROM NON-DIRECTORY
- CPI DIRTRK ;SECTORS OF DIRECTORY TRACK
- JZ RDPASS ;YES - JUST LET THAT PASS THRU
- PUSH PSW ;NO - WRITE ANY DATA IN READ BUFFER
- PUSH H
- CALL WRDDB
- POP H
- POP PSW
- MOV M,A ;FILL NEW TRACK INTO READ DDB
- PUSH H ;SAVE READ DDB ADDRESS
- CALL RDDDB ;AND FILL NEW DDB WITH DATA
- POP H ;GET READ DDB ADDRESS BACK
- JMP GETSEC ;TRANSFER SECTOR FROM DDB TO CALLER
- ;AND RETURN FROM GETSEC
- ;
- ; FAST SECTOR WRITE
- ; EXTERNALLY REFERENCED ROUTINE.
- ;
- FWRITE:
- LHLD WRADR ;TRY TO PUT SECTOR INTO WRITE BUFFER
- CALL PUTSEC
- RC ;IT WENT - ALL DONE
- LHLD DIRADR ;TRY TO PUT IT INTO DIRECTORY BUFFER
- CALL PUTSEC
- RC ;IT WENT - ALL DONE
- LHLD RDADR ;TRY TO PUT INTO READ BUFFER
- CALL PUTSEC
- RC ;IT WENT - ALL DONE
- LHLD WRADR ;IS THERE A WRITE TRACK BUFFER?
- MOV A,H
- ORA L
- JZ WRPASS ;NO - JUST PASS THIS WRITE THRU
- LDA REQTRK ;YES - SEE IF THIS IS A NON-DIRECTORY
- CPI DIRTRK ;SECTOR ON THE DIRECTORY TRACK?
- JZ WRPASS ;YES - JUST PASS THAT THRU
- PUSH PSW ;NO - DUMP EXISTING WRITE BUFFER TO DISK
- PUSH H
- CALL WRDDB
- POP H
- POP PSW
- MOV M,A ;AND BUFFER UP REQUESTED TRACK
- CALL PUTSEC ;MOVE SECTOR INTO WRITE BUFFER
- LDA WRTERRF ;RETURN WRITE ERROR FLAG
- RET
- ;
- ; CLOSE ALL OPEN DDB'S. WRITE ANY DATA LEFT IN THEM OUT TO
- ; DISK
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- CLOSE:
- MVI C,4*3 ;DDB COUNT
- LXI H,RDBUF ;START OF DDB ADDRESS TABLES
- CLOS:
- MOV E,M ;GET DDB ADDRESS TO REG DE
- INX H
- MOV D,M
- INX H
- PUSH H ;SAVE TABLE ADDRESS
- PUSH B
- XCHG ;DDB ADDRESS TO REG HL
- CALL WRDDB ;CLOSE ONE DDB
- LDA WRTERRF ;ANY WRITE ERRORS IN CLOSING?
- ORA A
- JZ CLOSOK ;NO - KEEP CLOSING
- CALL MSGP
- DB 'DISK WRITE ERROR', CR, LF+80H
- CLOSOK:
- POP B ;GET COUNT
- POP H ;GET TABLE ADDRESS
- DCR C ;DONE ALL DDBS YET?
- JNZ CLOS ;NO - KEEP CLOSING
- RET ;YES - ALL DONE
- ;
- ; INDEXED INDIRECT ADDRESSING. RETURNS THE WORD AT THE
- ; ADDRESS BASE + INDEX
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- INDXIND:
- DAD B ;ADD IN INDEX
- MOV A,M ;GET LOW ORDER OF RESULT
- INX H
- MOV H,M ;GET HIGH ORDER OF RESULT
- MOV L,A
- RET
- ;
- ; GET A SECTOR FROM A WRITE DDB INTO REQDMA. MATCHES ONLY
- ; IF UPDATE FLAG IS SET. RETURNS FLAG IF FOUND.
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- GETWSEC:
- CALL SRCHDDB ;FIND A SECTOR AND TRACK MATCH?
- RNC ;NO - RETURN WITHOUT FLAG
- INX H ;YES - SEE IF SECTOR HAS BEEN
- MOV A,M ;WRITTEN (UPDATE FLAG=1)?
- ORA A
- JNZ GS1 ;YES - TRANSFER FROM WRITE DDB
- CALL RDPASS ;NO - BYPASS BUFFERING
- STC ;SET FOUND IT FLAG
- RET
- ;
- ; GET A SECTOR FROM A DDB INTO REQDMA. FLAG SET IF FOUND.
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- GETSEC:
- CALL SRCHDDB ;DO WE HAVE THE REQUESTED SECTOR?
- RNC ;NO - RETURN WITHOUT FLAG
- INX H ;YES - POINT TO SECTOR DATA
- GS1: ;ENTRY FROM GETWSEC (ABOVE)
- INX H
- XCHG ;DATA ADDRESS TO REG DE
- LHLD REQDMA ;DESTINATION TO REG HL
- CALL XFER ;PERFORM THE TRANSFER
- LDAX D ;GET GOOD/BAD FLAG
- STC ;SET 'FOUND IT' FLAG
- RET
- ;
- ; SEARCH A DDB FOR THE REQUESTED TRACK AND SECTOR
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- SRCHDDB:
- MOV A,H ;SEE IF DDB IS PRESENT AT ALL
- ORA L
- RZ ;NO - WE DON'T HAVE IT
- LDA REQTRK ;YES - SEE IF REQTRK MATCHES DDB TRACK
- XRA M
- RNZ ;NO MATCH - WE DON'T HAVE IT
- INX H ;TRACKS MATCH - CHECK SECTORS
- INX H
- LDA REQSEC
- MOV C,A
- LXI D,SECLEN+3 ;BYTES BETWEEN SECTOR NUMBERS
- SRCH1:
- MOV A,M ;GET A SECTOR NUMBER FROM DDB
- ORA A ;END OF DDB?
- RZ ;YES - RETURN WITHOUT FLAG
- CMP C ;NO - SEE IF REQSEC MATCHES DDB SECTOR
- STC ;PREPARE TO RETURN FLAG IF SO
- RZ ;THEY MATCH - RETURN FLAG
- DAD D ;NO MATCH - ON TO NEXT SECTOR
- JMP SRCH1
- ;
- RDPASS:
- CALL PASSTHRU
- JMP CREAD
- ;
- ; MOVE A SECTOR FROM MEMORY INTO A DDB
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- PUTSEC:
- CALL SRCHDDB ;DOES IT GO IN THIS DDB?
- RNC ;NO - RETURN WITHOUT FLAG
- INX H ;POINT TO DATA FIELD OF DDB
- MVI M,UPDTTOK ;SET UPDATE FLAG
- INX H
- XCHG ;SAVE DDB ADDRESS IN REG DE
- LHLD REQDMA ;GET SOURCE ADDRESS INTO REG HL
- XCHG ;NOW REG HL=DDB ADDRESS (DEST) AND . .
- CALL XFER ;REG DE=MEMORY (SOURCE)
- XRA A ;RETURN WITHOUT WRITE ERROR
- MOV M,A ;SET GOOD/BAD FLAG TO GOOD
- STC ;SET SECTOR PUT FLAG
- RET
- WRPASS:
- CALL PASSTHRU
- JMP CWRITE
- ;
- ; PASS ALL DISK I/O PARAMETERS THRU TO BIOS
- ; INTERNALLY REFERENCED ROUTINE
- ;
- PASSTHRU:
- LDA REQDSK ;PASS REQUESTED DISK THRU
- MOV C,A
- CALL CSETDSK
- LDA REQTRK ;PASS REQUESTED TRACK THRU
- MOV C,A
- CALL CSETTRK
- LDA REQSEC ;PASS REQUESTED SECTOR
- MOV C,A
- CALL CSETSEC
- LHLD REQDMA ;PASS REQUESTED DMA ADDRESS
- MOV B,H
- MOV C,L
- JMP CSETDMA ;RETURN FROM CSETDMA
- ;
- ; READ A DDB FROM DISK. ALL SECTORS ARE FILED IN, AND THEIR
- ; UPDATE FLAGS ARE RESET.
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- RDDDB:
- MOV A,H ;DO NOTHING FI NO DDB
- ORA L
- RZ
- PUSH H ;SAVE DDB ADDRESS
- CALL SENDDT ;SEND DRIVE AND TRACK INFO TO BIOS
- POP H ;GET DDB ADDRESS
- INX H ;POINT TO FIRST SECTOR BYTE
- INX H
- RDDSEC:
- MOV A,M ;GET SECTOR NUMBER
- ORA A ;END OF DDB?
- RZ ;YES - ALL DONE
- MOV C,A ;PASS SECTOR TO BIOS
- PUSH H ;SAVE WHILE CALLING
- CALL CSETSEC
- POP H ;GET DDB ADDRESS BACK
- INX H ;POINT TO UPDATE FLAG
- MVI M,0 ;RESET UPDATE FLAG
- INX H ;POINT TO DATA FIELD
- PUSH H ;SAVE DATA POINTER
- MOV B,H ;DATA ADDRESS TO REG BC
- MOV C,L
- CALL CSETDMA ;PASS DATA ADDRESS TO BIOS
- CALL CREAD ;PERFORM THE READ
- POP H ;GET DATA ADDRESS BACK
- LXI B,SECLEN ;BYTES TO GOOD/BAD FLAG
- DAD B
- MOV M,A ;STORE GOOD/BAD FLAG FROM BIOS IN DDB
- INX H
- JMP RDDSEC ;ON TO NEXT SECTOR
- ;
- ; WRITE A DDB BACK TO DISK. ONLY SECTORS WITH THE UPDATE FLAG
- ; SET GET WRITTEN.
- ; THE DRIVE AND TRACK INFORMATION FROM THE DDB IS SAVED BY
- ; THIS ROUTINE AND PASSED TO THE BIOS BY RCLDT ONLY IF
- ; A SECTOR IS TO BE WRITTEN. THIS IS DONE TO BYPASS BIOS
- ; DELAYS WHEN SWITCHING DRIVES AND TO PREVENT NEEDLESS
- ; SEEKING TO TRACKS WHICH MIGHT NOT RECIEVE ANY DATA.
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- WRDDB:
- XRA A ;CLEAR WRITE ERROR FLAG
- STA WRTERRF
- MOV A,H ;SEE IF A DDB IS PRESENT
- ORA L
- RZ ;NO - ALL DONE WRITING
- MOV A,M ;GET TRACK NUMBER
- INR A ;TRACK = 0FFH (MEANING EMPTY)?
- RZ ;YES - NO WRITING TO DO
- SHLD TRKPTR ;NO - SAVE DISK & TRACK POINTER FOR
- XRA A ;RECALL LATER, AND RESET FLAG
- STA SENTFLG ;SHOWING THAT THEY HAVEN'T BEEN SENT
- INX H ;POINT TO FIRST SECTOR NUMBER
- INX H
- TSTUPDT:
- MOV A,M ;GET SECTOR TO REG A
- ORA A ;END OF DDB?
- RZ ;YES - ALL DONE
- MOV C,A ;SAVE SECTOR IN REG C
- INX H ;POINT TO UPDATE FLAG
- MOV A,M ;GET UPDATE FLAG
- ORA A ;DOES THIS SECTOR NEED UPDATING ON DISK?
- CNZ WRSEC ;YES - WRITE IT BACK
- LXI D,SECLEN+2 ;BYTES TO NEXT SECTOR NUMBER
- DAD D
- JMP TSTUPDT ;CHECK THE NEXT UPDATE FLAG
- ;
- ; WRITE A SECTOR FROM A DDB BACK OUT TO DISK.
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- WRSEC:
- MVI M,0 ;RESET UPDATE FLAG
- PUSH H ;SAVE UPDATE FLAG POINTER
- CALL CSETSEC ;PASS SECTOR NUBER TO BIOS
- CALL RCLDT ;PASS DRIVE AND TRACK TO BIOS
- POP H ;GET UPDATE FLAG POINTER
- PUSH H ;AND SAVE AGAIN
- INX H ;POINT TO DATA
- MOV B,H ;DATA ADDRESS TO REG BC
- MOV C,L
- CALL CSETDMA ;PASS DMA ADDRESS TO BIOS
- CALL CWRITE ;WRITE THE DATA OUT
- LXI H,WRTERRF ;OR THIS WRITE ERROR FLAG IN WITH
- ORA M ;THE REST FROM THIS WRDDB
- MOV M,A
- POP H ;GET CALLERS REG HL BACK
- RET
- ;
- ; RECALL DISK AND TRACK INFO FROM A DDB, PASS IT TO THE BIOS,
- ; AND SET FLAG SHOWING THAT IS HAS BEEN SENT.
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- RCLDT:
- LXI H,SENTFLG ;HAS THIS INFO ALREADY BEEN SENT?
- MOV A,M
- ORA A
- RNZ ;YES - SKIP SENDING AGAIN
- MVI M,SENTTOK ;NO - SET FLAG SHOWING IT HAS BEEN SENT
- LHLD TRKPTR ;GET POINTER TO DRIVE & TRACK INFO
- ;AND FALL THRU TO SEND IT TO BIOS
- ;
- ; SEND DRIVE AND TRACK INFO FROM A DDB TO THE BIOS.
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- SENDDT:
- PUSH H ;SAVE TRACK POINTER
- INX H ;POINT TO DRIVE
- MOV C,M ;GET DRIVE TO REG C
- CALL CSETDSK ;PASS DISK
- POP H ;GET TRACK POINTER
- MOV C,M ;GET TRACK TO REG C
- JMP CSETTRK ;PASS TRACK AND RETURN FROM THERE
- ;
- ; MOVE A SECTOR FROM ONE PLACE IN MEMORY TO ANOTHER. GIVE
- ; ERROR MESSAGE IF DATA CAN'T BE WRITTEN INTO DESTINATION.
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- XFER:
- MVI C,SECLEN ;COUNT NUMBER OF BYTES TO XFER IN C
- XF1:
- LDAX D ;GET BYTE FROM SOURCE
- MOV M,A ;STORE INTO DESTINATION
- XRA M ;DID IT GO?
- CNZ MEMHIT ;NO - GIVE WARNING MESSAGE
- INX H ;INCREMENT DEST POINTER
- INX D ;INCREMENT SOURCE POINTER
- DCR C ;DONE WITH MOVE YET?
- JNZ XF1 ;NO - KEEP MOVING
- RET ;YES - ALL DONE
- ;
- ; LOCAL MESSAGE PRINTER. WE CAN'T USE BDOS BECAUSE BDOS IS NOT
- ; RE-ENTRANT (WE MIGHT HAVE GOTTEN HERE VIA BDOS). FOLLOW
- ; THE CALL TO MSGP WITH THE TEXT OF THE MESSAGE. THE LAST
- ; CHARACTER OF THE MESSAGE MUST HAVE BIT SEVEN ON (I.E. +80H)
- ; INTERNALLY REFERENCED ROUTINE.
- ;
- MSGP:
- XTHL ;GET MESSAGE ADDRESS TO REG HL
- MSG1:
- MOV C,M ;GET MESSAGE CHARACTER
- PUSH H ;SAVE MESSAGE ADDRESS DURING PRINTING
- CALL CCONOUT ;SEND IT
- POP H ;RESTORE MESSAGE ADDRESS
- MOV A,M ;GET CHR JUST SENT
- INX H ;POINT TO NEXT CHARACTER
- ORA A ;WAS THAT THE LAST CHR TO PRINT?
- JP MSG1 ;NO - KEEP PRINTING
- XTHL ;YES - PUT MODIFIED RETURN ADDREESS
- RET ;BACK ON STACK AND RETURN PAST MESSAGE
- PAGE
- ;
- ; \\\\\\\\\\\\\\\\ ////////////////
- ; >>>>>>>>>>>>>>>> R A M <<<<<<<<<<<<<<<<
- ; //////////////// A R E A S \\\\\\\\\\\\\\\\
- ;
- ;
- ; SAVE SPACE FOR A COPY OF THE BIOS JUMP TABLE BEFORE THE
- ; INSTALLATION OF FAST
- ;
- SAVEJMP:
- CBOOT: JMP $-$
- CWBOOT: JMP $-$
- CCONST: JMP $-$
- CCONIN: JMP $-$
- CCONOUT: JMP $-$
- CLIST: JMP $-$
- CPUNCH: JMP $-$
- CREADER: JMP $-$
- CHOME: JMP $-$
- CSETDSK: JMP $-$
- CSETTRK: JMP $-$
- CSETSEC: JMP $-$
- CSETDMA: JMP $-$
- CREAD: JMP $-$
- CWRITE: JMP $-$
- ;
- DIRADR DW 0 ;ADDRESS OF CURRENT DIRECTORY DDB
- RDADR DW 0 ;ADDRESS OF CURRENT READ TRACK DDB
- WRADR DW 0 ;ADDRESS OF CURRENT WRITE TRACK DDB
- ;
- TRKPTR DW 0 ;POINTER TO TRACK & DRIVE INFO IN DDB
- SENTFLG DB 0 ;ZERO IF TRACK & DRIVE HAVEN'T BEEN SENT
- WRTERRF DB 0 ;WRITE DDB ERROR FLAG, 0 IF NO ERROR
- ;
- REQDSK DB 0FFH
- REQTRK DB 0FFH
- REQSEC DB 0FFH
- REQDMA DW 0FFFFH
- ;
- DS 10H ;AT LEAST AS MUCH STACK AS CCP
- ;
- ORG (($-1) OR 255) + 1 ;ORG TO NEXT PAGE BOUNDRY
- STACK:
- ;
- CODELEN EQU $-BASE
- ;
- ORG CODELEN ;INFORM OPERATOR OF CODE LENGTH
- END FASTNTRY
-