From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/BIOS/MS96TPI.INC | 536 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 536 insertions(+) create mode 100644 v4.0/src/BIOS/MS96TPI.INC (limited to 'v4.0/src/BIOS/MS96TPI.INC') diff --git a/v4.0/src/BIOS/MS96TPI.INC b/v4.0/src/BIOS/MS96TPI.INC new file mode 100644 index 0000000..2760b00 --- /dev/null +++ b/v4.0/src/BIOS/MS96TPI.INC @@ -0,0 +1,536 @@ +%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 -- cgit v1.2.3