%OUT MS96TPI.INC... ;============================================================================== ;REVISION HISTORY: ;AN000 - New for DOS Version 4.00 - J.K. ;AC000 - Changed for DOS Version 4.00 - J.K. ;AN00x - PTM number for DOS Version 4.00 - J.K. ;============================================================================== ;AN001 - p2781 Changeline error behavior incompatibile with DOS 3.3 1/06/88 J.K. ;============================================================================== ; ; DISK OPEN/CLOSE ROUTINES ARR 2.41 ; DSK$OPEN: ;ARR 2.41 PUBLIC DSK$OPEN MESSAGE FTESTDISK,<"DISK OPEN "> MNUM FTESTDISK,AX MESSAGE FTESTDISK, ; AL IS LOGICAL DRIVE CALL SETDRIVE ;GET BDS FOR DRIVE INC WORD PTR DS:[DI].OPCNT JMP EXIT ;ARR 2.41 DSK$CLOSE: ;ARR 2.41 PUBLIC DSK$CLOSE MESSAGE FTESTDISK,<"DISK CLOSE "> MNUM FTESTDISK,AX MESSAGE FTESTDISK, ; AL IS LOGICAL DRIVE CALL SETDRIVE ;GET BDS FOR DRIVE CMP WORD PTR DS:[DI].OPCNT,0 JZ EXITJX ; WATCH OUT FOR WRAP ARR 2.41 DEC WORD PTR DS:[DI].OPCNT EXITJX: JMP EXIT ; INPUT : DS:DI POINTS TO CURRENT BDS FOR DRIVE. ; RETURN : ZERO SET IF NO OPEN FILES ; ZERO RESET IF OPEN FILES CHKOPCNT: MESSAGE FTEST96,<"CHECK OPEN COUNT "> MNUM FTEST96,AX MESSAGE FTEST96, CMP WORD PTR DS:[DI].OPCNT,0 RET ; ; AT MEDIA CHECK TIME, WE NEED TO REALLY GET DOWN AND CHECK WHAT THE CHANGE IS. ; THIS IS GUARANTEED TO BE EXPENSIVE. ; PUBLIC MEDIACHECK MEDIACHECK: CALL CHECKSINGLE ; MAKE SURE CORRECT DISK IS IN PLACE XOR SI,SI CALL HASCHANGE JZ MEDIARET CALL CHECKROMCHANGE JNZ MEDIADOVOLID PUSH AX PUSH DX ;SB33001**************************************************************** mov DL, DS:[DI.drivenum] ;SB ; set logical drive number ;3.30* mov AH, 16h ;SB ; get changeline status ;3.30* int 13h ;SB ; call rom diskette routine ;3.30* ;SB33001**************************************************************** POP DX POP AX JC MEDIADOVOLID MOV SI,1 ; SIGNAL NO CHANGE ; THERE ARE SOME DRIVES WITH CHANGELINE THAT "LOSE" THE CHANGELINE INDICATION ; IF A DIFFERENT DRIVE IS ACCESSED AFTER THE CURRENT ONE. IN ORDER TO AVOID ; MISSING A MEDIA CHANGE, WE RETURN AN "I DON'T KNOW" TO DOS IF THE CHANGELINE ; IS NOT ACTIVE AND WE ARE ACCESSING A DIFFERENT DRIVE FROM THE LAST ONE. ; IF WE ARE ACCESSING THE SAME DRIVE, THEN WE CAN SAFELY RELY ON THE CHANGELINE ; STATUS. PUBLIC LOSECHNG LOSECHNG: MOV BL,CS:[TIM_DRV] ; GET LAST DRIVE ACCESSED CMP BYTE PTR [DI].DRIVENUM,BL JZ MEDIARET ; DO THE 2 SECOND TWIDDLE. IF TIME >= 2 SECONDS, DO A VOLID CHECK. ; OTHERWISE RETURN "I DON'T KNOW" (STRICTLY SPEAKING, WE SHOULD RETURN A ; "NOT CHANGED" HERE SINCE THE 2 SECOND TEST SAID NO CHANGE.) - RS. SAVEREG CALL CHECK_TIME_OF_ACCESS RESTOREREG OR SI,SI JZ MEDIADOVOLID ; CHECK_TIME SAYS ">= 2 SECS PASSED" XOR SI,SI ; RETURN "I DON'T KNOW" PUBLIC MEDIARET MEDIARET: RET ; ; SOMEHOW THE MEDIA WAS CHANGED. LOOK AT VID TO SEE. WE DO NOT LOOK AT FAT ; BECAUSE THIS MAY BE DIFFERENT SINCE WE ONLY SET MEDBYT WHEN DOING A READ ; OR WRITE. ; MEDIADOVOLID: CALL GETBP ; BUILD A NEW BPB IN CURRENT BDS JC MEDIARET CALL CHECK_VID JNC MEDIARET CALL MAPERROR ; FIX UP AL FOR RETURN TO DOS RET ; ; SIMPLE, QUICK CHECK OF LATCHED CHANGE. IF NO INDICATION, THEN RETURN ; OTHERWISE DO EXPENSIVE CHECK. IF THE EXPENSIVE TEST FAILS, POP OFF THE ; RETURN AND SET AL = 15 (FOR INVALID MEDIA CHANGE) WHICH WILL BE RETURNED TO ; DOS. ;J.K. 9/16/86 For DOS 3.3, this will work only for the drive that has ;J.K. 9/16/86 changeline. PUBLIC CHECKLATCHIO CHECKLATCHIO: ; IF RETURNING FAKE BPB THEN ASSUME THE DISK HAS NOT CHANGED ; TEST WORD PTR DS:[DI].FLAGS, RETURN_FAKE_BPB ; JNZ CHECKRET ;J.K. 9/16/86 ; call HasChange ;change line supported? ; jz CheckRet ;No. Just return CALL CHKOPCNT JNZ CHECKROM CHECKRET: RET ; ; CHECK FOR PAST ROM INDICATIONS. IF NO ROM CHANGE INDICATED, THEN RETURN OK. ; PUBLIC CHECKROM CHECKROM: CALL CHECKROMCHANGE JZ CHECKRET ; NO CHANGE ; ; WE NOW SEE THAT A CHANGE LINE HAS BEEN SEEN IN THE PAST. LET'S DO THE ; EXPENSIVE VERIFICATION. ; MESSAGE FTEST96,<"CHECKROMCHANGE SAYS YES...",CR,LF> CALL GETBP ; BUILD BPB IN CURRENT BDS JC RET_NO_ERROR_MAP ; GETBP HAS ALREADY CALLED MAPERROR CALL CHECK_VID JC CHECKLATCHRET ; DISK ERROR TRYING TO READ IN. OR SI,SI ; IS CHANGED FOR SURE? JNS CHECKRET CALL RETURNVID CHECKLATCHRET: CALL MAPERROR ; FIX UP AL FOR RETURN TO DOS RET_NO_ERROR_MAP: STC POP SI ; POP OFF RETURN ADDRESS RET ; ; CHECK THE FAT AND THE VID. RETURN IN DI -1 OR 0. RETURN WITH CARRY SET ; ONLY IF THERE WAS A DISK ERROR. RETURN THAT ERROR CODE IN AX. ; PUBLIC CHECKFATVID CHECKFATVID: MESSAGE FTEST96,<"CHECK FAT",CR,LF> CALL FAT_CHECK OR SI,SI JS CHANGED_DRV ; ; THE FAT WAS THE SAME. HOW ABOUT THE VOLUME ID? ; CHECK_VID: ;J.K. Now with the extended BOOT record, the logic should be enhanced. ;If it is the extended BOOT record, then we check the volume serial ;number instead of volume id. If it is different, then set SI to -1. ;If it is same, then SI= 1 (No change). ;If it is not the extended BOOT record, then just follows the old ;logic. DOS 4.00 will check if the # of FAT in the boot record BPB ;is not 0. If it is 0 then it must be Non_FAT based system and ;should have already covered by extended boot structure checking. ;So, we will return "I don't know" by setting SI to 0. ;This routine assume the newest valid boot record is in CS:[DISKSECTOR]. ;(This will be gauranteed by a successful GETBP call right before this ;routine.) MESSAGE FTEST96,<"CHECK VID",CR,LF> ;SB34MS96TPI001********************************************************* ;SB check the EXT_Boot_Sig variable for the Extended boot signature ;SB if it is set then go to do the extended ID check otherwise continue ;SB with code below ;SB 2 LOCS cmp cs:[Ext_Boot_Sig],Ext_Boot_Signature jz Do_Ext_Check_Id ;SB34MS96TPI001********************************************************* call HasChange ;AN000; jz CheckRet ;AN000; xor si,si ;AN000; assume I don't know. cmp byte ptr cs:[SECPERCLUSINSECTOR]+3,0 ;AN000; Don't read vol id from je CHECKFATRET ;AN000; the directory if not FAT system CALL READ_VOLUME_ID JC CHECKFATRET CALL CHECK_VOLUME_ID OR SI,SI JNZ CHANGED_DRV MESSAGE FTEST96,<"VID NOT CHANGED",CR,LF> VID_NO_Changed: CALL RESETCHANGED clc ;AN000; CHECKFATRET: RET CHANGED_DRV: MOV CS:[TIM_DRV],-1 ; ENSURE THAT WE ASK ROM FOR MEDIA RET ; CHECK NEXT TIME ROUND ; ; extended ID check ; Do_Ext_Check_ID: ;AN000; push ax ;AN000; ;SB34MS96TPI002************************************************************** ;SB The code to check extended ID is basically a check to see if the ;Sb volume serial number is still the same. The volume serial number ;SB previously read is in cs:[Boot_Serial_H] and cs:[Boot_Serial_L] ;SB high and low words respectively. DS:DI points to the BDS of the ;SB drive under consideration. The BDS has fields containing the ;SB high and low words of the volume serial number of the media in the ;SB drive. Compare these fields to the fields mentioned above. If these ;SB fields do not match the media has changed and so we should jump ;SB to the code starting at Ext_Changed else return "I don't know" status ;SB in the register used for the changeline status and continue executing ;SB the code given below. For temporary storage use the register which ;SB has been saved and restored around this block. ;SB 7 LOCS ;SB BDS fields in inc\msbds.inc mov ax,cs:[Boot_Serial_L] cmp ax,word ptr ds:[di+VOL_SERIAL] jnz Ext_Changed mov ax,cs:[Boot_Serial_H] cmp ax,word ptr ds:[di+VOL_SERIAL+2] jnz Ext_Changed xor si,si ; don't know ;SB34MS96TPI002************************************************************** pop ax ;AN000; ; jmp CheckFatRet ;AN000; jmp VID_NO_Changed ;AN001;Reset the flag Ext_Changed: ;AN000; Serial number is different! pop ax ;AN000; mov si, -1 ;AN000; disk changed! clc ;AN000; clear carry. Only SI is meaningful here. jmp Changed_Drv ;AN000; ; ; AT I/O TIME, WE DETECTED THE ERROR. NOW WE NEED TO DETERMINE WHETHER THE ; MEDIA WAS TRULY CHANGED OR NOT. WE RETURN NORMALLY IF MEDIA CHANGE UNKNOWN. ; AND WE POP OFF THE CALL AND JMP TO HARDERR IF WE SEE AN ERROR. ; PUBLIC CHECKIO CHECKIO: CMP AH,06 JNZ CHECKFATRET CALL CHKOPCNT JZ CHECKFATRET ; NO OPEN FILES ; IF RETURNING FAKE BPB THEN IGNORE DISK CHANGES ; TEST WORD PTR DS:[DI].FLAGS, RETURN_FAKE_BPB ; JNZ IGNORECHANGE CALL GETBP ; BUILD UP A NEW BPB IN CURRENT BDS JC NO_ERROR_MAP ; GETBP HAS ALREADY CALLED MAPERROR CALL CHECKFATVID JC CHECKIORET ; DISK ERROR TRYING TO READ IN. OR SI,SI ; IS CHANGED FOR SURE? JS CHECKIOERR ; YES CHANGED IGNORECHANGE: INC BP ; ALLOW A RETRY RET CHECKIOERR: CALL RETURNVID CHECKIORET: ; POP SI ; POP OFF RETURN STC ; MAKE SURE CARRY GETS PASSED THROUGH JMP HARDERR NO_ERROR_MAP: JMP HARDERR2 ; ; RETURN VID SETS UP THE VID FOR A RETURN TO DOS. ; PUBLIC RETURNVID RETURNVID: MESSAGE FTEST96,<"RETURN VID",CR,LF> PUSH DS ; SAVE POINTER TO CURRENT BDS PUSH DI PUSH CX CALL INIT_VID_LOOP ; SETS ES:DI -> VID LDS BX,CS:[PTRSAV] MOV [BX.EXTRA],DI MOV [BX.EXTRA+2],ES POP CX POP DI ; RESTORE CURRENT BDS POP DS MOV AH,6 ; INVALID MEDIA CHANGE STC RET ; ; MUNGE THE TIME OF LAST SUCCESSFUL ACCESS FOR TWEEKED DRIVES ; ; DON'T NEED ANY MORE ; TWEEKCHECK: ; PUSH AX ; MOV AX,WORD PTR DS:[DI].FLAGS ; TEST AL,FCHANGED_BY_FORMAT ; JZ TWEEKDONE ; MOV CS:[TIM_DRV],-1 ; TWEEKDONE: ; POP AX ; RET ; ; DRIVE IS THE LOGICAL DRIVE TO USE ; ; FORMAT_MEDIA_CHECK: ;ARR 2.42 ; PUSH AX ; MOV AX,WORD PTR DS:[DI].FLAGS ; TEST AL,FCHANGED_BY_FORMAT ; JZ RETF1 ; MEDIA NOT CHANGED VIA FORMAT ; AND AL,NOT FCHANGED_BY_FORMAT ; MOV WORD PTR [DI].FLAGS,AX ; RESET CHANGED_BY_FORMAT BIT ; MOV SI,-1 ; MEDIA CHANGED VIA FORMAT ; RETF1: ; POP AX ; RET ; ; MOVES THE POINTER TO THE VOLID FOR THE DRIVE INTO THE ORIGINAL REQUEST PACKET ; ON ENTRY, DS:BX POINTS TO THE ORIGINAL PACKET. ; NO ATTEMPT IS MADE TO PRESERVE REGISTERS. ; MEDIA_SET_VID: ; ARR 2.42 PUBLIC MEDIA_SET_VID CALL INIT_VID_LOOP ; SETS ES:DI -> VID LDS BX,CS:[PTRSAV] ; GET POINTER TO PACKET MOV WORD PTR [BX.TRANS+1],DI MOV WORD PTR [BX.TRANS+3],ES RET ; ; HIDENSITY - EXAMINE A DRIVE/MEDIA DESCRIPTOR TO SET THE MEDIA TYPE. IF ; THE MEDIA DESCRIPTOR IS NOT F9 (NOT 96TPI OR 3 1/2), WE RETURN AND LET THE ; CALLER DO THE REST. OTHERWISE, WE POP OFF THE RETURN AND JUMP TO THE TAIL ; OF GETBP. FOR 3.5" MEDIA, WE JUST RETURN. ; ; INPUTS: DS:DI POINT TO CORRECT BDS FOR THIS DRIVE ; AH HAS MEDIA BYTE ; ; OUTPUTS: CARRY CLEAR ; NO REGISTERS MODIFIED ; CARRY SET ; AL = SECTORS/FAT ; BH = NUMBER OF ROOT DIRECTORY ENTRIES ; BL = SECTORS PER TRACK ; CX = NUMBER OF SECTORS ; DH = SECTORS PER ALLOCATION UNIT ; DL = NUMBER OF HEADS ; HIDENSITY: PUBLIC HIDENSITY ; ; CHECK FOR CORRECT DRIVE ; TEST WORD PTR DS:[DI].FLAGS,FCHANGELINE ; IS IT SPECIAL? JZ DOFLOPPY ; NO, DO NORMAL FLOPPY TEST ; ; WE HAVE A MEDIA BYTE THAT IS PRETTY COMPLEX. EXAMINE DRIVE INFORMATION ; TABLE TO SEE WHAT KIND IT IS. ; CMP BYTE PTR DS:[DI].FORMFACTOR,FFSMALL; IS IT SINGLE-MEDIA? JZ DOFLOPPY ; YES, USE FATID... ; ; 96 TPI DRIVE ; CMP AH,0F9H JNZ DOFLOPPY MOV AL,7 ; SEVEN SECTORS / FAT MOV BX,224*256+0FH ; 224 ROOT DIR ENTRIES & 0F SECTOR MAX MOV CX,80*15*2 ; 80 TRACKS, 15 SECTORS/TRACK, 2 SIDES MOV DX,01*256+2 ; SECTORS/ALLOCATION UNIT & HEAD MAX POPR: ADD SP,2 ; POP OFF RETURN ADDRESS JMP HAS1 ; RETURN TO TAIL OF GETBP DOFLOPPY: RET PATHSTART 001,TPI96 ; ; CERTAIN BOGUS PROGRAMS AVOID DOS ALTOGETHER AND USE INT 13 DIRECTLY. THESE ; PROGRAMS EVEN RETRY OPERATIONS AND, THUS, WILL IGNORE THE DISK CHANGE LOGIC. ; ; WE HOOK INT 13 AND NOTE ALL ERRORS. ; ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING PUBLIC REAL13 REAL13 DD ? OLDINT DD ? DMY DW ? PATHEND 001,TPI96 PUBLIC INT13 INT13 PROC FAR POP WORD PTR OLDINT POP WORD PTR OLDINT+2 POP DMY MESSAGE FTEST13,<"*"> PUSHF CALL REAL13 ; SIMULATE ANOTHER INT 13 JC ERR13 ; DID AN ERROR OCCUR? JMP OLDINT ; NO, RETURN AND POP OFF FLAGS ERR13: MESSAGE FTEST13,<"INT 13 ERROR "> MNUM FTEST13,AX MESSAGE FTEST13, PUSHF ; SAVE STATE CMP AH,06H ; DID I SEE A CHANGE EVENT? JZ GOTERR ; YES B: POPF ; NO, SOME OTHER ERROR, IGNORE IT JMP OLDINT ; RETURN AND POP OFF FLAGS GOTERR: OR DL,DL ; IS THIS FOR THE HARD DISK? JS B ; YES, IGNORE MOV WORD PTR CS:[FLAGBITS],FCHANGED CALL SET_CHANGED_DL JMP B INT13 ENDP ; ; SET_CHANGED_DL - SETS FLAG BITS ACCORDING TO BITS SET IN [FLAGBITS]. ; ESSENTIALLY USED TO INDICATE CHANGELINE, OR FORMAT. ; ; INPUTS: DL CONTAINS PHYSICAL DRIVE NUMBER ; [FLAGBITS] CONTAINS BITS TO SET IN THE FLAG FIELD IN THE BDSS ; OUTPUTS: NONE ; REGISTERS MODIFIED: FLAGS ; SET_CHANGED_DL: PUBLIC SET_CHANGED_DL MESSAGE FTEST96,<"SET CHANGED",CR,LF> PUSH BX PUSH DX MOV BL,DL ALL_SET: MOV DX,CS:[FLAGBITS] ; GET BITS TO SET IN FLAG FIELD XOR BH,BH ; ; IN THE VIRTUAL DRIVE SYSTEM WE *MUST* FLAG THE OTHER DRIVES AS BEING CHANGED ; ; ASSUME FIRST BDS IS IN THIS SEGMENT PUSH AX PUSH DS ; SAVE CURRENT BDS PUSH DI LDS DI,DWORD PTR CS:[START_BDS] SCAN_BDS: CMP DI,-1 JZ SKIPSET CMP BYTE PTR [DI].DRIVENUM,BL JNZ GET_NEXT_BDS ; ; SOMEONE MAY COMPLAIN, BUT THIS *ALWAYS* MUST BE DONE WHEN A DISK CHANGE IS ; NOTED. THERE ARE *NO* OTHER COMPROMISING CIRCUMSTANCES. ; SETCHANGED: OR WORD PTR DS:[DI].FLAGS,DX ; SIGNAL CHANGE ON OTHER DRIVE GET_NEXT_BDS: MOV AX,WORD PTR [DI].LINK+2 ; GO TO NEXT BDS MOV DI,WORD PTR [DI].LINK MOV DS,AX JMP SHORT SCAN_BDS SKIPSET: POP DI ; RESTORE CURRENT BDS POP DS POP AX POP DX POP BX RET ; ; CHECKROMCHANGE - SEE IF EXTERNAL PROGRAM HAS DIDDLED ROM CHANGE LINE. ; ; INPUTS: DS:DI POINTS TO CURRENT BDS. ; OUTPUTS: ZERO SET - NO CHANGE ; ZERO RESET - CHANGE ; REGISTERS MODIFIED: NONE CHECKROMCHANGE: MESSAGE FTEST13,<"CHECKROM "> MNUM FTEST13 MESSAGE FTEST13, TEST WORD PTR [DI].FLAGS,FCHANGED RET ; ; RESETCHANGED - RESTORE VALUE OF CHANGE LINE ; ; INPUTS: DS:DI POINTS TO CURRENT BDS ; OUTPUTS: NONE ; REGISTERS MODIFIED: NONE public ResetChanged RESETCHANGED: MESSAGE FTEST13,<"RESETCHANGED "> MNUM FTEST13 MESSAGE FTEST13, AND WORD PTR DS:[DI].FLAGS,NOT FCHANGED RET ; ; HASCHANGE - SEE IF DRIVE CAN SUPPLY CHANGE LINE ; ; INPUTS: DS:DI POINTS TO CURRENT BDS ; OUTPUTS: ZERO SET - NO CHANGE LINE AVAILABLE ; ZERO RESET - CHANGE LINE AVAILABLE ; REGISTERS MODIFIED: NONE PUBLIC HASCHANGE HASCHANGE: MESSAGE FTEST13,<"HASCHANGE "> MNUM FTEST13 MESSAGE FTEST13, TEST WORD PTR [DI].FLAGS,FCHANGELINE RET ASSUME DS:CODE INCLUDE MSVOLID.INC PUBLIC END96TPI END96TPI LABEL BYTE