diff options
| author | 2024-04-25 21:24:10 +0100 | |
|---|---|---|
| committer | 2024-04-25 22:32:27 +0000 | |
| commit | 2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch) | |
| tree | 80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/BIOS/MSDISK.ASM | |
| parent | Merge pull request #430 from jpbaltazar/typoptbr (diff) | |
| download | ms-dos-main.tar.gz ms-dos-main.tar.xz ms-dos-main.zip | |
Diffstat (limited to 'v4.0/src/BIOS/MSDISK.ASM')
| -rw-r--r-- | v4.0/src/BIOS/MSDISK.ASM | 2443 |
1 files changed, 2443 insertions, 0 deletions
diff --git a/v4.0/src/BIOS/MSDISK.ASM b/v4.0/src/BIOS/MSDISK.ASM new file mode 100644 index 0000000..f132e7f --- /dev/null +++ b/v4.0/src/BIOS/MSDISK.ASM | |||
| @@ -0,0 +1,2443 @@ | |||
| 1 | PAGE ,132 ; | ||
| 2 | TITLE MSDISK - BIOS | ||
| 3 | %OUT ...MSDISK.ASM | ||
| 4 | |||
| 5 | ;============================================================================== | ||
| 6 | ;REVISION HISTORY: | ||
| 7 | ;AN000 - New for DOS Version 4.00 - J.K. | ||
| 8 | ;AC000 - Changed for DOS Version 4.00 - J.K. | ||
| 9 | ;AN00x - PTM number for DOS Version 4.00 - J.K. | ||
| 10 | ;============================================================================== | ||
| 11 | ;AN001; d24 Multi Track enable/disable command in CONFIG.SYS 6/27/87 J.K. | ||
| 12 | ;AN002; d9 Double word MOV instruction 7/1/87 J.K. | ||
| 13 | ;AN003: d25 Change DASD ERP to that recommended by Storage systems 7/28/87 J.K. | ||
| 14 | ;AN004; D113 Disable I/O access to unformatted media 9/03/87 J.K. | ||
| 15 | ;AN005; P985 Allow I/O access to unformatted media 9/14/87 J.K. | ||
| 16 | ;AN006; P1535 Disallow I/O access to unformatted media. 10/15/87 J.K. | ||
| 17 | ; (Give the user to control this - Generic IOCTL subfunction 64h/44h | ||
| 18 | ;AN007; p2828 Do not retry for multi-track format request 12/08/87 J.K. | ||
| 19 | ;AC008; p3197 Should reset change line after BPB set in BDS table 01/21/88 J.K. | ||
| 20 | ;AN009; p3349 Should retry at hard file timeout error 02/03/88 J.K. | ||
| 21 | ;AN010; p4696 ECC error handler should cover PC ATs for CMC disks 05/04/88 J.K. | ||
| 22 | ;AN011; p5034 Possible virgin hard file problem with direct INT 13 06/03/88 J.K. | ||
| 23 | ;AN012; P5049 Attempt to write at DISK BASE table in ROM BIOS 06/06/88 J.K. | ||
| 24 | ;AN013; P5055 Diskcopy fails (Regression of P5049) 06/09/88 J.K. | ||
| 25 | ;============================================================================== | ||
| 26 | |||
| 27 | ;for testing, set itest to 1. So as MSBIO1.ASM. | ||
| 28 | itest=0 | ||
| 29 | EXTRN NUMERR:ABS ;MSDATA | ||
| 30 | |||
| 31 | INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT | ||
| 32 | INCLUDE MSEQU.INC | ||
| 33 | INCLUDE PUSHPOP.INC | ||
| 34 | INCLUDE MSMACRO.INC | ||
| 35 | INCLUDE DEVSYM.INC | ||
| 36 | INCLUDE MSDSKPR.INC | ||
| 37 | include biostruc.inc | ||
| 38 | |||
| 39 | EXTRN INT2F_DISK:FAR ;MSBIO2 | ||
| 40 | EXTRN MEDIACHECK:NEAR ;96TPI | ||
| 41 | EXTRN HASCHANGE:NEAR ;96TPI | ||
| 42 | EXTRN MEDIA_SET_VID:NEAR ;96TPI | ||
| 43 | EXTRN HIDENSITY:NEAR ;96TPI | ||
| 44 | EXTRN CHECKLATCHIO:NEAR ;96TPI | ||
| 45 | EXTRN CHECKIO:NEAR ;96TPI | ||
| 46 | EXTRN SET_CHANGED_DL:NEAR ;96TPI | ||
| 47 | EXTRN SET_VOLUME_ID:NEAR ;MSVOLID | ||
| 48 | EXTRN SWPDSK:NEAR ;MSBIO2 | ||
| 49 | EXTRN CMDERR:NEAR ;MSBIO1 | ||
| 50 | EXTRN STRATEGY:NEAR ;MSBIO1 | ||
| 51 | EXTRN ERR$CNT:NEAR ;MSBIO1 | ||
| 52 | EXTRN DSK$IN:NEAR ;MSBIO1 | ||
| 53 | EXTRN EXIT:NEAR ;MSBIO1 | ||
| 54 | EXTRN BUS$EXIT:NEAR ;MSBIO1 | ||
| 55 | EXTRN ERR$EXIT:NEAR ;MSBIO1 | ||
| 56 | extrn ResetChanged:near ;AN000; MS96TPI | ||
| 57 | |||
| 58 | ;DATA | ||
| 59 | EXTRN OLD13:DWORD ;MSBIO2 | ||
| 60 | EXTRN PTRSAV:DWORD ;MSBIO1 | ||
| 61 | EXTRN COM1DEV:WORD ;MSAUX | ||
| 62 | EXTRN DAYCNT:WORD ;MSCLOCK | ||
| 63 | EXTRN TIM_DRV:BYTE ;MSDATA | ||
| 64 | EXTRN ACCESSCOUNT:BYTE ;MSDATA | ||
| 65 | EXTRN SM92:BYTE ;MSDATA | ||
| 66 | EXTRN DISKSECTOR:BYTE ;MSDATA | ||
| 67 | EXTRN MEDIABYTE:BYTE ;MSDATA | ||
| 68 | EXTRN SECPERCLUSINSECTOR:BYTE ;MSDATA | ||
| 69 | EXTRN BPB_IN_SECTOR:WORD ;MSDATA | ||
| 70 | EXTRN DISKSECTOR:BYTE ;MSDATA | ||
| 71 | EXTRN STEP_DRV:BYTE ;MSDATA | ||
| 72 | EXTRN START_BDS:WORD ;MSDATA | ||
| 73 | EXTRN PHYS_DRV:BYTE ;MSDATA | ||
| 74 | EXTRN WRTVERIFY:WORD ;MSDATA | ||
| 75 | EXTRN FSETOWNER:BYTE ;MSDATA | ||
| 76 | EXTRN SINGLE:BYTE ;MSDATA | ||
| 77 | EXTRN RFLAG:BYTE ;MSDATA | ||
| 78 | EXTRN MEDBYT:BYTE ;MSDATA | ||
| 79 | EXTRN SPSAV:WORD ;MSDATA | ||
| 80 | EXTRN SECCNT:WORD ;MSDATA | ||
| 81 | EXTRN DPT:DWORD ;MSDATA | ||
| 82 | EXTRN CURSEC:BYTE,CURHD:BYTE ;MSDATA | ||
| 83 | EXTRN CURTRK:WORD ;MSDATA | ||
| 84 | EXTRN EOT:BYTE ;MSDATA | ||
| 85 | EXTRN MOTORSTARTUP:BYTE,SETTLECURRENT:BYTE,SETTLESLOW:BYTE ;MSDATA | ||
| 86 | EXTRN CURHD:BYTE ;MSDATA | ||
| 87 | EXTRN LSTERR:BYTE ;MSDATA | ||
| 88 | EXTRN ERRIN:BYTE,ERROUT:BYTE ;MSDATA | ||
| 89 | EXTRN PREVOPER:WORD ;MSDATA | ||
| 90 | EXTRN ORIG13:DWORD ;MSDATA | ||
| 91 | EXTRN FLAGBITS:WORD ;MSDATA | ||
| 92 | EXTRN NUMBER_OF_SEC:BYTE ;MSDATA | ||
| 93 | EXTRN FHAVE96:BYTE ;MSDATA | ||
| 94 | EXTRN NEW_ROM:BYTE ;MSDATA | ||
| 95 | EXTRN FORMT_EOT:BYTE,HDNUM:BYTE,TRKNUM:WORD,GAP_PATCH:BYTE ;MSDATA | ||
| 96 | EXTRN NEXT2F_13:WORD ;MSDATA | ||
| 97 | extrn Save_head_sttl:byte ;msbdata | ||
| 98 | extrn Secrete_Code:word ;msbdata J.K. 11/7/86 Secrete code for DOS 3.3 MSBIO | ||
| 99 | extrn Ext_Boot_Sig:byte ;AN000; msbdata | ||
| 100 | extrn Boot_Serial_L:word ;AN000; msbdata | ||
| 101 | extrn Boot_Serial_H:word ;AN000; msbdata | ||
| 102 | extrn Boot_Volume_Label:byte ;AN000; msbdata | ||
| 103 | extrn Boot_System_ID:byte ;AN000; msbdata | ||
| 104 | extrn Model_Byte:Byte ;MSBIO2 | ||
| 105 | extrn Secondary_Model_Byte:Byte ;MSBIO2 | ||
| 106 | |||
| 107 | ;----------------------------------------------------------------- | ||
| 108 | ; | ||
| 109 | ; DISK INTERFACE ROUTINES | ||
| 110 | ; | ||
| 111 | ; DEVICE ATTRIBUTE BITS: | ||
| 112 | ; BIT 6 - GET/SET MAP FOR LOGICAL DRIVES AND GENERIC IOCTL. | ||
| 113 | ; | ||
| 114 | |||
| 115 | MAXERR = 5 | ||
| 116 | LSTDRV = 504H | ||
| 117 | |||
| 118 | ; SOME FLOPPIES DO NOT HAVE CHANGELINE. AS A RESULT, MEDIA-CHECK WOULD | ||
| 119 | ; NORMALLY RETURN I-DON'T-KNOW, THE DOS WOULD CONTINUALLY REREAD THE FAT, AND | ||
| 120 | ; DISCARD CACHED DATA. WE OPTIMIZE THIS BY IMPLEMENTING A LOGICAL DOOR- | ||
| 121 | ; LATCH: IT IS PHYSICALLY IMPOSSIBLE TO CHANGE A DISK IN UNDER 2 SECONDS. WE | ||
| 122 | ; RETAIN THE TIME OF THE LAST SUCCESSFUL DISK OPERATION AND COMPARE IT WITH | ||
| 123 | ; THE CURRENT TIME DURING MEDIA-CHECK. IF < 2 SECONDS AND AT LEAST 1 TIMER | ||
| 124 | ; TICK HAS PASSED, THE WE SAY NO CHANGE. IF > 2 SECONDS THEN WE SAY I- | ||
| 125 | ; DON'T-KNOW. FINALLY, SINCE WE CANNOT TRUST THE TIMER TO BE ALWAYS | ||
| 126 | ; AVAILABLE, WE RECORD THE NUMBER OF MEDIA CHECKS THAT HAVE OCCURRED WHEN NO | ||
| 127 | ; APPARENT TIME HAS ELAPSED. WHILE THIS NUMBER IS < A GIVEN THRESHOLD, WE SAY | ||
| 128 | ; NO CHANGE. WHEN IT EXCEEDS THAT THRESHOLD, WE SAY I-DON'T-KNOW AND RESET | ||
| 129 | ; THE COUNTER TO 0. WHEN WE STORE THE TIME OF LAST SUCCESSFUL ACCESS, IF WE | ||
| 130 | ; SEE THAT TIME HAS PASSED TOO, WE RESET THE COUNTER. | ||
| 131 | ; | ||
| 132 | ACCESSMAX = 5 | ||
| 133 | ; | ||
| 134 | ; DUE TO VARIOUS BOGOSITIES, WE NEED TO CONTINUALLY ADJUST WHAT THE HEAD | ||
| 135 | ; SETTLE TIME IS. THE FOLLOWING ALGORITHM IS USED: | ||
| 136 | ; | ||
| 137 | ; GET THE CURRENT HEAD SETTLE VALUE. | ||
| 138 | ; IF IT IS 0, THEN | ||
| 139 | ; SET SLOW = 15 | ||
| 140 | ; ELSE | ||
| 141 | ; SET SLOW = VALUE | ||
| 142 | ; ... | ||
| 143 | ;********************************************* | ||
| 144 | ;************ OLD ALGORITHM ****************** | ||
| 145 | ;* IF WE ARE SEEKING AND WRITING THEN | ||
| 146 | ;* USE SLOW | ||
| 147 | ;* ELSE | ||
| 148 | ;* USE FAST | ||
| 149 | ;********************************************* | ||
| 150 | ;*********** IBM'S REQUESTED LOGIC *********** | ||
| 151 | ; IF WE ARE SEEKING AND WRITING AND NOT ON AN AT THEN | ||
| 152 | ; USE SLOW | ||
| 153 | ; ELSE | ||
| 154 | ; USE FAST | ||
| 155 | ; ... | ||
| 156 | ; RESTORE CURRENT HEAD SETTLE VALUE | ||
| 157 | ; | ||
| 158 | |||
| 159 | Set_ID_Flag db 0 ;AN000; If 1, GETBP routine will set the | ||
| 160 | ;Vol_Serial and FileSys_ID in BDS table | ||
| 161 | ;from the media Boot record, if it is > DOS 4.00 | ||
| 162 | ;formatted one. Then Set_ID_flag will be set to 2 | ||
| 163 | ;to signal that volume_label is set from the extended | ||
| 164 | ;boot record and do not set it from the root | ||
| 165 | ;directory as done in SET_VOLUME_ID routine. | ||
| 166 | ;For the old version, Vol_Serial | ||
| 167 | ;will be set to -1, and FileSys_ID will be set | ||
| 168 | ;to "FAT12 " if it is a floppy. | ||
| 169 | |||
| 170 | public Fat_12_ID | ||
| 171 | Fat_12_ID DB "FAT12 ",0 ;AN000; Default System ID for floppy. | ||
| 172 | public Fat_16_ID | ||
| 173 | Fat_16_ID DB "FAT16 ",0 ;AN000; | ||
| 174 | public Vol_No_Name | ||
| 175 | Vol_No_Name db "NO NAME ",0 ;AN000; | ||
| 176 | public Temp_H | ||
| 177 | Temp_H dw 0 ;AN000; Temporary for 32 bit calculation. | ||
| 178 | |||
| 179 | public Start_Sec_H | ||
| 180 | Start_Sec_H dw 0 ;AN000; Starting sector number high word. | ||
| 181 | ;Used as an input to DISKIO subroutine. | ||
| 182 | Saved_Word dw 0 ;AN000; Tempory saving place for a word. | ||
| 183 | |||
| 184 | ;--------------------------------------- | ||
| 185 | ;J.K. 6/29/87 For Multi-track | ||
| 186 | MULTRK_ON EQU 10000000B ;User spcified Mutitrack=on, or System turns | ||
| 187 | ; it on after handling CONFIG.SYS file as a | ||
| 188 | ; default value, if MulTrk_flag = MULTRK_OFF1. | ||
| 189 | MULTRK_OFF1 EQU 00000000B ;initial value. No "Multitrack=" command entered. | ||
| 190 | MULTRK_OFF2 EQU 00000001B ;User specified Multitrack=off. | ||
| 191 | public MulTrk_Flag | ||
| 192 | MulTrk_Flag dw 0 ;AN001; | ||
| 193 | ;J.K. 6/29/87 End of Multi-track definition. | ||
| 194 | ;--------------------------------------------------------------------- | ||
| 195 | public EC35_Flag | ||
| 196 | EC35_Flag db 0 ; flags for electrically compatible 3.5 inch disk drives (mrw 4/88) | ||
| 197 | ;--------------------------------------------------------------------- | ||
| 198 | VRetry_Cnt dw 0 ;AN003; | ||
| 199 | Soft_ECC_Cnt dw 0 ;AN003; | ||
| 200 | ;--------------------------------------------------------------------- | ||
| 201 | MultiTrk_Format_Flag db 0 ;AN007;Testing. If 1, then Multi track format request | ||
| 202 | ;--------------------------------------------------------------------- | ||
| 203 | ; | ||
| 204 | ; IF ID IS F9, HAVE A 96TPI DISK ELSE | ||
| 205 | ; IF BIT 2 IS 0 THEN MEDIA IS NOT REMOVABLE AND COULD NOT HAVE CHANGED | ||
| 206 | ; OTHERWISE IF WITHIN 2 SECS OF LAST DISK OPERATION MEDIA COULD NOT | ||
| 207 | ; HAVE CHANGED, OTHERWISE DONT KNOW IF MEDIA HAS CHANGED | ||
| 208 | ; | ||
| 209 | PUBLIC MEDIA$CHK | ||
| 210 | MEDIA$CHK PROC NEAR | ||
| 211 | MESSAGE FTESTDISK,<"DISK MEDIA CHECK "> | ||
| 212 | MNUM FTESTDISK,AX | ||
| 213 | MESSAGE FTESTDISK,<CR,LF> | ||
| 214 | CALL SETDRIVE | ||
| 215 | |||
| 216 | cmp cs:Secrete_Code, 'jk' ;J.K.11/7/86 Secrete code for DOS 3.3 IBMBIO. | ||
| 217 | jne media$done ;J.K.11/7/86 | ||
| 218 | |||
| 219 | ; FOR NON-REMOVABLE DISKS ONLY RETURN CHANGED IF CHANGED BY FORMAT, OTHERWISE | ||
| 220 | ; RETURN 'NOT CHANGED'. | ||
| 221 | MOV SI,1 ; ASSUME NO CHANGE | ||
| 222 | TEST WORD PTR [DI].FLAGS,FCHANGED_BY_FORMAT | ||
| 223 | JZ WEARENOTFAKINGIT | ||
| 224 | AND WORD PTR [DI].FLAGS,NOT FCHANGED_BY_FORMAT ; RESET FLAG | ||
| 225 | ; IF MEDIA HAS BEEN CHANGED BY FORMAT, WE MUST ASK THE ROM. CANNOT RELY ON THE | ||
| 226 | ; 2 SECOND TIME CHECK. | ||
| 227 | MOV CS:[TIM_DRV],-1 ; ENSURE THAT WE ASK THE ROM IF MEDIA | ||
| 228 | ; HAS CHANGED | ||
| 229 | TEST WORD PTR [DI].FLAGS,FNON_REMOVABLE | ||
| 230 | JZ WEHAVEAFLOPPY | ||
| 231 | MOV SI,-1 ; INDICATE MEDIA CHANGED | ||
| 232 | JMP SHORT MEDIA$DONE | ||
| 233 | ; | ||
| 234 | ; WE NEED TO RETURN 'NOT CHANGED' IF WE HAVE A HARD FILE. | ||
| 235 | ; | ||
| 236 | WEARENOTFAKINGIT: | ||
| 237 | TEST WORD PTR [DI].FLAGS,FNON_REMOVABLE | ||
| 238 | JNZ MEDIA$DONE | ||
| 239 | WEHAVEAFLOPPY: | ||
| 240 | XOR SI,SI ; PRESUME "I DON'T KNOW" | ||
| 241 | ; | ||
| 242 | ; IF WE HAVE A FLOPPY WITH CHANGELINE SUPPORT, WE ASK THE ROM TO DETERMINE IF | ||
| 243 | ; MEDIA HAS CHANGED. WE DO NOT PERFORM THE 2 SECOND CHECK FOR THESE DRIVES. | ||
| 244 | ;----------------------------------------| | ||
| 245 | ; WARNING: DO NOT CHANGE THE FOLLOWING. ;| | ||
| 246 | ; IT GETS PATCHED IN MSINIT ;| | ||
| 247 | PUBLIC MEDIA_PATCH ;| | ||
| 248 | MEDIA_PATCH: ;| | ||
| 249 | CALL MEDIACHECK ;| | ||
| 250 | JC ERR$EXITJ ;| | ||
| 251 | CALL HASCHANGE ;| | ||
| 252 | JNZ MEDIA$DONE ;| | ||
| 253 | ;----------------------------------------| | ||
| 254 | ; IF WE COME HERE, WE HAVE A FLOPPY WITH NO CHANGELINE SUPPORT | ||
| 255 | MOV SI,1 ; PRESUME NO CHANGE | ||
| 256 | MOV AL,CS:[TIM_DRV] ; LAST DRIVE ACCESSED | ||
| 257 | CMP AL,BYTE PTR [DI].DRIVENUM ;IS DRIVE OF LAST ACCESS THE SAME? | ||
| 258 | JNZ MEDIA$UNK ; NO, THEN "I DON'T KNOW" | ||
| 259 | ; | ||
| 260 | ; CHECK TO SEE IF THIS DRIVE HAS BEEN ACCESSED IN THE LAST 2 SECONDS. | ||
| 261 | CALL CHECK_TIME_OF_ACCESS ; SETS SI CORRECTLY | ||
| 262 | JMP SHORT MEDIA$DONE | ||
| 263 | |||
| 264 | MEDIA$UNK: | ||
| 265 | DEC SI ; RETURN "I DON'T KNOW" | ||
| 266 | ; | ||
| 267 | ; SI NOW CONTAINS THE CORRECT VALUE FOR MEDIA CHANGE. CLEAN UP THE LEFT OVERS | ||
| 268 | ; | ||
| 269 | MEDIA$DONE: | ||
| 270 | LES BX,CS:[PTRSAV] ; GET ORIGINAL PACKET | ||
| 271 | MOV WORD PTR ES:[BX].TRANS,SI | ||
| 272 | OR SI,SI | ||
| 273 | JS INIT_PATCH | ||
| 274 | JMP EXIT | ||
| 275 | MEDIA$CHK ENDP | ||
| 276 | ;----------------------------------------| | ||
| 277 | ; WARNING: DO NOT CHANGE THE FOLLOWING. ;| | ||
| 278 | ; IT GETS PATCHED IN MSINIT ;| | ||
| 279 | PUBLIC INIT_PATCH ;| | ||
| 280 | INIT_PATCH PROC NEAR ;| | ||
| 281 | CALL MEDIA_SET_VID ;| | ||
| 282 | ;----------------------------------------| | ||
| 283 | MOV CS:[TIM_DRV],-1 ; MAKE SURE WE ASK ROM FOR MEDIA CHECK | ||
| 284 | VOLIDOK: | ||
| 285 | JMP EXIT | ||
| 286 | INIT_PATCH ENDP | ||
| 287 | |||
| 288 | ERR$EXITJ PROC NEAR | ||
| 289 | |||
| 290 | MESSAGE FTESTCOM,<"ERR$EXITJ: "> | ||
| 291 | MNUM FTESTCOM,AX | ||
| 292 | MESSAGE FTESTCOM,<" == "> | ||
| 293 | CALL MAPERROR | ||
| 294 | MNUM FTESTCOM,AX | ||
| 295 | MESSAGE FTESTCOM,<CR,LF> | ||
| 296 | JMP ERR$EXIT | ||
| 297 | ERR$EXITJ ENDP | ||
| 298 | |||
| 299 | ; | ||
| 300 | ; PERFORM A CHECK ON THE TIME PASSED SINCE THE LAST ACCESS FOR THIS PHYSICEL | ||
| 301 | ; DRIVE. | ||
| 302 | ; WE ARE ACCESSING THE SAME DRIVE. IF THE TIME OF LAST SUCCESSFUL ACCESS WAS | ||
| 303 | ; LESS THAN 2 SECONDS AGO, THEN WE MAY PRESUME THAT THE DISK WAS NOT CHANGED. | ||
| 304 | ; RETURNS IN SI: | ||
| 305 | ; 0 - IF TIME OF LAST ACCESS WAS >= 2 SECONDS | ||
| 306 | ; 1 - IF TIME WAS < 2 SECONDS (I.E NO MEDIA CHANGE ASSUMED) | ||
| 307 | ; REGISTERS AFFECTED AX,CX,DX, FLAGS. | ||
| 308 | ; | ||
| 309 | CHECK_TIME_OF_ACCESS PROC NEAR | ||
| 310 | PUBLIC CHECK_TIME_OF_ACCESS | ||
| 311 | |||
| 312 | MOV SI,1 ; PRESUME NO CHANGE. | ||
| 313 | ;SB33014************************************************************* | ||
| 314 | xor AH,AH ; set command to read time | ||
| 315 | int 1Ah ; call rom-bios clock routine | ||
| 316 | ;SB33014************************************************************* | ||
| 317 | ; | ||
| 318 | ; NOW THAT WE ARE READING THE TIME, WE MUST MAKE SURE THAT WE DO NOT LOSE A | ||
| 319 | ; DATE WRAP. THE ROM WILL RETURN THE VALUE ONLY ONCE, SO WE NEED TO NOTE THIS | ||
| 320 | ; FACT. | ||
| 321 | ; | ||
| 322 | SHR AL,1 | ||
| 323 | ADC CS:[DAYCNT],0 ; ADD IT IN TO OUR REMEMBERED DAY COUNT | ||
| 324 | ; | ||
| 325 | ; COMPUTE ELAPSED TIME | ||
| 326 | ; | ||
| 327 | MOV AX,WORD PTR DS:[DI].TIM_LO ; GET STORED TIME | ||
| 328 | SUB DX,AX | ||
| 329 | MOV AX,WORD PTR DS:[DI].TIM_HI | ||
| 330 | SBB CX,AX | ||
| 331 | ; | ||
| 332 | ; CX:DX IS THE ELAPSED TIME | ||
| 333 | ; | ||
| 334 | JNZ TIMECHECK_UNK ; CX <> 0 => > 1 HOUR | ||
| 335 | OR DX,DX ; TIME MUST PASS | ||
| 336 | JNZ TIMEPASSED ; YES, EXAMINE MAX VALUE | ||
| 337 | ; | ||
| 338 | ; NO NOTICEABLE TIME HAS PASSED. WE CANNOT TRUST THE COUNTER TO BE ALWAYS | ||
| 339 | ; AVAILABLE AS THERE ARE BOGUS PROGRAMS THAT GO AND REPROGRAM THE THING. WE | ||
| 340 | ; KEEP A COUNT OF THE NUMBER OF MEDIA CHECKS THAT WE'VE SEEN THAT DO NOT HAVE | ||
| 341 | ; ANY TIME PASSING. IF WE EXCEED A GIVE THRESHOLD, WE GIVE UP ON THE TIMER. | ||
| 342 | ; | ||
| 343 | INC BYTE PTR CS:ACCESSCOUNT | ||
| 344 | CMP BYTE PTR CS:ACCESSCOUNT,ACCESSMAX | ||
| 345 | JB TIMECHECK_RET ; IF COUNT IS LESS THAN THRESHOLD, OK | ||
| 346 | DEC BYTE PTR CS:ACCESSCOUNT ; DON'T LET THE COUNT WRAP | ||
| 347 | JMP SHORT TIMECHECK_UNK ; "I DON'T KNOW" IF MEDIA CHANGED | ||
| 348 | ; | ||
| 349 | ; 18.2 TICS PER SECOND. | ||
| 350 | ; | ||
| 351 | TIMEPASSED: | ||
| 352 | CMP DX,18 * 2 ; MIN ELAPSED TIME? | ||
| 353 | JBE TIMECHECK_RET ; YES, PRESUME NO CHANGE | ||
| 354 | ; | ||
| 355 | ; EVERYTHING INDICATES THAT WE DO NOT KNOW WHAT HAS HAPPENED. | ||
| 356 | ; | ||
| 357 | TIMECHECK_UNK: | ||
| 358 | DEC SI ; PRESUME I DON'T KNOW | ||
| 359 | TIMECHECK_RET: | ||
| 360 | RET | ||
| 361 | CHECK_TIME_OF_ACCESS ENDP | ||
| 362 | |||
| 363 | ERR$EXITJ2: JMP ERR$EXITJ | ||
| 364 | ; | ||
| 365 | ; BUILD A VALID BPB FOR THE DISK IN THE DRIVE. | ||
| 366 | ; | ||
| 367 | PUBLIC GET$BPB | ||
| 368 | GET$BPB PROC NEAR | ||
| 369 | MESSAGE FTESTDISK,<"DISK BUILD BPB "> | ||
| 370 | MNUM FTESTDISK,AX | ||
| 371 | MESSAGE FTESTDISK,<CR,LF> | ||
| 372 | MOV AH,BYTE PTR ES:[DI] ;GET FAT ID BYTE READ BY DOS | ||
| 373 | CALL SETDRIVE ; GET THE CORRECT BDS FOR THE DRIVE | ||
| 374 | TEST WORD PTR [DI].FLAGS,FNON_REMOVABLE | ||
| 375 | JNZ ALREADY_GOTBPB ; NO NEED TO BUILD FOR FIXED DISKS | ||
| 376 | ;J.K. Let's set the default value for VOLID,Vol_Serial,FileSys_ID in BDS table | ||
| 377 | call Clear_IDs ;AN000; | ||
| 378 | mov cs:[Set_ID_Flag],1 ;AN000; Indicate to set system id in BDS | ||
| 379 | CALL GETBP ;BUILD A BPB IF NECESSARY. | ||
| 380 | JC ERR$EXITJ2 ;AN000; If error, Set_ID_flag is set to 0 already. | ||
| 381 | cmp cs:[Set_ID_Flag],2 ;AN000; Already, volume_Label set from Boot record | ||
| 382 | mov cs:[Set_ID_Flag],0 ;AN000; to BDS table? | ||
| 383 | je Already_GotBPB ;AN000; Then do not set it again from Root directory. | ||
| 384 | ;AN000; Otherwise, conventional Boot record. | ||
| 385 | GET$BPB ENDP | ||
| 386 | ;----------------------------------------| | ||
| 387 | ; WARNING: DO NOT CHANGE THE FOLLOWING. ;| | ||
| 388 | ; IT GETS PATCHED IN MSINIT ;| | ||
| 389 | PUBLIC SET_PATCH ;| | ||
| 390 | SET_PATCH PROC NEAR ;| | ||
| 391 | CALL SET_VOLUME_ID ;| | ||
| 392 | ;----------------------------------------| | ||
| 393 | MESSAGE FTESTDISK,<"SET VOLUME ID"> | ||
| 394 | MNUM FTESTDISK,DI | ||
| 395 | MESSAGE FTESTDISK,<" "> | ||
| 396 | MNUM FTESTDISK,DS | ||
| 397 | MESSAGE FTESTDISK,<CR,LF> | ||
| 398 | |||
| 399 | ALREADY_GOTBPB: | ||
| 400 | ADD DI,BYTEPERSEC ; RETURN THE BPB THAT IS IN THE CURRENT BDS | ||
| 401 | |||
| 402 | PUBLIC SETPTRSAV | ||
| 403 | SETPTRSAV: ; RETURN POINT FOR DSK$INIT | ||
| 404 | LES BX,CS:[PTRSAV] | ||
| 405 | MOV ES:[BX].MEDIA,AH | ||
| 406 | MOV ES:[BX].COUNT,DI | ||
| 407 | MOV ES:[BX].COUNT+2,DS | ||
| 408 | JMP EXIT | ||
| 409 | SET_PATCH ENDP | ||
| 410 | |||
| 411 | ;J.K. Clear IDs in BDS table. Only applied for Floppies. | ||
| 412 | ;Input: DS:DI -> BDS table | ||
| 413 | ;Output: VOLID set to "NO NAME " | ||
| 414 | ; VOL_SERIAL set to 0. | ||
| 415 | ; FileSys_ID set to "FAT12 " or "FAT16 " | ||
| 416 | ; depending on the flag FATSIZE in BDS. | ||
| 417 | ;All registers saved. | ||
| 418 | public Clear_IDs | ||
| 419 | Clear_IDs proc near ;AN000; | ||
| 420 | push ds ;AN000; | ||
| 421 | push di ;AN000; | ||
| 422 | push es ;AN000; | ||
| 423 | push si ;AN000; | ||
| 424 | push cx ;AN000; | ||
| 425 | |||
| 426 | push ds ;AN000; | ||
| 427 | pop es ;AN000; es -> bds | ||
| 428 | push cs ;AN000; | ||
| 429 | pop ds ;AN000; ds = cs | ||
| 430 | |||
| 431 | mov cx, 0 ;AN000; no serial number | ||
| 432 | mov word ptr es:[di.VOL_SERIAL],cx ;AN000; | ||
| 433 | mov word ptr es:[di.VOL_SERIAL]+2,cx ;AN000; | ||
| 434 | |||
| 435 | mov cx, BOOT_VOLUME_LABEL_SIZE ;AN000; =11 | ||
| 436 | mov si, offset VOL_NO_NAME ;AN000; | ||
| 437 | push di ;AN000; save BDS pointer | ||
| 438 | add di, VOLID ;AN000; points to VOLID field | ||
| 439 | rep movsb ;AN000; | ||
| 440 | pop di ;AN000; restore BDS pointer | ||
| 441 | test es:[di.FATSIZ], FBIG ;AN000; | ||
| 442 | jnz CI_BigFat ;AN000; small fat | ||
| 443 | mov si, offset FAT_12_ID ;AN000; | ||
| 444 | jmp CI_Filesys ;AN000; | ||
| 445 | CI_BigFat: ;AN000; | ||
| 446 | mov si, offset FAT_16_ID ;AN000; big fat | ||
| 447 | CI_Filesys: ;AN000; | ||
| 448 | mov cx, BOOT_SYSTEM_ID_SIZE ;AN000; =8 | ||
| 449 | add di, FILESYS_ID ;AN000; points to FILESYS_ID field | ||
| 450 | rep movsb ;AN000; | ||
| 451 | |||
| 452 | pop cx ;AN000; | ||
| 453 | pop si ;AN000; | ||
| 454 | pop es ;AN000; | ||
| 455 | pop di ;AN000; | ||
| 456 | pop ds ;AN000; | ||
| 457 | ret ;AN000; | ||
| 458 | Clear_IDs endp ;AN000; | ||
| 459 | |||
| 460 | |||
| 461 | ; GETBP - RETURN BPB FROM THE DRIVE SPECIFIED BY THE BDS. | ||
| 462 | ; IF THE RETURN_FAKE_BPB FLAG IS SET, THEN IT DOES NOTHING. | ||
| 463 | ; NOTE THAT WE NEVER COME HERE FOR FIXED DISKS. | ||
| 464 | ; FOR ALL OTHER CASES, | ||
| 465 | ; - IT READS BOOT SECTOR TO PULL OUT THE BPB | ||
| 466 | ; - IF NO VALID BPB IS FOUND, IT THEN READS THE FAT SECTOR, | ||
| 467 | ; TO GET THE FAT ID BYTE TO BUILD THE BPB FROM THERE. | ||
| 468 | ; | ||
| 469 | ; INPUTS: DS:DI POINT TO CORRECT BDS. | ||
| 470 | ; | ||
| 471 | ; OUTPUTS: FILLS IN BPB IN CURRENT BDS IF VALID BPB OR FAT ID ON DISK. | ||
| 472 | ; CARRY SET, AND AL=7 IF INVALID DISK. | ||
| 473 | ; CARRY SET AND ERROR CODE IN AL IF OTHER ERROR. | ||
| 474 | ; If failed to recognize the Boot Record, then will set the | ||
| 475 | ; Set_ID_Flag to 0. | ||
| 476 | ; J.K. This routine will only work for a floppy diskette. | ||
| 477 | ; For a fixed disk, it will just return. | ||
| 478 | |||
| 479 | PUBLIC GETBP | ||
| 480 | GETBP PROC NEAR | ||
| 481 | ; IF RETURNING FAKE BPB THEN RETURN BPB AS IS. | ||
| 482 | TEST WORD PTR [DI].FLAGS,RETURN_FAKE_BPB OR FNON_REMOVABLE | ||
| 483 | JZ GETBP1 | ||
| 484 | JMP GETRET_EXIT | ||
| 485 | |||
| 486 | GETBP1: | ||
| 487 | MESSAGE FTESTDISK,<"BUILDING BPB FROM SCRATCH",CR,LF> | ||
| 488 | SAVEREG <CX,DX,ES,BX> | ||
| 489 | ; | ||
| 490 | ; ATTEMPT TO READ IN BOOT SECTOR AND DETERMINE BPB. | ||
| 491 | ; WE ASSUME THAT THE 2.X AND GREATER DOS DISKS ALL HAVE A VALID BOOT SECTOR. | ||
| 492 | ; | ||
| 493 | RDBOOT: | ||
| 494 | CALL READBOOTSEC | ||
| 495 | JC GETBP_ERR_RET_brdg ; CARRY SET IF THERE WAS ERROR. | ||
| 496 | CMP BX,0 ; BX IS 0 IF BOOT SECTOR IS VALID. | ||
| 497 | JNZ DOFATBPB | ||
| 498 | |||
| 499 | CALL MOVBPB ; MOVE BPB INTO REGISTERS. | ||
| 500 | JMP HAS1 | ||
| 501 | |||
| 502 | Getbp_err_ret_brdg: jmp Getbp_err_ret | ||
| 503 | ; | ||
| 504 | ; WE HAVE A 1.X DISKETTE. | ||
| 505 | ; IN THIS CASE READ IN THE FAT ID BYTE AND FILL IN BPB FROM THERE. | ||
| 506 | ; | ||
| 507 | DOFATBPB: | ||
| 508 | CALL READFAT ; PUTS MEDIA DESCRIPTOR BYTE IN AH | ||
| 509 | JC GETBP_ERR_RET_Brdg | ||
| 510 | ;----------------------------------------| | ||
| 511 | ; WARNING: DO NOT CHANGE THE FOLLOWING. ;| | ||
| 512 | ; IT GETS PATCHED IN MSINIT ;| | ||
| 513 | PUBLIC GETBP1_PATCH ;| | ||
| 514 | GETBP1_PATCH: ;| | ||
| 515 | CALL HIDENSITY ;| | ||
| 516 | ;----------------------------------------| | ||
| 517 | ;TEST FOR A VALID 3.5" MEDIUM | ||
| 518 | CMP [DI].FORMFACTOR,FFSMALL | ||
| 519 | JNZ IS_FLOPPY | ||
| 520 | CMP AH,0F9H ; IS IT A VALID FAT ID BYTE FOR 3.5" ? | ||
| 521 | JNZ GOT_UNKNOWN_MEDIUM | ||
| 522 | MOV BX,OFFSET SM92 ; POINTER TO CORRECT BPB | ||
| 523 | PUSH CS | ||
| 524 | POP ES | ||
| 525 | |||
| 526 | ASSUME ES:CODE | ||
| 527 | ;J.K. DS points to segment of BDS. The following should be modified | ||
| 528 | ;J.K. to get spf,csec,spa,spt correctly. It had been wrong if DRIVER.SYS | ||
| 529 | ;J.K. is loaded since the BDS is inside the driver.sys. | ||
| 530 | MOV AL,es:[BX.SPF] | ||
| 531 | MOV CX,es:[BX.CSEC] | ||
| 532 | MOV DX,WORD PTR es:[BX.SPA] | ||
| 533 | MOV BX,WORD PTR es:[BX.SPT] | ||
| 534 | JMP SHORT HAS1 | ||
| 535 | ; MUST BE A 5.25" FLOPPY IF WE COME HERE | ||
| 536 | IS_FLOPPY: | ||
| 537 | MOV CL,AH ;SAVE MEDIA | ||
| 538 | AND CL,0F8H ;NORMALIZE | ||
| 539 | CMP CL,0F8H ;COMPARE WITH GOOD MEDIA BYTE | ||
| 540 | JNZ GOT_UNKNOWN_MEDIUM | ||
| 541 | |||
| 542 | GOODID: | ||
| 543 | MOV AL,1 ;SET NUMBER OF FAT SECTORS | ||
| 544 | MOV BX,64*256+8 ;SET DIR ENTRIES AND SECTOR MAX | ||
| 545 | MOV CX,40*8 ;SET SIZE OF DRIVE | ||
| 546 | MOV DX,01*256+1 ;SET HEAD LIMIT AND SEC/ALL UNIT | ||
| 547 | TEST AH,00000010B ;TEST FOR 8 OR 9 SECTOR | ||
| 548 | JNZ HAS8 ;NZ = HAS 8 SECTORS | ||
| 549 | INC AL ;INC NUMBER OF FAT SECTORS | ||
| 550 | INC BL ;INC SECTOR MAX | ||
| 551 | ADD CX,40 ;INCREASE SIZE | ||
| 552 | HAS8: | ||
| 553 | TEST AH,00000001B ;TEST FOR 1 OR 2 HEADS | ||
| 554 | JZ HAS1 ;Z = 1 HEAD | ||
| 555 | ADD CX,CX ;DOUBLE SIZE OF DISK | ||
| 556 | MOV BH,112 ;INCREASE NUMBER OF DIRECTORY ENTRIES | ||
| 557 | INC DH ;INC SEC/ALL UNIT | ||
| 558 | INC DL ;INC HEAD LIMIT | ||
| 559 | |||
| 560 | HAS1: | ||
| 561 | PUBLIC HAS1 | ||
| 562 | |||
| 563 | MOV BYTE PTR DS:[DI].SECPERCLUS,DH | ||
| 564 | MOV BYTE PTR DS:[DI].CDIR,BH | ||
| 565 | MOV WORD PTR DS:[DI].DRVLIM,CX | ||
| 566 | MOV BYTE PTR DS:[DI].MEDIAD,AH | ||
| 567 | MOV BYTE PTR DS:[DI].CSECFAT,AL | ||
| 568 | MOV BYTE PTR DS:[DI].SECLIM,BL | ||
| 569 | MOV BYTE PTR DS:[DI].HDLIM,DL | ||
| 570 | ;SB34DISK001******************************************************************* | ||
| 571 | ;SB the HIDSEC_H field and DRVLIM_L field and the | ||
| 572 | ;SB DRVLIM_H fields need to be set to 0 since this code here is for floppies | ||
| 573 | ;SB 3 LOCS | ||
| 574 | |||
| 575 | mov word ptr ds:[di].HIDSEC_H,0 | ||
| 576 | mov word ptr ds:[di].HIDSEC_L,0 | ||
| 577 | mov word ptr ds:[di].DRVLIM_H,0 | ||
| 578 | |||
| 579 | ;SB34DISK001******************************************************************* | ||
| 580 | GETRET: | ||
| 581 | POP BX | ||
| 582 | RESTOREREG <ES,DX,CX> | ||
| 583 | |||
| 584 | ASSUME ES:NOTHING | ||
| 585 | |||
| 586 | GETRET_EXIT: | ||
| 587 | RET | ||
| 588 | |||
| 589 | GETBP_ERR_RET: | ||
| 590 | ;J.K. Before doing anything else, set Set_ID_Flag to 0. | ||
| 591 | mov cs:Set_ID_Flag, 0 ;AN000; | ||
| 592 | CALL MAPERROR | ||
| 593 | JMP SHORT GETRET | ||
| 594 | ; | ||
| 595 | ; WE HAVE A 3.5" DISKETTE FOR WHICH WE CANNOT BUILD A BPB. WE DO NOT ASSUME ANY | ||
| 596 | ; TYPE OF BPB FOR THIS MEDIUM. | ||
| 597 | ; | ||
| 598 | GOT_UNKNOWN_MEDIUM: | ||
| 599 | mov cs:Set_ID_Flag, 0 ;AN000; | ||
| 600 | MOV AL,ERROR_UNKNOWN_MEDIA | ||
| 601 | STC | ||
| 602 | JMP SHORT GETRET | ||
| 603 | GETBP ENDP | ||
| 604 | |||
| 605 | BPBTYPE STRUC | ||
| 606 | SPF DB ? | ||
| 607 | SPT DB ? | ||
| 608 | CDIRE DB ? | ||
| 609 | CSEC DW ? | ||
| 610 | SPA DB ? | ||
| 611 | CHEAD DB ? | ||
| 612 | BPBTYPE ENDS | ||
| 613 | |||
| 614 | ; | ||
| 615 | ; READ IN THE BOOT SECTOR. SET CARRY IF ERROR IN READING SECTOR. | ||
| 616 | ; BX IS SET TO 1 IF THE BOOT SECTOR IS INVALID, OTHERWISE IT IS 0. | ||
| 617 | ; | ||
| 618 | READBOOTSEC PROC NEAR | ||
| 619 | MOV DH,0 ;HEAD 0 | ||
| 620 | MOV CX,0001 ;CYLINDER 0, SECTOR 1 | ||
| 621 | CALL READ_SECTOR | ||
| 622 | JC ERR_RET | ||
| 623 | XOR BX,BX ; ASSUME VALID BOOT SECTOR. | ||
| 624 | |||
| 625 | ;******************************************************************************* | ||
| 626 | ; PUT A SANITY CHECK FOR THE BOOT SECTOR IN HERE TO DETECT BOOT SECTORS THAT | ||
| 627 | ; DO NOT HAVE VALID BPBS. | ||
| 628 | ; WE EXAMINE THE FIRST TWO BYTES - THEY MUST CONTAIN A LONG JUMP (69H) OR A | ||
| 629 | ; SHORT JUMP (EBH) FOLLOWED BY A NOP (90H), OR A SHORT JUMP (E9H). | ||
| 630 | ; IF THIS TEST IS PASSED, WE FURTHER CHECK BY EXAMINING THE SIGNATURE AT | ||
| 631 | ; THE END OF THE BOOT SECTOR FOR THE WORD AA55H. | ||
| 632 | ; IF THE SIGNATURE IS NOT PRESENT, WE EXAMINE THE MEDIA DESCRIPTOR BYTE TO | ||
| 633 | ; SEE IF IT IS VALID. | ||
| 634 | ;J.K. 10/15/86 DCR00012. For DOS 3.3, this logic is modified a little bit. | ||
| 635 | ; We are not going to check Signature. Instead we are going to sanity | ||
| 636 | ; check the media byte in BPB regardless of the validity of signature. | ||
| 637 | ; This is to save the already developed commercial products that have | ||
| 638 | ; good jump instruction and signature but with the false BPB informations | ||
| 639 | ; that will crash the diskette drive operation. (For example, Symphony diskette). | ||
| 640 | ;****************************************************************************** | ||
| 641 | CMP BYTE PTR CS:[DISKSECTOR],069H ; IS IT A DIRECT JUMP? | ||
| 642 | JE Check_bpb_MediaByte ; DON'T NEED TO FIND A NOP | ||
| 643 | CMP BYTE PTR CS:[DISKSECTOR],0E9H ; DOS 2.0 JUMP? | ||
| 644 | JE Check_bpb_MediaByte ; NO NEED FOR NOP | ||
| 645 | CMP BYTE PTR CS:[DISKSECTOR],0EBH ; HOW ABOUT A SHORT JUMP. | ||
| 646 | JNE INVALIDBOOTSEC | ||
| 647 | CMP BYTE PTR CS:[DISKSECTOR]+2,090H ; IS NEXT ONE A NOP? | ||
| 648 | JNE INVALIDBOOTSEC | ||
| 649 | |||
| 650 | |||
| 651 | ;J.K. 10/15/86 Don't have to perform the following signature check since | ||
| 652 | ; we need to check the media byte even with the good signatured diskette. | ||
| 653 | ;CHECK_SIGNATURE: | ||
| 654 | ; CMP WORD PTR CS:[DISKSECTOR+1FEH],0AA55H ; SEE IF NON-IBM DISK OR 1.X | ||
| 655 | ; ; MEDIA. | ||
| 656 | ; JZ CHECKSINGLESIDED ; GO SEE IF SINGLE SIDED MEDIUM. MAY | ||
| 657 | ; ; NEED SOME SPECIAL HANDLING | ||
| 658 | ; | ||
| 659 | ; CHECK FOR NON-IBM DISKS WHICH DO NOT HAVE THE SIGNATURE AA55 AT THE | ||
| 660 | ; END OF THE BOOT SECTOR, BUT STILL HAVE A VALID BOOT SECTOR. THIS IS DONE | ||
| 661 | ; BY EXAMINING THE MEDIA DESCRIPTOR IN THE BOOT SECTOR. | ||
| 662 | ; | ||
| 663 | |||
| 664 | Check_bpb_MediaByte: | ||
| 665 | |||
| 666 | MOV AL,BYTE PTR CS:MEDIABYTE | ||
| 667 | AND AL,0F0H | ||
| 668 | CMP AL,0F0H ; ALLOW FOR STRANGE MEDIA | ||
| 669 | JNZ INVALIDBOOTSEC | ||
| 670 | ; | ||
| 671 | ; THERE WERE SOME (APPARENTLY A LOT OF THEM) DISKETTES THAT HAD BEEN FORMATTED | ||
| 672 | ; UNDER DOS 3.1 AND EARLIER VERSIONS WHICH HAVE INVALID BPBS IN THEIR BOOT | ||
| 673 | ; SECTORS. THESE ARE SPECIFICALLY DISKETTES THAT WERE FORMATTED IN DRIVES | ||
| 674 | ; WITH ONE HEAD, OR WHOSE SIDE 0 WAS BAD. THESE CONTAIN BPBS IN THE BOOT | ||
| 675 | ; SECTOR THAT HAVE THE SEC/CLUS FIELD SET TO 2 INSTEAD OF 1, AS IS STANDARD | ||
| 676 | ; IN DOS. IN ORDER TO SUPPORT THEM, WE HAVE TO INTRODUCE A "HACK" THAT WILL | ||
| 677 | ; HELP OUR BUILD BPB ROUTINE TO RECOGNISE THESE SPECIFIC CASES, AND TO | ||
| 678 | ; SET UP OUT COPY OF THE BPB ACCORDINGLY. | ||
| 679 | ; WE DO THIS BY CHECKING TO SEE IF THE BOOT SECTOR IS OFF A DISKETTE THAT | ||
| 680 | ; IS SINGLE-SIDED AND IS A PRE-DOS 3.20 DISKETTE. IF IT IS, WE SET THE | ||
| 681 | ; SEC/CLUS FIELD TO 1. IF NOT, WE CARRY ON AS NORMAL. | ||
| 682 | CHECKSINGLESIDED: | ||
| 683 | MOV AL,BYTE PTR CS:MEDIABYTE | ||
| 684 | TEST AL,0001H ; IS LOW BIT SET? - INDICATES DOUBLE SIDED | ||
| 685 | JNZ GOODDSK | ||
| 686 | CMP WORD PTR CS:[DISKSECTOR+8],"." SHL 8 + "3" | ||
| 687 | JNZ MUSTBEEARLIER | ||
| 688 | CMP BYTE PTR CS:[DISKSECTOR+10],"2" | ||
| 689 | JAE GOODDSK | ||
| 690 | |||
| 691 | ; WE MUST HAVE A PRE-3.20 DISKETTE. SET THE SEC/CLUS FIELD TO 1 | ||
| 692 | MUSTBEEARLIER: | ||
| 693 | MOV BYTE PTR CS:[SECPERCLUSINSECTOR],1 | ||
| 694 | JMP SHORT GOODDSK | ||
| 695 | ;****************************************************************************** | ||
| 696 | |||
| 697 | INVALIDBOOTSEC: | ||
| 698 | INC BX ; INDICATE THAT BOOT SECTOR INVALID | ||
| 699 | GOODDSK: ; CARRY ALREADY RESET | ||
| 700 | CLC | ||
| 701 | RET | ||
| 702 | |||
| 703 | ERR_RET: ; CARRY IS ALREADY SET ON ENTRY HERE | ||
| 704 | MESSAGE FTESTDISK,<"ERROR IN READBOOT",CR,LF> | ||
| 705 | RET | ||
| 706 | READBOOTSEC ENDP | ||
| 707 | |||
| 708 | ; MOVES THE BPB READ FROM THE BOOT SECTOR INTO REGISTERS FOR USE BY | ||
| 709 | ; GETBP ROUTINE AT HAS1 | ||
| 710 | ;J.K.- | ||
| 711 | ; If the Set_ID_Flag is 1, and if an extended Boot Record, then set Volume | ||
| 712 | ; Serial Number, Volume Label, File System ID in BDS according to | ||
| 713 | ; the BOOT reocrd. After that, this routine will set the Set_ID_Flag to 2 | ||
| 714 | ; to signal that VOLUME Label is set already from the Extended BOOT record | ||
| 715 | ; (so, don't set it again by calling "SET_VOLUME_ID" routine which uses | ||
| 716 | ; the volume label in the root directory. | ||
| 717 | |||
| 718 | MOVBPB PROC NEAR | ||
| 719 | SAVEREG <DS,DI> | ||
| 720 | PUSH CS | ||
| 721 | POP DS | ||
| 722 | MOV DI,OFFSET BPB_IN_SECTOR | ||
| 723 | MOV DH,BYTE PTR [DI].SECALL ;SECTORS PER UNIT | ||
| 724 | MOV BH,BYTE PTR [DI].DIRNUM ;NUMBER OF DIRECTORY ENTRIES | ||
| 725 | MOV CX,WORD PTR [DI].SECNUM ;SIZE OF DRIVE | ||
| 726 | MOV AH,BYTE PTR [DI].FATID ;MEDIA DESCRIPTOR | ||
| 727 | MOV AL,BYTE PTR [DI].FATSIZE ;NUMBER OF FAT SECTORS | ||
| 728 | MOV BL,BYTE PTR [DI].SLIM ;SECTORS PER TRACK | ||
| 729 | MOV DL,BYTE PTR [DI].HLIM ;NUMBER OF HEADS | ||
| 730 | RESTOREREG <DI,DS> | ||
| 731 | cmp cs:[Set_ID_Flag], 1 ;AC008 called by GET$BPB? | ||
| 732 | jne MovBPB_Ret ;AC008 | ||
| 733 | call Mov_Media_IDs ;AC008 | ||
| 734 | jc MovBPB_Conv ;AC008 Conventional boot record? | ||
| 735 | mov cs:[Set_ID_Flag],2 ;AC008 signals that Volume ID is set. | ||
| 736 | MovBPB_Conv: ;AC008 | ||
| 737 | cmp cs:fHave96, 1 ;AC008 | ||
| 738 | jne MovBPB_Ret ;AC008 | ||
| 739 | call ResetChanged ;AC008 Reset Flags in BDS to NOT fCHANGED. | ||
| 740 | MovBPB_Ret: ;AC008 | ||
| 741 | clc ;AC008 | ||
| 742 | ret ;AC008 | ||
| 743 | MOVBPB ENDP ;AC008 | ||
| 744 | |||
| 745 | |||
| 746 | ; | ||
| 747 | public Mov_Media_IDs | ||
| 748 | Mov_Media_IDs Proc near ;AN000; | ||
| 749 | ;copy the boot_serial number, Volume id, and Filesystem id from the | ||
| 750 | ;***Extended Boot record*** in cs:DiskSector to the BDS table pointed | ||
| 751 | ;by DS:DI. | ||
| 752 | ;In.) DS:DI -> BDS | ||
| 753 | ; CS:DiskSector = Valid extended boot record. | ||
| 754 | ;Out.) Vol_Serial, Volid and System_Id in BDS are set according to | ||
| 755 | ; the boot record information. | ||
| 756 | ; Carry flag set if not an extended BPB. | ||
| 757 | ; All registers saved except the flag. | ||
| 758 | |||
| 759 | cmp cs:[Ext_Boot_Sig], EXT_BOOT_SIGNATURE ;AN000; = 41 | ||
| 760 | jne MMI_Not_Ext ;AN000; | ||
| 761 | push cx ;AN000; | ||
| 762 | mov cx, cs:[Boot_Serial_L] ;AN000; | ||
| 763 | mov word ptr ds:[di.VOL_SERIAL],cx ;AN000; | ||
| 764 | mov cx, cs:[Boot_Serial_H] ;AN000; | ||
| 765 | mov word ptr ds:[di.VOL_SERIAL+2],cx ;AN000; | ||
| 766 | push ds ;AN000; Save regs. | ||
| 767 | push di ;AN000; | ||
| 768 | push es ;AN000; | ||
| 769 | push si ;AN000; | ||
| 770 | |||
| 771 | push ds ;AN000; ds-> cs, es-> bds | ||
| 772 | pop es ;AN000; | ||
| 773 | push cs ;AN000; | ||
| 774 | pop ds ;AN000; | ||
| 775 | |||
| 776 | mov cx, BOOT_VOLUME_LABEL_SIZE ;AN000; | ||
| 777 | mov si, offset Boot_Volume_Label;AN000; | ||
| 778 | push di | ||
| 779 | add di, VOLID ;AN000; | ||
| 780 | rep movsb ;AN000; | ||
| 781 | pop di | ||
| 782 | mov cx, BOOT_SYSTEM_ID_SIZE ;AN000; =8 | ||
| 783 | mov si, offset Boot_System_ID ;AN000; | ||
| 784 | add di, FILESYS_ID ;AN000; | ||
| 785 | rep movsb ;AN000; | ||
| 786 | |||
| 787 | pop si ;AN000; | ||
| 788 | pop es ;AN000; | ||
| 789 | pop di ;AN000; | ||
| 790 | pop ds ;AN000; | ||
| 791 | pop cx ;AN000; | ||
| 792 | clc ;AN000; | ||
| 793 | MMI_Ret: ;AN000; | ||
| 794 | ret ;AN000; | ||
| 795 | MMI_Not_Ext: ;AN000; | ||
| 796 | stc ;AN000; | ||
| 797 | ret ;AN000; | ||
| 798 | Mov_Media_IDs endp ;AN000; | ||
| 799 | |||
| 800 | |||
| 801 | ; READ IN THE FAT SECTOR AND GET THE MEDIA BYTE FROM IT. | ||
| 802 | ; INPUT : AL CONTAINS LOGICAL DRIVE. | ||
| 803 | ; OUTPUT: | ||
| 804 | ; CARRY SET IF AN ERROR OCCURS, AX CONTAINS ERROR CODE. | ||
| 805 | ; OTHERWISE, AH CONTAINS MEDIA BYTE ON EXIT. AL IS PRESERVED. | ||
| 806 | |||
| 807 | READFAT PROC NEAR | ||
| 808 | PUSH AX ; PRESERVE LOGICAL DRIVE IN AL | ||
| 809 | MOV DH,0 ; HEAD 0 | ||
| 810 | MOV CX,0002 ; CYLINDER 0, SECTOR 2 | ||
| 811 | CALL READ_SECTOR ; CS:BX POINTS TO FAT SECTOR | ||
| 812 | JC BAD_FAT_RET | ||
| 813 | POP AX ; RESET LOGICAL DRIVE | ||
| 814 | MOV AH,BYTE PTR CS:[BX] ; MEDIA BYTE | ||
| 815 | RET | ||
| 816 | |||
| 817 | BAD_FAT_RET: ; CARRY SET ON ENTRY | ||
| 818 | MESSAGE FTESTDISK,<"ERROR IN FAT READ",CR,LF> | ||
| 819 | POP CX ; CLEAR STACK | ||
| 820 | RET | ||
| 821 | READFAT ENDP | ||
| 822 | |||
| 823 | ; READ A SINGLE SECTOR INTO THE TEMP BUFFER. | ||
| 824 | ; PERFORM THREE RETRIES IN CASE OF ERROR. | ||
| 825 | ; INPUTS: DRIVE HAS PHYSICAL DRIVE TO USE | ||
| 826 | ; CX HAS SECTOR AND CYLINDER | ||
| 827 | ; DH HAS HEAD | ||
| 828 | ; OUTPUTS: CARRY CLEAR | ||
| 829 | ; CS:BX POINT TO SECTOR | ||
| 830 | ; CARRY SET | ||
| 831 | ; AX HAS ROM ERROR CODE | ||
| 832 | ; REGISTERS ES AND BP ARE PRESERVED. | ||
| 833 | |||
| 834 | READ_SECTOR PROC NEAR | ||
| 835 | PUBLIC READ_SECTOR | ||
| 836 | |||
| 837 | PUSH BP | ||
| 838 | MOV BP,3 ; MAKE 3 ATTEMPTS | ||
| 839 | PUSH ES | ||
| 840 | ;SB33015***************************************************************** | ||
| 841 | mov DL, byte ptr ds:[di].DriveNum ;SB;3.30* | ||
| 842 | mov BX, offset DiskSector ; Get ES:BX to point to buffer ;SB;3.30* | ||
| 843 | push CS ; get the segment right ;SB;3.30* | ||
| 844 | pop ES ; now ES:BX is correct ;SB;3.30* | ||
| 845 | ;SB33015***************************************************************** | ||
| 846 | RD_RET: | ||
| 847 | ;SB33016***************************************************************** | ||
| 848 | mov AX, 0201h ; number of sectors to 1 (AL=1);SB;3.30* | ||
| 849 | int 13h ; call rom-bios disk routines ;SB;3.30* | ||
| 850 | |||
| 851 | ;SB33016***************************************************************** | ||
| 852 | JNC OKRET2 | ||
| 853 | Rd_rty: | ||
| 854 | CALL AGAIN ; RESET DISK, DECREMENT BP, PRESERVE AX | ||
| 855 | jz Err_RD_RET | ||
| 856 | test word ptr ds:[di].flags,fNon_Removable | ||
| 857 | JNZ RD_RET | ||
| 858 | cmp cs:[Media_Set_For_Format], 0 ;AN012; | ||
| 859 | jne Rd_Skip1_DPT ;AN012; | ||
| 860 | push ds ;J.K. 11/7/86 For retry, set the head settle time | ||
| 861 | push ax ;to 0Fh. PTM845. | ||
| 862 | lds si,cs:DPT | ||
| 863 | mov al, ds:[si].disk_head_sttl | ||
| 864 | mov cs:[save_head_sttl],al | ||
| 865 | mov byte ptr ds:[si].disk_head_sttl, NormSettle | ||
| 866 | pop ax | ||
| 867 | pop ds | ||
| 868 | Rd_Skip1_DPT: ;AN012; | ||
| 869 | ;SB33017***************************************************************** | ||
| 870 | ; SET CMD TO READ (AH=2) AND ;SB ;3.30 | ||
| 871 | MOV AX, 0201h ; NUM OF SECTORS TO 1 (AL=1) ;SB ;3.30 | ||
| 872 | INT 13h ; CALL ROM-BIOS DISK ROUTINES ;SB ;3.30 | ||
| 873 | ;SB33017***************************************************************** | ||
| 874 | pushf ;AN012; | ||
| 875 | cmp cs:[Media_Set_For_Format], 0 ;AN012; | ||
| 876 | jne Rd_Skip2_DPT ;AN012; | ||
| 877 | push ds | ||
| 878 | push ax | ||
| 879 | lds si,cs:DPT | ||
| 880 | mov al, cs:[save_head_sttl] | ||
| 881 | mov byte ptr ds:[si].disk_head_sttl, al | ||
| 882 | pop ax | ||
| 883 | pop ds | ||
| 884 | Rd_Skip2_DPT: ;AN012; | ||
| 885 | popf ;AN012; | ||
| 886 | jnc OKRET2 | ||
| 887 | jmp Rd_rty | ||
| 888 | ERR_RD_RET: | ||
| 889 | MOV DL,-1 ; MAKE SURE WE ASK ROM IF MEDIA HAS CHANGED | ||
| 890 | STC ; RETURN ERROR | ||
| 891 | ; UPDATE INFORMATION PERTAINING TO LAST DRIVE ACCESSED, TIME OF ACCESS, LAST | ||
| 892 | ; TRACK ACCESSED IN THAT DRIVE. | ||
| 893 | OKRET2: | ||
| 894 | MOV CS:[STEP_DRV],DL ; SET UP FOR HEAD SETTLE LOGIC IN DISK. | ||
| 895 | MOV CS:[TIM_DRV],DL ;SAVE DRIVE LAST ACCESSED | ||
| 896 | MOV BYTE PTR [DI].TRACK,CH ; SAVE LAST TRACK ACCESSED ON THIS DRIVE | ||
| 897 | PUSHF ; PRESERVE FLAGS IN CASE ERROR OCCURRED | ||
| 898 | CALL SET_TIM | ||
| 899 | POPF ; RESTORE FLAGS | ||
| 900 | POP ES | ||
| 901 | POP BP | ||
| 902 | RET | ||
| 903 | READ_SECTOR ENDP | ||
| 904 | |||
| 905 | ;----------------------------------------------------------- | ||
| 906 | ; | ||
| 907 | ; DISK REMOVABLE ROUTINE ARR 2.41 | ||
| 908 | ; | ||
| 909 | |||
| 910 | DSK$REM PROC NEAR ;ARR 2.41 | ||
| 911 | PUBLIC DSK$REM | ||
| 912 | |||
| 913 | MESSAGE FTESTDISK,<"DISK REMOVABLE "> | ||
| 914 | MNUM FTESTDISK,AX | ||
| 915 | MESSAGE FTESTDISK,<CR,LF> | ||
| 916 | ; AL IS UNIT # | ||
| 917 | CALL SETDRIVE ; GET BDS FOR THIS DRIVE | ||
| 918 | TEST WORD PTR [DI].FLAGS,FNON_REMOVABLE | ||
| 919 | JNZ NON_REM | ||
| 920 | JMP EXIT | ||
| 921 | |||
| 922 | NON_REM: | ||
| 923 | JMP BUS$EXIT ;ARR 2.41 | ||
| 924 | DSK$REM ENDP | ||
| 925 | |||
| 926 | ; SETDRIVE SCANS THROUGH THE DATA STRUCTURE OF BDSS, AND RETURNS A POINTER TO | ||
| 927 | ; THE ONE THAT BELONGS TO THE DRIVE SPECIFIED. CARRY IS SET IF NONE EXISTS FOR | ||
| 928 | ; THE DRIVE. | ||
| 929 | ; IF THE BYTE [PHYS_DRV] IS 0 THEN | ||
| 930 | ; ON ENTRY, AL CONTAINS THE LOGICAL DRIVE NUMBER. | ||
| 931 | ; ON EXIT, DS:DI POINTS TO CORRECT BDS FOR THE DRIVE IF CARRY CLEAR. | ||
| 932 | |||
| 933 | ; ELSE IF THE BYTE [PHYS_DRV] IS 1 THEN (ONLY USED FOR FIXED DISKS WHEN AN ECC | ||
| 934 | ; ERROR OCCURS) | ||
| 935 | ; ON ENTRY, DL CONTAINS THE PYHSICAL DRIVE NUMBER. | ||
| 936 | ; ON EXIT, DS:DI POINTS TO CORRECT BDS FOR THE DRIVE IF CARRY CLEAR. | ||
| 937 | |||
| 938 | PUBLIC SETDRIVE | ||
| 939 | SETDRIVE PROC NEAR | ||
| 940 | MESSAGE FTESTDISK,<"SETDRIVE",CR,LF> | ||
| 941 | PUSH BX | ||
| 942 | PUSH CS | ||
| 943 | POP DS | ||
| 944 | ASSUME DS:CODE | ||
| 945 | |||
| 946 | ; ASSUME FIRST BDS IS IN THIS SEGMENT | ||
| 947 | MOV DI,WORD PTR START_BDS | ||
| 948 | SCAN_LOOP: | ||
| 949 | CMP BYTE PTR CS:[PHYS_DRV],1 ; DOES AL HAVE PHYSICAL DRIVE? | ||
| 950 | JB USE_LOGICAL_DRV | ||
| 951 | CMP BYTE PTR [DI].DRIVENUM,AL | ||
| 952 | JE SETDRV | ||
| 953 | JMP SHORT GET_NXT_BDS | ||
| 954 | USE_LOGICAL_DRV: | ||
| 955 | CMP BYTE PTR [DI].DRIVELET,AL | ||
| 956 | JE SETDRV | ||
| 957 | GET_NXT_BDS: | ||
| 958 | MOV BX,WORD PTR [DI].LINK+2 ; GO TO NEXT BDS | ||
| 959 | MOV DI,WORD PTR [DI].LINK | ||
| 960 | MOV DS,BX | ||
| 961 | ASSUME DS:NOTHING | ||
| 962 | |||
| 963 | CMP DI,-1 | ||
| 964 | JNZ SCAN_LOOP | ||
| 965 | STC | ||
| 966 | SETDRV: | ||
| 967 | POP BX | ||
| 968 | RET | ||
| 969 | SETDRIVE ENDP | ||
| 970 | |||
| 971 | ;----------------------------------------------------------- | ||
| 972 | ; | ||
| 973 | ; DISK I/O ROUTINES | ||
| 974 | ; | ||
| 975 | |||
| 976 | DSK$WRITV PROC NEAR | ||
| 977 | PUBLIC DSK$WRITV | ||
| 978 | |||
| 979 | MESSAGE FTESTDISK,<"DISK WRITE WITH VERIFY "> | ||
| 980 | MNUM FTESTDISK,AX | ||
| 981 | MESSAGE FTESTDISK,<" "> | ||
| 982 | MNUM FTESTDISK,DX | ||
| 983 | MESSAGE FTESTDISK,<" FOR "> | ||
| 984 | MNUM FTESTDISK,CX | ||
| 985 | MESSAGE FTESTDISK,<CR,LF> | ||
| 986 | MOV CS:[WRTVERIFY],103H | ||
| 987 | JMP SHORT DSK$CL | ||
| 988 | |||
| 989 | DSK$WRIT: | ||
| 990 | PUBLIC DSK$WRIT | ||
| 991 | MESSAGE FTESTDISK,<"DISK WRITE "> | ||
| 992 | MNUM FTESTDISK,AX | ||
| 993 | MESSAGE FTESTDISK,<" "> | ||
| 994 | MNUM FTESTDISK,DX | ||
| 995 | MESSAGE FTESTDISK,<" FOR "> | ||
| 996 | MNUM FTESTDISK,CX | ||
| 997 | MESSAGE FTESTDISK,<CR,LF> | ||
| 998 | MOV CS:[WRTVERIFY],ROMWRITE | ||
| 999 | |||
| 1000 | DSK$CL: | ||
| 1001 | CALL DISKIO | ||
| 1002 | DSK$IO: | ||
| 1003 | JC DSKBAD | ||
| 1004 | JMP EXIT | ||
| 1005 | DSKBAD: | ||
| 1006 | JMP ERR$CNT | ||
| 1007 | DSK$WRITV ENDP | ||
| 1008 | |||
| 1009 | DSK$READ PROC NEAR | ||
| 1010 | PUBLIC DSK$READ | ||
| 1011 | MESSAGE FTESTDISK,<"DISK READ "> | ||
| 1012 | MNUM FTESTDISK,AX | ||
| 1013 | MESSAGE FTESTDISK,<" "> | ||
| 1014 | MNUM FTESTDISK,DX | ||
| 1015 | MESSAGE FTESTDISK,<" FOR "> | ||
| 1016 | MNUM FTESTDISK,CX | ||
| 1017 | MESSAGE FTESTDISK,<CR,LF> | ||
| 1018 | CALL DISKRD | ||
| 1019 | JMP DSK$IO | ||
| 1020 | DSK$READ ENDP | ||
| 1021 | |||
| 1022 | ; MISCELLANEOUS ODD JUMP ROUTINES. MOVED OUT OF MAINLINE FOR SPEED. | ||
| 1023 | |||
| 1024 | |||
| 1025 | ; IF WE HAVE A SYSTEM WHERE WE HAVE VIRTUAL DRIVES, WE NEED TO PROMPT THE | ||
| 1026 | ; USER TO PLACE THE CORRECT DISK IN THE DRIVE. | ||
| 1027 | |||
| 1028 | CHECKSINGLE PROC NEAR | ||
| 1029 | PUBLIC CHECKSINGLE | ||
| 1030 | |||
| 1031 | PUSH AX | ||
| 1032 | PUSH BX | ||
| 1033 | MOV BX,WORD PTR DS:[DI].FLAGS | ||
| 1034 | ; IF HARD DRIVE, CANNOT CHANGE DISK. | ||
| 1035 | ; IF CURRENT OWNER OF PHYSICAL DRIVE, NO NEED TO CHANGE DISKETTE. | ||
| 1036 | TEST BL,FNON_REMOVABLE OR FI_OWN_PHYSICAL | ||
| 1037 | JNZ SINGLERET | ||
| 1038 | TEST BL,FI_AM_MULT ; IS THERE A DRIVE SHARING THIS | ||
| 1039 | ; PHYSICAL DRIVE? | ||
| 1040 | JZ SINGLERET | ||
| 1041 | ; LOOK FOR THE PREVIOUS OWNER OF THIS PHYSICAL DRIVE AND RESET ITS OWNERSHIP | ||
| 1042 | ; FLAG. | ||
| 1043 | MOV AL,DS:[DI].DRIVENUM ; GET PHYSICAL DRIVE NUMBER | ||
| 1044 | PUSH DS ; PRESERVE POINTER TO CURRENT BDS | ||
| 1045 | PUSH DI | ||
| 1046 | PUSH CS | ||
| 1047 | POP DS | ||
| 1048 | ASSUME DS:CODE | ||
| 1049 | |||
| 1050 | MOV DI,OFFSET START_BDS | ||
| 1051 | SCAN_LIST: | ||
| 1052 | MOV BX,WORD PTR [DI].LINK+2 ; GO TO NEXT BDS | ||
| 1053 | MOV DI,WORD PTR [DI].LINK | ||
| 1054 | MOV DS,BX | ||
| 1055 | ASSUME DS:NOTHING | ||
| 1056 | |||
| 1057 | CMP DI,-1 ; END OF LIST? | ||
| 1058 | JZ SINGLE_ERR_RET ; MUST BE ERROR | ||
| 1059 | CMP BYTE PTR [DI].DRIVENUM,AL | ||
| 1060 | JNZ SCAN_LIST | ||
| 1061 | |||
| 1062 | CHECK_OWN: | ||
| 1063 | MOV BX,WORD PTR [DI].FLAGS | ||
| 1064 | TEST BL,FI_OWN_PHYSICAL | ||
| 1065 | JZ SCAN_LIST | ||
| 1066 | XOR BL,FI_OWN_PHYSICAL ; RESET OWNERSHIP FLAG | ||
| 1067 | MOV WORD PTR DS:[DI].FLAGS,BX | ||
| 1068 | POP DI ; RESTORE POINTER TO CURRENT BDS | ||
| 1069 | POP DS | ||
| 1070 | XOR BX,BX | ||
| 1071 | OR BL,FI_OWN_PHYSICAL ; ESTABLISH CURRENT BDS AS OWNER | ||
| 1072 | OR WORD PTR [DI].FLAGS,BX | ||
| 1073 | |||
| 1074 | ; | ||
| 1075 | ; WE EXAMINE THE FSETOWNER FLAG. IF IT IS SET, THEN WE ARE USING THE CODE IN | ||
| 1076 | ; CHECKSINGLE TO JUST SET THE OWNER OF A DRIVE. WE MUST NOT ISSUE THE PROMPT | ||
| 1077 | ; IN THIS CASE. | ||
| 1078 | ; | ||
| 1079 | CMP BYTE PTR CS:[FSETOWNER],1 | ||
| 1080 | JZ SINGLERET | ||
| 1081 | ; TO SUPPORT "BACKWARD" COMPATIBILITY WITH IBM'S "SINGLE DRIVE STATUS BYTE" | ||
| 1082 | ; WE NOW CHECK TO SEE IF WE ARE IN A SINGLE DRIVE SYSTEM AND THE APPLICATION | ||
| 1083 | ; HAS "CLEVERLY" DIDDLED THE SDSB | ||
| 1084 | CMP CS:[SINGLE],2 ; IF (SINGLE_DRIVE_SYSTEM) | ||
| 1085 | JNE SHORT IGNORE_SDSB | ||
| 1086 | |||
| 1087 | SAVEREG <DS,DI,AX> ; THEN | ||
| 1088 | MOV AL,DS:[DI].DRIVELET ; IF (CURR_DRV == REQ_DRV) | ||
| 1089 | MOV AH,AL | ||
| 1090 | XOR DI,DI | ||
| 1091 | MOV DS,DI | ||
| 1092 | XCHG AL,DS:BYTE PTR LSTDRV ; THEN SWAP(CURR_DRV,REQ_DRV) | ||
| 1093 | CMP AH,AL ; ELSE | ||
| 1094 | RESTOREREG <AX,DI,DS> ; SWAP(CURR_DRV,REQ_DRV) | ||
| 1095 | JE SINGLERET ; ISSUE SWAP_DSK_MSG | ||
| 1096 | |||
| 1097 | IGNORE_SDSB: | ||
| 1098 | CALL SWPDSK ; ASK USER FOR CORRECT DISK | ||
| 1099 | SINGLERET: | ||
| 1100 | POP BX | ||
| 1101 | POP AX | ||
| 1102 | RET | ||
| 1103 | |||
| 1104 | SINGLE_ERR_RET: | ||
| 1105 | STC | ||
| 1106 | POP DI ; RESTORE CURRENT BDS | ||
| 1107 | POP DS | ||
| 1108 | JMP SHORT SINGLERET | ||
| 1109 | |||
| 1110 | BADDRIVE: | ||
| 1111 | MOV AL,8 ;Sector not found | ||
| 1112 | jmp short BadDrive_Ret ;AN004;AN005;AN006; | ||
| 1113 | UnformattedDrive: ;AN004;AN005;AN006; | ||
| 1114 | mov al,7 ;AN004;Unknown media;AN005;AN006; | ||
| 1115 | BadDrive_Ret: | ||
| 1116 | STC | ||
| 1117 | IORET: RET | ||
| 1118 | |||
| 1119 | BOGUSSETTLE: | ||
| 1120 | MOV AL,NORMSETTLE ; SOMEONE HAS DIDDLED THE SETTLE | ||
| 1121 | JMP GOTSLOWSETTLE | ||
| 1122 | CHECKSINGLE ENDP | ||
| 1123 | ;------------------------------------------------------------ | ||
| 1124 | ; | ||
| 1125 | ; DISK I/O HANDLER | ||
| 1126 | ; | ||
| 1127 | ; AL = DRIVE NUMBER (0-6) | ||
| 1128 | ; AH = MEDIA DESCRIPTOR | ||
| 1129 | ; CX = SECTOR COUNT | ||
| 1130 | ; DX = FIRST SECTOR (low) | ||
| 1131 | ; [Start_Sec_H] = FIRST SECTOR (high) ;J.K. 32 bit calculation. | ||
| 1132 | ; DS = CS | ||
| 1133 | ; ES:DI = TRANSFER ADDRESS | ||
| 1134 | ; [RFLAG]=OPERATION (2=READ, 3=WRITE) | ||
| 1135 | ; [VERIFY]=1 FOR VERIFY AFTER WRITE | ||
| 1136 | ; | ||
| 1137 | ; IF SUCCESSFUL CARRY FLAG = 0 | ||
| 1138 | ; ELSE CF=1 AND AL CONTAINS ERROR CODE | ||
| 1139 | ; | ||
| 1140 | PUBLIC DISKRD | ||
| 1141 | DISKRD PROC NEAR | ||
| 1142 | MOV CS:[RFLAG],ROMREAD | ||
| 1143 | |||
| 1144 | DISKIO: | ||
| 1145 | MOV BX,DI ; ES:BX = TRANSFER ADDRESS | ||
| 1146 | CALL SETDRIVE ; MAP LOGICAL AND PHYSICAL | ||
| 1147 | MOV AL,BYTE PTR DS:[DI].MEDIAD | ||
| 1148 | MOV CS:MEDBYT,AL ; PRESERVE MEDIA BYTE FOR DRIVE FOR USE | ||
| 1149 | ; IN DETERMINING MEDIA CHANGE. | ||
| 1150 | JCXZ IORET | ||
| 1151 | ;SB34DISK006****************************************************************** | ||
| 1152 | ;SB See if the Media is formatted or not by checking the flags field in | ||
| 1153 | ;SB in the BDS. If it is unformatted we cannot allow I/O, so we should | ||
| 1154 | ;SB go to the error exit at label UnformattedDrive. 2LOCS | ||
| 1155 | |||
| 1156 | test word ptr ds:[di].FLAGS, UNFORMATTED_MEDIA | ||
| 1157 | jnz UnformattedDrive | ||
| 1158 | ;SB34DISK006****************************************************************** | ||
| 1159 | mov cs:[SECCNT],CX ;save sector count | ||
| 1160 | MOV CS:[SPSAV],SP ; SAVE SP | ||
| 1161 | |||
| 1162 | ; ENSURE THAT WE ARE TRYING TO ACCESS VALID SECTORS ON THE DRIVE | ||
| 1163 | ; | ||
| 1164 | |||
| 1165 | mov ax,dx ;AN000; save DX to AX | ||
| 1166 | xor si,si ;AN000; | ||
| 1167 | add dx,cx ;AN000; | ||
| 1168 | adc si,0 ;AN000; | ||
| 1169 | cmp [di].DrvLim, 0 ;AN000; Is this drive > 32 bit sector ? | ||
| 1170 | je Sanity32 ;AN000; | ||
| 1171 | cmp si,0 ;AN000; | ||
| 1172 | jne BADDRIVE ;AN000; | ||
| 1173 | cmp dx, [di].DrvLim ;AN000; | ||
| 1174 | ja BADDRIVE ;AN000; | ||
| 1175 | jmp short SanityOK ;AN000; | ||
| 1176 | Sanity32: ;AN000; | ||
| 1177 | add si, cs:[Start_Sec_H] ;AN000; | ||
| 1178 | cmp si, [di].DrvLim_H ;AN000; | ||
| 1179 | jb SanityOK ;AN000; | ||
| 1180 | ja BADDRIVE ;AN000; | ||
| 1181 | cmp dx, [di].DrvLim_L ;AN000; | ||
| 1182 | ja BADDRIVE ;AN000; | ||
| 1183 | SanityOK: ;AN000; | ||
| 1184 | mov dx,cs:[Start_Sec_H] ;AN000; | ||
| 1185 | add ax,word ptr [di].HIDSEC_L ;AN000; | ||
| 1186 | adc dx,word ptr [di].Hidsec_H ;AN000; | ||
| 1187 | ;J.K. Now DX;AX have the physical first sector. | ||
| 1188 | ;Since the following procedures is going to destroy AX, let's | ||
| 1189 | ;save it temporarily to SAVED_WORD. | ||
| 1190 | mov cs:[Saved_Word], ax ;AN000; Save the sector number (low) | ||
| 1191 | |||
| 1192 | ; MOV SI,DX | ||
| 1193 | ; ADD SI,CX | ||
| 1194 | ; ADD DX,WORD PTR [DI].HIDSEC ; ADD IN THE HIDDEN SECTORS | ||
| 1195 | ; CMP SI,WORD PTR [DI].DRVLIM ; COMPARE AGAINST DRIVE MAX | ||
| 1196 | ; JA BADDRIVE | ||
| 1197 | |||
| 1198 | ; SET UP POINTER TO DISK BASE TABLE IN [DPT]. WE CANNOT ASSUME THAT IOSETUP | ||
| 1199 | ; WILL DO IT BECAUSE WE WILL SKIP THE SET UP STUFF WITH HARD DISKS. | ||
| 1200 | PUSH DS | ||
| 1201 | XOR AX,AX | ||
| 1202 | MOV DS,AX | ||
| 1203 | LDS SI,DWORD PTR DS:[DSKADR]; CURRENT DISK PARM TABLE | ||
| 1204 | MOV WORD PTR CS:DPT,SI | ||
| 1205 | MOV WORD PTR CS:DPT+2,DS | ||
| 1206 | POP DS | ||
| 1207 | TEST WORD PTR [DI].FLAGS,FNON_REMOVABLE | ||
| 1208 | JNZ SKIP_SETUP | ||
| 1209 | CALL CHECKSINGLE | ||
| 1210 | ; | ||
| 1211 | ; CHECK TO SEE IF WE HAVE PREVIOUSLY NOTED A CHANGE LINE. THE ROUTINE | ||
| 1212 | ; RETURNS IF EVERYTHING IS OK. OTHERWISE, IT POPS OFF THE STACK AND RETURNS | ||
| 1213 | ; THE PROPER ERROR CODE. | ||
| 1214 | ; | ||
| 1215 | ;----------------------------------------| | ||
| 1216 | ; WARNING: DO NOT CHANGE THE FOLLOWING. ;| | ||
| 1217 | ; IT GETS PATCHED IN MSINIT ;| | ||
| 1218 | PUBLIC DISKIO_PATCH ;| | ||
| 1219 | DISKIO_PATCH: ;| | ||
| 1220 | CALL CHECKLATCHIO ;| | ||
| 1221 | ;----------------------------------------| | ||
| 1222 | ; | ||
| 1223 | ; SET UP TABLES AND VARIABLES FOR I/O | ||
| 1224 | CALL IOSETUP | ||
| 1225 | ; | ||
| 1226 | ; NOW THE SETTLE VALUES ARE CORRECT FOR THE FOLLOWING CODE | ||
| 1227 | ; | ||
| 1228 | SKIP_SETUP: | ||
| 1229 | ;J.K. 32 bit sector calculation. | ||
| 1230 | ; DX;[Saved_Word] = starting sector number. | ||
| 1231 | mov ax,dx ;AN000; | ||
| 1232 | xor dx,dx ;AN000; | ||
| 1233 | DIV WORD PTR [DI].SECLIM ;DIVIDE BY SEC PER TRACK | ||
| 1234 | mov cs:[Temp_H],ax ;AN000; | ||
| 1235 | mov ax, cs:[Saved_Word] ;AN000; Restore the lower word | ||
| 1236 | div word ptr [di].SecLim ;AN000; | ||
| 1237 | ;Now, [Temp_H],AX = track #, DX = sector | ||
| 1238 | INC DL ;Sector number is 1 based. | ||
| 1239 | MOV CS:[CURSEC],DL ;SAVE CURRENT SECTOR | ||
| 1240 | MOV CX,WORD PTR [DI].HDLIM ;GET NUMBER OF HEADS | ||
| 1241 | |||
| 1242 | push ax ;AN000; | ||
| 1243 | XOR DX,DX ;DIVIDE TRACKS BY HEADS PER CYLINDER | ||
| 1244 | mov ax, cs:[Temp_H] ;AN000; | ||
| 1245 | DIV CX | ||
| 1246 | mov cs:[Temp_H],ax ;AN000; | ||
| 1247 | pop ax ;AN000; | ||
| 1248 | div cx ;AN000; | ||
| 1249 | ;Now, [Temp_H],AX = cyliner #, DX = head | ||
| 1250 | cmp cs:[Temp_H],0 ;AN000; | ||
| 1251 | ja BADDRIVE_brdg ;AN000; | ||
| 1252 | cmp AX, 1024 ;AN000; 2**10 currently maxium for track #. | ||
| 1253 | ja BADDRIVE_brdg ;AN000; | ||
| 1254 | MOV CS:[CURHD],DL ;SAVE CURRENT HEAD | ||
| 1255 | MOV CS:[CURTRK],AX ;SAVE CURRENT TRACK | ||
| 1256 | |||
| 1257 | ; | ||
| 1258 | ; WE ARE NOW SET UP FOR THE I/O. NORMALLY, WE CONSIDER THE DMA BOUNDARY | ||
| 1259 | ; VIOLATIONS HERE. NOT TRUE. WE PERFORM THE OPERATION AS IF EVERYTHING IS | ||
| 1260 | ; SYMMETRIC; LET THE INT 13 HANDLER WORRY ABOUT THE DMA VIOLATIONS. | ||
| 1261 | ; | ||
| 1262 | MOV AX, CS:[SECCNT] | ||
| 1263 | CALL BLOCK | ||
| 1264 | CALL DONE | ||
| 1265 | RET | ||
| 1266 | DISKRD ENDP | ||
| 1267 | |||
| 1268 | ; | ||
| 1269 | BADDRIVE_Brdg:jmp Baddrive | ||
| 1270 | ; | ||
| 1271 | |||
| 1272 | ; SET THE DRIVE-LAST-ACCESSED FLAG FOR DISKETTE ONLY. WE KNOW THAT THE HARD | ||
| 1273 | ; DISK WILL NOT BE REMOVED. | ||
| 1274 | ; DS:DI -> CURRENT BDS. | ||
| 1275 | ; AX,CX,SI ARE DESTROYED. | ||
| 1276 | ; | ||
| 1277 | PUBLIC IOSETUP | ||
| 1278 | IOSETUP PROC NEAR | ||
| 1279 | MOV AL,[DI].DRIVENUM | ||
| 1280 | MOV CS:[TIM_DRV],AL ; SAVE DRIVE LETTER | ||
| 1281 | ; | ||
| 1282 | ; DETERMINE PROPER HEAD SETTLE VALUES | ||
| 1283 | ; | ||
| 1284 | cmp cs:[Media_Set_For_Format], 0 ;AN012; | ||
| 1285 | jne Skip_DPT_Setting ;AN012; | ||
| 1286 | MOV CX,DS | ||
| 1287 | LDS SI,DWORD PTR CS:[DPT] ; GET POINTER TO DISK BASE TABLE | ||
| 1288 | MOV AL,CS:[EOT] | ||
| 1289 | MOV [SI].DISK_EOT,AL ; BUMP FOR US | ||
| 1290 | MOV AL,[SI].DISK_MOTOR_STRT ; PRESERVE OLD MOTOR START TIME | ||
| 1291 | MOV CS:MOTORSTARTUP,AL | ||
| 1292 | ; | ||
| 1293 | ; FOR 3.5" DRIVES, BOTH EXTERNAL AS WELL AS ON THE K09, WE NEED TO SET THE | ||
| 1294 | ; MOTOR START TIME TO 4. THIS CHECKING FOR EVERY I/O IS GOING TO AFFECT | ||
| 1295 | ; PERFORMANCE ACROSS THE BOARD, BUT IS NECESSARY!! - RS | ||
| 1296 | ; | ||
| 1297 | PUSH ES | ||
| 1298 | MOV ES,CX ; ES:DI -> TO CURRENT BDS | ||
| 1299 | CMP BYTE PTR ES:[DI].FORMFACTOR,FFSMALL | ||
| 1300 | JNZ MOTOR_START_OK | ||
| 1301 | MOV AL,4 | ||
| 1302 | XCHG AL,[SI].DISK_MOTOR_STRT | ||
| 1303 | MOTOR_START_OK: | ||
| 1304 | POP ES | ||
| 1305 | ; | ||
| 1306 | ; DS:SI NOW POINTS TO DISK PARAMETER TABLE. GET CURRENT SETTLE AND SET FAST | ||
| 1307 | ; SETTLE | ||
| 1308 | ; | ||
| 1309 | XOR AL,AL | ||
| 1310 | INC AL ; IBM WANTS FAST SETTLE TO BE 1 - RS. | ||
| 1311 | XCHG AL,[SI].DISK_HEAD_STTL ; GET SETTLE AND SET UP FOR FAST | ||
| 1312 | MOV CS:SETTLECURRENT,AL | ||
| 1313 | MOV AL,NORMSETTLE ; SOMEONE HAS DIDDLED THE SETTLE | ||
| 1314 | GOTSLOWSETTLE: | ||
| 1315 | MOV DS,CX | ||
| 1316 | MOV CS:SETTLESLOW,AL | ||
| 1317 | Skip_DPT_Setting: ;AN012; | ||
| 1318 | RET | ||
| 1319 | ; | ||
| 1320 | ; SET TIME OF LAST ACCESS, AND RESET DEFAULT VALUES IN THE DPT. | ||
| 1321 | ; | ||
| 1322 | DONE: | ||
| 1323 | TEST WORD PTR [DI].FLAGS,FNON_REMOVABLE | ||
| 1324 | JNZ RETZ ; DO NOT SET FOR NON-REMOVABLE MEDIA | ||
| 1325 | CALL SET_TIM ; SET TIME OF LAST ACCESS FOR DRIVE | ||
| 1326 | ; | ||
| 1327 | ; RESTORE HEAD SETTLE AND EOT VALUES | ||
| 1328 | ; | ||
| 1329 | DIDDLEBACK: | ||
| 1330 | pushf ;AN013;Save flag | ||
| 1331 | cmp cs:[Media_Set_For_Format], 0 ;AN012; | ||
| 1332 | jne NoDiddleBack ;AN012; | ||
| 1333 | PUSH AX | ||
| 1334 | MOV DX,DS | ||
| 1335 | MOV AL,CS:SETTLECURRENT | ||
| 1336 | MOV AH,CS:MOTORSTARTUP | ||
| 1337 | LDS SI,CS:DPT | ||
| 1338 | ; MOV [SI].DISK_EOT,9 ;J.K. 4/25/86. Should not change the EOT value | ||
| 1339 | ;of diskbase to 9. This cause a problem | ||
| 1340 | ;with 1.44M diskette in Polaris when the user | ||
| 1341 | ;issue INT 13 with the default system | ||
| 1342 | ;diskbase. | ||
| 1343 | mov [si].DISK_EOT,9 ;J.K. 11/5/86. For compatibility reason, return | ||
| 1344 | ;back to set it to 9 ( PTM826 ). | ||
| 1345 | MOV [SI].DISK_HEAD_STTL,AL | ||
| 1346 | MOV [SI].DISK_SECTOR_SIZ,2 | ||
| 1347 | MOV [SI].DISK_MOTOR_STRT,AH | ||
| 1348 | MOV DS,DX | ||
| 1349 | POP AX | ||
| 1350 | NoDiddleBack: ;AN013; | ||
| 1351 | popf ;AN013;Restore flag | ||
| 1352 | RETZ: | ||
| 1353 | RET | ||
| 1354 | |||
| 1355 | ;READ THE NUMBER OF SECTORS SPECIFIED IN AX, HANDLING TRACK BOUNDARIES | ||
| 1356 | ;DS:DI -> BDS FOR THIS DRIVE | ||
| 1357 | BLOCK: | ||
| 1358 | OR AX,AX ;SEE IF ANY SECTORS TO READ | ||
| 1359 | JZ RETZ | ||
| 1360 | ;Fixed disk will not be restricted to the track-by-track basis. -J.K.4/10/86 | ||
| 1361 | test word ptr [di].Flags, fNon_Removable ;J.K. Fixed disk? | ||
| 1362 | jz BLOCK_FLOPPY ;J.K. | ||
| 1363 | ;SB34DISK002***************************************************************** | ||
| 1364 | ;SB Check to see if multi track operation is allowed. If not | ||
| 1365 | ;SB we have to go to the block_floppy below to break up the operation. | ||
| 1366 | ;SB 2 LOCS | ||
| 1367 | test word ptr CS:MulTrk_Flag, MulTrk_ON | ||
| 1368 | jz BLOCK_FLOPPY | ||
| 1369 | ;SB34DISK002***************************************************************** | ||
| 1370 | call DISK ;J.K. | ||
| 1371 | xor ax,ax | ||
| 1372 | RET ;J.K. | ||
| 1373 | BLOCK_FLOPPY: ;J.K.4/10/86 | ||
| 1374 | ; | ||
| 1375 | ; READ AT MOST 1 TRACK WORTH. PERFORM MINIMIZATION AT SECTOR / TRACK | ||
| 1376 | ; | ||
| 1377 | MOV CL,BYTE PTR [DI].SECLIM | ||
| 1378 | INC CL | ||
| 1379 | SUB CL,CS:CURSEC ; LEEAC 3.20 ADD SEGMENT OVERRIDE | ||
| 1380 | XOR CH,CH | ||
| 1381 | CMP AX,CX | ||
| 1382 | JAE GOTMIN | ||
| 1383 | MOV CX,AX | ||
| 1384 | GOTMIN: | ||
| 1385 | ; | ||
| 1386 | ; AX IS THE REQUESTED NUMBER OF SECTORS TO READ | ||
| 1387 | ; CX IS THE NUMBER THAT WE CAN DO ON THIS TRACK | ||
| 1388 | ; | ||
| 1389 | PUSH AX | ||
| 1390 | PUSH CX | ||
| 1391 | MOV AX,CX ; AL IS NUMBER OF SECTORS TO READ | ||
| 1392 | CALL DISK | ||
| 1393 | POP CX | ||
| 1394 | POP AX | ||
| 1395 | ; | ||
| 1396 | ; CX IS THE NUMBER OF SECTORS JUST TRANSFERRED | ||
| 1397 | ; | ||
| 1398 | SUB AX,CX ; REDUCE SECTORS-REMAINING BY LAST I/O | ||
| 1399 | SHL CL,1 | ||
| 1400 | ADD BH,CL ; ADJUST TRANSFER ADDRESS | ||
| 1401 | JMP BLOCK | ||
| 1402 | IOSETUP ENDP | ||
| 1403 | |||
| 1404 | DskErr_Brdg: jmp DskErr ;AN003; | ||
| 1405 | |||
| 1406 | ; | ||
| 1407 | ;PERFORM DISK I/O WITH RETRIES | ||
| 1408 | ; AL = NUMBER OF SECTORS (1-8, ALL ON ONE TRACK) | ||
| 1409 | ; DI POINT TO DRIVE PARAMETERS | ||
| 1410 | ; ES:BX = TRANSFER ADDRESS (MUST NOT CROSS A 64K PHYSICAL BOUNDARY) | ||
| 1411 | ; [RFLAG] = 2 IF READ, 3 IF WRITE | ||
| 1412 | ; [VERIFY] = 0 FOR NORMAL, 1 FOR VERIFY AFTER WRITE | ||
| 1413 | |||
| 1414 | PUBLIC DISK | ||
| 1415 | DISK PROC NEAR | ||
| 1416 | MOV BP,MAXERR ; SET UP RETRY COUNT | ||
| 1417 | mov cs:VRetry_Cnt, BP ;AN003;Verify op. retry cnt for Write-Verify. | ||
| 1418 | mov cs:Soft_ECC_Cnt, BP ;AN003;Soft ECC error retry count. | ||
| 1419 | MOV AH,CS:RFLAG ;GET READ/WRITE INDICATOR | ||
| 1420 | |||
| 1421 | RETRY: | ||
| 1422 | PUSH AX | ||
| 1423 | |||
| 1424 | MOV DX,CS:[CURTRK] ;LOAD CURRENT CYLINDER | ||
| 1425 | |||
| 1426 | test word ptr [di].FLAGS, fNon_Removable ;Fixed disk? - J.K. 4/7/86 | ||
| 1427 | jz DISK_NOT_MINI ;no, skip this. - J.K. 4/7/86 | ||
| 1428 | cmp [di].IsMini, 1 ;Is this a mini disk? - J.K. 4/7/86 | ||
| 1429 | jnz DISK_NOT_MINI ;No. continue to next.- J.K. 4/7/86 | ||
| 1430 | add dx, [di].Hidden_Trks ;else add hidden trks.- J.K. 4/7/86 | ||
| 1431 | DISK_NOT_MINI: ;J.K. 4/7/86 | ||
| 1432 | ROR DH,1 | ||
| 1433 | ROR DH,1 | ||
| 1434 | |||
| 1435 | OR DH,CS:[CURSEC] | ||
| 1436 | MOV CX,DX | ||
| 1437 | XCHG CH,CL ; CL = SECTOR, CH = CYLINDER | ||
| 1438 | MOV DH,BYTE PTR CS:[CURHD] ; LOAD CURRENT HEAD NUMBER AND | ||
| 1439 | MOV DL,BYTE PTR [DI].DRIVENUM ; PHYSICAL DRIVE NUMBER | ||
| 1440 | CMP BYTE PTR [DI].FORMFACTOR,FFHARDFILE | ||
| 1441 | JZ DO_FAST ; HARD FILES USE FAST SPEED | ||
| 1442 | ; IF WE HAVE [STEP_DRV] SET TO -1, WE USE THE SLOW SETTLE TIME. | ||
| 1443 | ; THIS HELPS WHEN WE HAVE JUST DONE A RESED DISK OPERATION AND THE HEAD HAS | ||
| 1444 | ; BEEN MOVED TO ANOTHER CYLINDER - THE PROBLEM CROPS UP WITH 3.5" DRIVES. | ||
| 1445 | CMP CS:[STEP_DRV],-1 | ||
| 1446 | JZ DO_WRITEJ | ||
| 1447 | CMP AH,ROMREAD ; ARR 2.20 | ||
| 1448 | JE DO_FAST | ||
| 1449 | CMP AH, ROMVERIFY | ||
| 1450 | JE DO_FAST | ||
| 1451 | DO_WRITEJ: | ||
| 1452 | ; READS ALWAYS FAST, UNLESS WE HAVE JUST DONE A DISK RESET OPERATION | ||
| 1453 | JMP DO_WRITE ; ARR 2.20 READS ALWAYS FAST | ||
| 1454 | DO_FAST: ; ARR 2.20 | ||
| 1455 | CALL FASTSPEED ; MZ 2.21 CHANGE SETTLE MODE | ||
| 1456 | TESTERR: ; MZ 2.21 | ||
| 1457 | JC DSKERR_brdg | ||
| 1458 | ; SET DRIVE AND TRACK OF LAST ACCESS | ||
| 1459 | MOV CS:[STEP_DRV],DL ; ARR 2.20 SET DRIVE | ||
| 1460 | MOV BYTE PTR [DI].TRACK,CH ; ARR 2.20 SAVE TRACK | ||
| 1461 | NO_SET: | ||
| 1462 | CMP CS:WRTVERIFY,103H ; CHECK FOR WRITE AND VERIFY | ||
| 1463 | JZ DOVERIFY | ||
| 1464 | NOVERIFY: | ||
| 1465 | POP AX | ||
| 1466 | |||
| 1467 | ;SB34DISK003***************************************************************** | ||
| 1468 | ;SB Check the flags word in the BDS to see if the drive is non removable | ||
| 1469 | ;SB If not we needn't do anything special | ||
| 1470 | ;SB If it is a hard disk then check to see if multi-track operation | ||
| 1471 | ;SB is specified. If specified we don't have to calculate for the next | ||
| 1472 | ;SB track since we are already done. So we can go to the exit of this | ||
| 1473 | ;SB routine. 5 LOCS | ||
| 1474 | |||
| 1475 | test word ptr [di].FLAGS, fNON_REMOVABLE | ||
| 1476 | jz ITS_REMOVABLE | ||
| 1477 | test CS:MulTrk_Flag, MulTrk_ON | ||
| 1478 | jnz DISK_RET | ||
| 1479 | ITS_REMOVABLE: | ||
| 1480 | ;SB34DISK003***************************************************************** | ||
| 1481 | AND CL,03FH ; ELIMINATE CYLINDER BITS FROM SECTOR | ||
| 1482 | XOR AH,AH | ||
| 1483 | SUB CS:[SECCNT],AX ; REDUCE COUNT OF SECTORS TO GO | ||
| 1484 | ADD CL,AL ; NEXT SECTOR | ||
| 1485 | MOV CS:[CURSEC],CL | ||
| 1486 | CMP CL,BYTE PTR [DI].SECLIM ; SEE IF SECTOR/TRACK LIMIT REACHED | ||
| 1487 | JBE DISK_RET | ||
| 1488 | NEXTTRACK: | ||
| 1489 | MOV CS:[CURSEC],1 ; START WITH FIRST SECTOR OF NEXT TRACK | ||
| 1490 | MOV DH,CS:[CURHD] | ||
| 1491 | INC DH | ||
| 1492 | CMP DH,BYTE PTR [DI].HDLIM | ||
| 1493 | JB NOXOR | ||
| 1494 | XOR DH,DH | ||
| 1495 | INC CS:[CURTRK] ;NEXT TRACK | ||
| 1496 | NOXOR: | ||
| 1497 | MOV CS:[CURHD],DH | ||
| 1498 | DISK_RET: | ||
| 1499 | CLC ; LEEAC | ||
| 1500 | RET | ||
| 1501 | DISK ENDP | ||
| 1502 | |||
| 1503 | |||
| 1504 | ; THE REQUEST IS FOR WRITE. DETERMINE IF WE ARE TALKING ABOUT THE SAME | ||
| 1505 | ; TRACK AND DRIVE. IF SO, USE THE FAST SPEED. | ||
| 1506 | |||
| 1507 | DO_WRITE PROC NEAR | ||
| 1508 | CMP DL,CS:[STEP_DRV] ; ARR 2.20 | ||
| 1509 | JNZ DO_NORM ; WE HAVE CHANGED DRIVES | ||
| 1510 | |||
| 1511 | CMP CH,BYTE PTR [DI].TRACK ; ARR 2.20 | ||
| 1512 | JZ DO_FAST ; WE ARE STILL ON THE SAME TRACK | ||
| 1513 | |||
| 1514 | DO_NORM: | ||
| 1515 | CALL NORMSPEED | ||
| 1516 | JMP SHORT TESTERR ; MZ 2.21 TEST FOR ERROR | ||
| 1517 | DO_WRITE ENDP | ||
| 1518 | ; | ||
| 1519 | ; WE HAVE A VERIFY REQUEST ALSO. GET STATE INFO AND GO VERIFY | ||
| 1520 | ; | ||
| 1521 | |||
| 1522 | DOVERIFY PROC NEAR | ||
| 1523 | POP AX ; RESTORE SECTOR COUNT | ||
| 1524 | PUSH AX | ||
| 1525 | MOV AH,ROMVERIFY ; REQUEST VERIFY | ||
| 1526 | CALL FASTSPEED ; MZ 2.21 CHANGE SETTLE MODE | ||
| 1527 | JNC NOVERIFY | ||
| 1528 | |||
| 1529 | ;SB34DISK004************************************************************** | ||
| 1530 | ;SB check the error returned in AH to see if it is a SOFT ECC error. | ||
| 1531 | ;SB If it is not we needn't do anything special. If it is a SOFT | ||
| 1532 | ;SB ECC error then decrement the SOFT_ECC_CNT error retry count. If | ||
| 1533 | ;SB this retry count becomes 0 then we just ignore the error and go to | ||
| 1534 | ;SB No_verify but if we can still try then we call the routine to reset | ||
| 1535 | ;SB the disk and go to DSKerr1 to retry the operation. 6 LOCS | ||
| 1536 | |||
| 1537 | cmp ah,11h ;SOFT ECC error ? | ||
| 1538 | jnz Not_SoftECC_Err | ||
| 1539 | dec SOFT_ECC_CNT | ||
| 1540 | jz NoVerify ;no more retry | ||
| 1541 | call ResetDisk ;reset disk | ||
| 1542 | jmp DskErr1 ;retry | ||
| 1543 | |||
| 1544 | ;SB34DISK004************************************************************** | ||
| 1545 | |||
| 1546 | Not_SoftECC_Err: ;AN003;Other error. | ||
| 1547 | call ResetDisk ;AN003; | ||
| 1548 | dec VRetry_Cnt ;AN003; | ||
| 1549 | jmp DskErr0 ;AN003; | ||
| 1550 | DOVERIFY ENDP | ||
| 1551 | ; | ||
| 1552 | ; NEED TO SPECIAL CASE THE CHANGE-LINE ERROR AH=06H. IF WE GET THIS, WE | ||
| 1553 | ; NEED TO RETURN IT. | ||
| 1554 | ; | ||
| 1555 | ;----------------------------------------| | ||
| 1556 | ; WARNING: DO NOT CHANGE THE FOLLOWING. ;| | ||
| 1557 | ; IT GETS PATCHED IN MSINIT ;| | ||
| 1558 | PUBLIC DSKERR ;| | ||
| 1559 | DSKERR PROC NEAR ;| | ||
| 1560 | CALL CHECKIO ;| | ||
| 1561 | ;---------------------------------------;| | ||
| 1562 | |||
| 1563 | cmp cs:MultiTrk_Format_Flag, 1 ;AN007;Multi trk format request? | ||
| 1564 | jne DoChkAgain ;AN007; | ||
| 1565 | mov bp, 1 ;AN007;No more retry. | ||
| 1566 | mov cs:MultiTrk_Format_Flag, 0 ;AN007;Clear the flag. | ||
| 1567 | DoChkAgain: ;AN007; | ||
| 1568 | CALL AGAIN | ||
| 1569 | DskErr0: ;AN003; | ||
| 1570 | JZ HARDERR | ||
| 1571 | test word ptr [di].FLAGS, fNon_Removable ;AN009; | ||
| 1572 | jnz Skip_TimeOut_Chk ;AN009; | ||
| 1573 | CMP AH,80H ;TIMEOUT? | ||
| 1574 | JZ HARDERR ;*** | ||
| 1575 | Skip_TimeOut_Chk: ;AN009; | ||
| 1576 | cmp ah, 0cch ;AN003;Write Fault error? | ||
| 1577 | jz Write_Fault_Err ;AN003; Then, don't retry. | ||
| 1578 | mov cs:Soft_ECC_Cnt, MAXERR ;AN003;Set Soft_ECC_Cnt back to MAXERR | ||
| 1579 | DSKERR1: | ||
| 1580 | POP AX ;RESTORE SECTOR COUNT | ||
| 1581 | JMP RETRY | ||
| 1582 | |||
| 1583 | Write_Fault_Err: ;AN003; | ||
| 1584 | mov bp, 1 ;AN003;Just retry only once for Write Fault error. | ||
| 1585 | jmp DskErr1 ;AN003; | ||
| 1586 | |||
| 1587 | HARDERR: | ||
| 1588 | PUBLIC HARDERR | ||
| 1589 | |||
| 1590 | CALL MAPERROR | ||
| 1591 | |||
| 1592 | HARDERR2: ; FOR ROUTINES THAT CALL MAPERROR THEMSELVES | ||
| 1593 | PUBLIC HARDERR2 | ||
| 1594 | |||
| 1595 | MOV CS:[TIM_DRV],-1 ;FORCE A MEDIA CHECK THROUGH ROM | ||
| 1596 | MOV CX,CS:SECCNT ;GET COUNT OF SECTORS TO GO | ||
| 1597 | MOV SP,CS:[SPSAV] ;RECOVER ENTRY STACK POINTER | ||
| 1598 | ; | ||
| 1599 | ; SINCE WE ARE PERFORMING A NON-LOCAL GOTO, RESTORE THE DISK PARAMETERS | ||
| 1600 | ; | ||
| 1601 | MEDBYT_OK: | ||
| 1602 | CALL DIDDLEBACK | ||
| 1603 | RET ;AND RETURN | ||
| 1604 | DSKERR ENDP | ||
| 1605 | |||
| 1606 | ; | ||
| 1607 | ; CHANGE SETTLE VALUE FROM SETTLECURRENT TO WHATEVER IS APPROPRIATE | ||
| 1608 | ; NOTE THAT THIS ROUTINE IS NEVER CALLED FOR A FIXED DISK. | ||
| 1609 | ; | ||
| 1610 | NORMSPEED PROC NEAR | ||
| 1611 | cmp cs:[Media_Set_For_Format], 0 ;AN012; | ||
| 1612 | jne FASTSPEED ;AN012; | ||
| 1613 | PUSH DS | ||
| 1614 | PUSH AX | ||
| 1615 | MOV AL,CS:SETTLESLOW | ||
| 1616 | LDS SI,CS:DPT ; CURRENT DISK PARM TABLE | ||
| 1617 | MOV [SI].DISK_HEAD_STTL,AL | ||
| 1618 | POP AX | ||
| 1619 | POP DS | ||
| 1620 | CALL FASTSPEED | ||
| 1621 | PUSH DS | ||
| 1622 | LDS SI,CS:DPT | ||
| 1623 | MOV [SI].DISK_HEAD_STTL,1 ; 1 IS FAST SETTLE VALUE | ||
| 1624 | POP DS | ||
| 1625 | RET | ||
| 1626 | NORMSPEED ENDP | ||
| 1627 | |||
| 1628 | FASTSPEED PROC NEAR | ||
| 1629 | ; | ||
| 1630 | ; IF THE DRIVE HAS BEEN MARKED AS TOO BIG (I.E. STARTING SECTOR OF THE | ||
| 1631 | ; PARTITION IS > 16 BITS, THEN ALWAYS RETURN DRIVE NOT READY. | ||
| 1632 | ; | ||
| 1633 | TEST BYTE PTR [DI].FATSIZ,FTOOBIG | ||
| 1634 | IF iTEST | ||
| 1635 | JZ READY | ||
| 1636 | JMP NOTREADY | ||
| 1637 | READY: | ||
| 1638 | ELSE | ||
| 1639 | JNZ NOTREADY | ||
| 1640 | ENDIF | ||
| 1641 | |||
| 1642 | MESSAGE FTESTINIT,<"<"> | ||
| 1643 | MNUM FTESTINIT,AX | ||
| 1644 | MESSAGE FTESTINIT,<","> | ||
| 1645 | MNUM FTESTINIT,ES | ||
| 1646 | MESSAGE FTESTINIT,<":"> | ||
| 1647 | MNUM FTESTINIT | ||
| 1648 | MESSAGE FTESTINIT,<","> | ||
| 1649 | MNUM FTESTINIT,CX | ||
| 1650 | MESSAGE FTESTINIT,<","> | ||
| 1651 | MNUM FTESTINIT,DX | ||
| 1652 | MESSAGE FTESTINIT,<">"> | ||
| 1653 | INT 13H | ||
| 1654 | DEATH: | ||
| 1655 | RET | ||
| 1656 | NOTREADY: | ||
| 1657 | STC | ||
| 1658 | MOV AH,80H | ||
| 1659 | JMP DEATH | ||
| 1660 | FASTSPEED ENDP | ||
| 1661 | |||
| 1662 | ; MAP ERROR RETURNED BY ROM IN AH INTO CORRESPONDING CODE TO BE RETURNED TO | ||
| 1663 | ; DOS IN AL. | ||
| 1664 | ; | ||
| 1665 | MAPERROR PROC NEAR | ||
| 1666 | PUBLIC MAPERROR | ||
| 1667 | |||
| 1668 | PUSH CX ; SAVE CX | ||
| 1669 | PUSH CS | ||
| 1670 | POP ES ;MAKE ES THE LOCAL SEGMENT | ||
| 1671 | MOV AL,AH ;PUT ERROR CODE IN AL | ||
| 1672 | MOV CS:[LSTERR],AL ;TERMINATE LIST WITH ERROR CODE | ||
| 1673 | MOV CX,NUMERR ;NUMBER OF POSSIBLE ERROR CONDITIONS | ||
| 1674 | MOV DI,OFFSET ERRIN ;POINT TO ERROR CONDITIONS | ||
| 1675 | REPNE SCASB | ||
| 1676 | MOV AL,CS:[DI + NUMERR - 1] ;GET TRANSLATION | ||
| 1677 | POP CX ; RESTORE CX | ||
| 1678 | STC ;FLAG ERROR CONDITION | ||
| 1679 | RET | ||
| 1680 | MAPERROR ENDP | ||
| 1681 | |||
| 1682 | ; SET THE TIME OF LAST ACCESS FOR THIS DRIVE. THIS IS DONE ONLY FOR REMOVABLE | ||
| 1683 | ; MEDIA. | ||
| 1684 | |||
| 1685 | PUBLIC SET_TIM | ||
| 1686 | SET_TIM PROC NEAR | ||
| 1687 | PUSH AX | ||
| 1688 | ;SB33018****************************************************************** | ||
| 1689 | xor AH, AH ; set command to get time ;SB;3.30* | ||
| 1690 | int 1Ah ; call rom-bios timer function ;SB;3.30* | ||
| 1691 | ;SB33018****************************************************************** | ||
| 1692 | OR AL,AL | ||
| 1693 | JZ NOROLL3 | ||
| 1694 | INC CS:[DAYCNT] ; CATCH ROLLOVER | ||
| 1695 | NOROLL3: | ||
| 1696 | ; WE HAVE THE NEW TIME. IF WE SEE THAT THE TIME HAS PASSED, THEN WE RESET | ||
| 1697 | ; THE THRESHOLD COUNTER... | ||
| 1698 | CMP DX,WORD PTR [DI].TIM_LO | ||
| 1699 | JNZ SETACCESS | ||
| 1700 | CMP CX,WORD PTR [DI].TIM_HI | ||
| 1701 | JZ DONE_SET | ||
| 1702 | SETACCESS: | ||
| 1703 | MOV BYTE PTR CS:[ACCESSCOUNT],0 | ||
| 1704 | MOV WORD PTR [DI].TIM_LO,DX ;SAVE IT | ||
| 1705 | MOV WORD PTR [DI].TIM_HI,CX | ||
| 1706 | DONE_SET: | ||
| 1707 | CLC | ||
| 1708 | POP AX | ||
| 1709 | RET | ||
| 1710 | SET_TIM ENDP | ||
| 1711 | |||
| 1712 | ASSUME CS:CODE,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 1713 | |||
| 1714 | ; | ||
| 1715 | ; THIS IS THE TRUE INT 13 HANDLER. WE PARSE THE REQUEST TO SEE IF THERE IS | ||
| 1716 | ; A DMA VIOLATION. IF SO, DEPENDING ON THE FUNCTION, WE: | ||
| 1717 | ; READ/WRITE BREAK THE REQUEST INTO THREE PIECES AND MOVE THE MIDDLE ONE | ||
| 1718 | ; INTO OUR INTERNAL BUFFER. | ||
| 1719 | ; FORMAT COPY THE FORMAT TABLE INTO THE BUFFER | ||
| 1720 | ; VERIFY POINT THE TRANSFER ADDRESS INTO THE BUFFER | ||
| 1721 | ; | ||
| 1722 | ; THIS IS THE BIGGEST BOGOSITY OF ALL. THE IBM CONTROLLER DOES NOT HANDLE | ||
| 1723 | ; OPERATIONS THAT CROSS PHYSICAL 64K BOUNDARIES. IN THESE CASES, WE COPY | ||
| 1724 | ; THE OFFENDING SECTOR INTO THE BUFFER BELOW AND DO THE I/O FROM THERE. | ||
| 1725 | ; | ||
| 1726 | INT13FRAME STRUC | ||
| 1727 | OLDBP DW ? | ||
| 1728 | OLDAX DW ? | ||
| 1729 | OLDBX DW ? | ||
| 1730 | OLDCX DW ? | ||
| 1731 | OLDDX DW ? | ||
| 1732 | OLDDD DD ? | ||
| 1733 | OLDF DW ? | ||
| 1734 | INT13FRAME ENDS | ||
| 1735 | |||
| 1736 | ;J.K. 1/30/87 To handle the ps2_30 machine INT 13h, AH = 8 Problem. | ||
| 1737 | ;Save Registers here. | ||
| 1738 | Save_AX DW ? | ||
| 1739 | Save_BX DW ? | ||
| 1740 | Save_CX DW ? | ||
| 1741 | Save_DX DW ? | ||
| 1742 | Save_DI DW ? | ||
| 1743 | Save_SI DW ? | ||
| 1744 | Save_BP DW ? | ||
| 1745 | Save_DS DW ? | ||
| 1746 | Save_ES DW ? | ||
| 1747 | Prev_DX DW ? | ||
| 1748 | Save_Flag DW ? | ||
| 1749 | |||
| 1750 | |||
| 1751 | ; ENTRY CONDITIONS: | ||
| 1752 | ; AH = FUNCTION | ||
| 1753 | ; AL = NUMBER OF SECTORS | ||
| 1754 | ; ES:BX = DMA ADDRESS | ||
| 1755 | ; CX = PACKED TRACK AND SECTOR | ||
| 1756 | ; DX = HEAD AND DRIVE | ||
| 1757 | ; OUTPUT CONDITIONS: | ||
| 1758 | ; NO DMA VIOLATION. | ||
| 1759 | ; | ||
| 1760 | PUBLIC BLOCK13 | ||
| 1761 | BLOCK13 PROC FAR | ||
| 1762 | ; | ||
| 1763 | ; LET THE OPPERATION PROCEED. IF THERE IS A DMA VIOLATION, THEN WE DO THINGS. | ||
| 1764 | ; | ||
| 1765 | MOV CS:PREVOPER,AX ; SAVE REQUEST | ||
| 1766 | PUSHF | ||
| 1767 | CMP AH,ROMFORMAT | ||
| 1768 | JNZ NOT_FORMAT | ||
| 1769 | ; SET CHANGED BY FORMAT BIT FOR ALL LOGICAL DRIVES USING THIS PHYSICAL DRIVE | ||
| 1770 | ;---------------------------------------------------------| | ||
| 1771 | ; WARNING: DO NOT CHANGE THE FOLLOWING. | ||
| 1772 | ; IT GETS PATCHED IN AT INIT TIME | | ||
| 1773 | PUBLIC CHANGED_PATCH | ||
| 1774 | CHANGED_PATCH: | ||
| 1775 | MOV WORD PTR CS:[FLAGBITS],FCHANGED_BY_FORMAT+FCHANGED | ||
| 1776 | CALL SET_CHANGED_DL ; INDICATE THAT MEDIA CHANGED BY FORMAT | ||
| 1777 | ; | | ||
| 1778 | ;---------------------------------------------------------| | ||
| 1779 | NOT_FORMAT: | ||
| 1780 | test dl, 80h ; floppy or hard disk? | ||
| 1781 | jnz not_floppy ; if hard, skip this nonsense | ||
| 1782 | cmp cs:EC35_Flag, 0 ; any electrically compat. drives? | ||
| 1783 | jz not_floppy ; no; proceed unhindered | ||
| 1784 | SAVEREG <ax, bx, cx> | ||
| 1785 | mov cl, dl ; turn drive number into bit map: | ||
| 1786 | mov al, 1 ; assume drive 0 | ||
| 1787 | shl al, cl ; shift over correct number of times | ||
| 1788 | test al, cs:EC35_Flag ; is THIS drive an electrically compatible 3.5 incher? | ||
| 1789 | jz not_EC35 ; no; don't change anything | ||
| 1790 | mov bl, dl ; which drive was it? | ||
| 1791 | xor bh, bh ; need only one byte of index | ||
| 1792 | push es ; need a segment register | ||
| 1793 | mov ax, 40h ; the machine state byte is in the... | ||
| 1794 | mov es, ax ; ...segment at 40h | ||
| 1795 | mov byte ptr es:[90h+bx], 93H ; establish drive type as: (360k disk in 360k drive, no double-stepping, 250 kbs transfer rate) | ||
| 1796 | pop es ; fix up register again | ||
| 1797 | not_EC35: | ||
| 1798 | RESTOREREG <cx, bx, ax> | ||
| 1799 | not_floppy: | ||
| 1800 | cmp cs:[model_byte], mdl_ps2_30 ; is this a ps2/30? | ||
| 1801 | jne not_ps2_30 ; if not, just do normal call | ||
| 1802 | cmp ah, 8 ;J.K. 1/30/87 Read Driver Parm ? | ||
| 1803 | je ps2_30_Problem ;J.K. 1/30/87 | ||
| 1804 | cmp ah, 15h | ||
| 1805 | je ps2_30_Problem | ||
| 1806 | not_ps2_30: | ||
| 1807 | CALL ORIG13 ; SIMULATE INT 13 | ||
| 1808 | JC GOTERR13_br ; ERROR? | ||
| 1809 | RET 2 ; NO, RETURN AND CLEAR FLAGS | ||
| 1810 | |||
| 1811 | GOTERR13_br: jmp Goterr13 | ||
| 1812 | |||
| 1813 | ;J.K.1/30/87 ps2_30 machine has some problem with AH=8h(Read Drive Parm), Int 13h. | ||
| 1814 | ;This function does not reset the common buses after the execution. | ||
| 1815 | ;To solve this problem, when we detect AH=8h, then we will save the result and | ||
| 1816 | ;will issue AH=1 (Read Status) call to reset the buses. | ||
| 1817 | |||
| 1818 | ps2_30_Problem: ;J.K. 1/30/87; ps2_30 = PS2 Model 30. | ||
| 1819 | mov cs:Prev_DX, DX ;save orignal drive number | ||
| 1820 | call Orig13 ;Do "Read drive parm" | ||
| 1821 | |||
| 1822 | mov cs:Save_AX, AX ;Save registers,flag | ||
| 1823 | mov cs:Save_BX, BX | ||
| 1824 | mov cs:Save_CX, CX | ||
| 1825 | mov cs:Save_DX, DX | ||
| 1826 | mov cs:Save_DI, DI | ||
| 1827 | mov cs:Save_SI, SI | ||
| 1828 | mov cs:Save_BP, BP | ||
| 1829 | mov cs:Save_DS, DS | ||
| 1830 | mov cs:Save_ES, ES | ||
| 1831 | pushf | ||
| 1832 | pop cs:Save_Flag | ||
| 1833 | |||
| 1834 | mov dx, cs:Prev_DX ;restore orignal drive | ||
| 1835 | pushf | ||
| 1836 | mov ah, 1 ;Read Status. | ||
| 1837 | call Orig13 ;Reset the bus as a side effect of this call. | ||
| 1838 | |||
| 1839 | mov AX, cs:Save_AX ;restore registers,flag | ||
| 1840 | mov BX, cs:Save_BX | ||
| 1841 | mov CX, cs:Save_CX | ||
| 1842 | mov DX, cs:Save_DX | ||
| 1843 | mov DI, cs:Save_DI | ||
| 1844 | mov SI, cs:Save_SI | ||
| 1845 | mov BP, cs:Save_BP | ||
| 1846 | mov DS, cs:Save_DS | ||
| 1847 | mov ES, cs:Save_ES | ||
| 1848 | push cs:Save_Flag | ||
| 1849 | popf | ||
| 1850 | jc GotErr13 ;AH=8 had been an error? | ||
| 1851 | ret 2 | ||
| 1852 | |||
| 1853 | ; | ||
| 1854 | ; SOME KIND OF ERROR OCCURRED. SEE IF IT IS DMA VIOLATION | ||
| 1855 | ; | ||
| 1856 | GOTERR13: | ||
| 1857 | PUSHF | ||
| 1858 | cmp ah, 09h ;AN011; DMA error? | ||
| 1859 | je Chk_ValidMedia_ERR13 ;AN011; | ||
| 1860 | cmp ah, 11h ;AN011; ECC error? | ||
| 1861 | je Chk_ValidMedia_ERR13 ;AN011; | ||
| 1862 | jmp Skip_Ecc_Check ;AN011; Other error. Just return back. | ||
| 1863 | |||
| 1864 | Chk_ValidMedia_ERR13: ;AN011;If SetDrive fails, then just | ||
| 1865 | push ds ;AN011; return back to INT 13h caller, | ||
| 1866 | push di ;AN011; without performing ECC, DMA | ||
| 1867 | push ax ;AN011; error handling. | ||
| 1868 | mov byte ptr cs:[Phys_Drv], 1 ;AN011; | ||
| 1869 | mov al, dl ;AN011; | ||
| 1870 | call SetDrive ;AN011; | ||
| 1871 | mov byte ptr cs:[Phys_Drv], 0 ;AN011; | ||
| 1872 | pop ax ;AN011; | ||
| 1873 | pop di ;AN011; | ||
| 1874 | pop ds ;AN011; | ||
| 1875 | jc Skip_Ecc_Check ;AN011; | ||
| 1876 | |||
| 1877 | ; TEST OF BIT PATTERN 08H LET OTHER ERRORS BE PASSED AS DMA ERRORS - PTR 32D0519 | ||
| 1878 | ; TEST AH,08H ; DMA BIT | ||
| 1879 | CMP AH, 09H ; DMA ERROR CODE | ||
| 1880 | JNZ CHECK_ECC | ||
| 1881 | JMP GOTDMAERR | ||
| 1882 | CHECK_ECC: | ||
| 1883 | ;J.K. AN003; Soft ECC bug is only applied to PC1 and PC-XT. So, we will enforce | ||
| 1884 | ;this ECC error handler for them. Also, since CMC hardfiles in PC AT also | ||
| 1885 | ;generate a lot of unnecessary ECC errors, we will still cover PC ATs as | ||
| 1886 | ;it is done in the earlier version of MSBIO. | ||
| 1887 | ;During Format/Verify operation, we are going to consider any Soft Ecc as a | ||
| 1888 | ;hard error. | ||
| 1889 | |||
| 1890 | ;SB34DISK005***************************************************************** | ||
| 1891 | ;SB See if the machine we are operating on is a PC, XT or AT by checking | ||
| 1892 | ;SB the model byte. The soft ECC bug is only on these machines and if | ||
| 1893 | ;SB the machine we are operating on is not one of these three then we | ||
| 1894 | ;SB needn't do anything special. If we are operating one these however | ||
| 1895 | ;SB we check to see if the error occured during format by checking | ||
| 1896 | ;SB media_set_for_format. If it did occur during format we cannot do | ||
| 1897 | ;SB anything but if not during format then check to see if the error | ||
| 1898 | ;SB returned in AH is the SOFT_ECC error and if so go to OK11 since | ||
| 1899 | ;SB the error can be ignored. 6 LOCS | ||
| 1900 | |||
| 1901 | cmp cs:[Media_Set_For_Format], 1 ; formatting? | ||
| 1902 | je Skip_Ecc_Check | ||
| 1903 | cmp cs:[Model_Byte], 0FEh ; PC or XT? | ||
| 1904 | jae Go_Chk_Ecc | ||
| 1905 | cmp cs:[Model_Byte], 0FBh ; XT? | ||
| 1906 | je Go_Chk_Ecc | ||
| 1907 | cmp cs:[Model_Byte], 0FCh | ||
| 1908 | jne Skip_Ecc_Check | ||
| 1909 | cmp cs:[Secondary_Model_Byte], 2 ; AT? | ||
| 1910 | ja Skip_Ecc_Check | ||
| 1911 | Go_Chk_Ecc: ; for PC, XT, AT | ||
| 1912 | CMP AH,11H | ||
| 1913 | JZ OK11 | ||
| 1914 | Skip_Ecc_Check: ;AN003; Just return back to INT 13h caller. | ||
| 1915 | |||
| 1916 | ;SB34DISK005***************************************************************** | ||
| 1917 | |||
| 1918 | POPF | ||
| 1919 | RET 2 | ||
| 1920 | ; | ||
| 1921 | ; WE HAVE AN ERROR STATUS 11H. THIS INDICATES AN ECC-CORRECTED ERROR. NOTE | ||
| 1922 | ; THAT THIS INDICATES THAT THE DATA IS PROBABLY CORRECT BUT NOT CERTAINLY | ||
| 1923 | ; CORRECT. THE ROMS ON PC-1S AND PC_XTS HAVE A 'BUG' IN THAT IF AN ECC ERROR | ||
| 1924 | ; OCCURS FOR A MULTI-SECTOR READ, ONLY THE SECTORS UP TO THE ONE WHERE THE | ||
| 1925 | ; ERROR OCCURRED ARE READ IN. WE HAVE NO WAY OF KNOWING HOW MANY WERE READ IN | ||
| 1926 | ; THIS CASE, SO WE REDO THE OPERATION, READING ONE SECTOR AT A TIME. IF WE | ||
| 1927 | ; GET AN ECC ERROR ON READING ONE SECTOR, WE IGNORE THE ERROR BECAUSE THE | ||
| 1928 | ; SECTOR HAS BEEN READ IN. | ||
| 1929 | ; | ||
| 1930 | PUBLIC OK11 | ||
| 1931 | OK11: | ||
| 1932 | ; POPF | ||
| 1933 | ;J.K. 8/29/86 Here, it is better reset the system. So, we are going to | ||
| 1934 | ;call Orig13 again | ||
| 1935 | |||
| 1936 | xor ah, ah | ||
| 1937 | call Orig13 ;reset. Don't care about the result | ||
| 1938 | |||
| 1939 | MOV AX,CS:[PREVOPER] ; RETRIEVE REQUEST | ||
| 1940 | ; | ||
| 1941 | ; THIS WILL PROVIDE A TERMINATION POINT. | ||
| 1942 | ; | ||
| 1943 | CMP AL,1 ; IF REQUEST FOR ONE SECTOR, ASSUME OK | ||
| 1944 | JNZ ECC_ERR_HANDLE | ||
| 1945 | XOR AH,AH ; CLEAR CARRY TOO! | ||
| 1946 | RET 2 | ||
| 1947 | |||
| 1948 | PUBLIC ECC_ERR_HANDLE | ||
| 1949 | ECC_ERR_HANDLE: | ||
| 1950 | SAVEREG <BX,CX,DX> | ||
| 1951 | MOV CS:[NUMBER_OF_SEC],AL | ||
| 1952 | LOOP_ECC: | ||
| 1953 | MOV AX,CS:[PREVOPER] | ||
| 1954 | MOV AL,1 ; REQUEST FOR ONE SECTOR ONLY | ||
| 1955 | ; | ||
| 1956 | ; WE DO READS ONE SECTOR AT A TIME. THIS ENSURES THAT WE WILL EVENTUALLY | ||
| 1957 | ; FINISH THE REQUEST SINCE ECC ERRORS ON ONE SECTOR DO READ IN THAT SECTOR. | ||
| 1958 | ; | ||
| 1959 | ; WE NEED TO PUT IN SOME "INTELLIGENCE" INTO THE ECC HANDLER TO HANDLE READS | ||
| 1960 | ; THAT ATTEMPT TO READ MORE SECTORS THAN ARE AVAILABLE ON A PARTICULAR | ||
| 1961 | ; TRACK. | ||
| 1962 | ; WE CALL CHECK_WRAP TO SET UP THE SECTOR #, HEAD # AND CYLINDER # FOR | ||
| 1963 | ; THIS REQUEST. | ||
| 1964 | ; AT THIS POINT, ALL REGISTERS ARE SET UP FOR THE CALL TO ORIG13, EXCEPT | ||
| 1965 | ; THAT THERE MAY BE A STARTING SECTOR NUMBER THAT IS BIGGER THAN THE NUMBER | ||
| 1966 | ; OF SECTORS ON A TRACK. | ||
| 1967 | ; | ||
| 1968 | CALL CHECK_WRAP ; GET CORRECT PARAMETERS FOR INT 13 | ||
| 1969 | PUSHF | ||
| 1970 | CALL ORIG13 | ||
| 1971 | JNC OK11_OP | ||
| 1972 | CMP AH,11H ; ONLY ALLOW ECC ERRORS | ||
| 1973 | JNZ OK11_EXIT_err ;J.K. 8/26/86 Other error? | ||
| 1974 | mov ah, 0 ;J.K. ECC error. Reset the system again. | ||
| 1975 | pushf | ||
| 1976 | call Orig13 | ||
| 1977 | xor ax, ax ; clear the error code so that if this | ||
| 1978 | ; was the last sector, no error code | ||
| 1979 | ; will be returned for the corrected | ||
| 1980 | ; read. (clear carry too.) | ||
| 1981 | OK11_OP: | ||
| 1982 | DEC CS:[NUMBER_OF_SEC] | ||
| 1983 | JZ OK11_EXIT ; ALL DONE? | ||
| 1984 | INC CL ; ADVANCE SECTOR NUMBER | ||
| 1985 | INC BH ; ADD 200H TO ADDRESS | ||
| 1986 | INC BH | ||
| 1987 | JMP SHORT LOOP_ECC | ||
| 1988 | OK11_EXIT_err: | ||
| 1989 | stc ;J.K. 8/28/86 Set carry bit again. | ||
| 1990 | OK11_EXIT: | ||
| 1991 | RESTOREREG <DX,CX,BX> | ||
| 1992 | RET 2 | ||
| 1993 | ; | ||
| 1994 | ; WE TRULY HAVE A DMA VIOLATION. RESTORE REGISTER AX AND RETRY THE | ||
| 1995 | ; OPERATION AS BEST WE CAN. | ||
| 1996 | ; | ||
| 1997 | GOTDMAERR: | ||
| 1998 | POP AX ; CLEAN UP STACK | ||
| 1999 | MOV AX,CS:PREVOPER | ||
| 2000 | STI | ||
| 2001 | CMP AH,ROMREAD ; SAVE USER FLAGS | ||
| 2002 | JB INTDONE | ||
| 2003 | CMP AH,ROMVERIFY | ||
| 2004 | JZ INTVERIFY | ||
| 2005 | CMP AH,ROMFORMAT | ||
| 2006 | JZ INTFORMAT | ||
| 2007 | JA INTDONE | ||
| 2008 | ; | ||
| 2009 | ; WE ARE DOING A READ/WRITE CALL. CHECK FOR DMA PROBLEMS | ||
| 2010 | ; | ||
| 2011 | SAVEREG <DX,CX,BX,AX> | ||
| 2012 | PUSH BP | ||
| 2013 | MOV BP,SP | ||
| 2014 | MOV DX,ES ; CHECK FOR 64K BOUNDARY ERROR | ||
| 2015 | |||
| 2016 | SHL DX,1 | ||
| 2017 | SHL DX,1 | ||
| 2018 | SHL DX,1 | ||
| 2019 | SHL DX,1 ; SEGMENT CONVERTED TO ABSOLUTE ADDRESS | ||
| 2020 | |||
| 2021 | ADD DX,BX ; COMBINE WITH OFFSET | ||
| 2022 | ADD DX,511 ; SIMULATE A TRANSFER | ||
| 2023 | ; | ||
| 2024 | ; IF CARRY IS SET, THEN WE ARE WITHIN 512 BYTES OF THE END OF THE SEGMENT. | ||
| 2025 | ; WE SKIP THE FIRST TRANSFER AND PERFORM THE REMAINING BUFFERING AND TRANSFER | ||
| 2026 | ; | ||
| 2027 | JNC NO_SKIP_FIRST | ||
| 2028 | MOV DH,BYTE PTR [BP.OLDDX+1] ; SET UP HEAD NUMBER | ||
| 2029 | JMP BUFFER ;J.K. 4/10/86 | ||
| 2030 | ; JMP SHORT BUFFER | ||
| 2031 | ; | ||
| 2032 | ; DX IS THE PHYSICAL 16 BITS OF START OF TRANSFER. COMPUTE REMAINING | ||
| 2033 | ; SECTORS IN SEGMENT. | ||
| 2034 | ; | ||
| 2035 | NO_SKIP_FIRST: | ||
| 2036 | SHR DH,1 ; DH = NUMBER OF SECTORS BEFORE ADDRESS | ||
| 2037 | MOV AH,128 ; AH = MAX NUMBER OF SECTORS IN SEGMENT | ||
| 2038 | SUB AH,DH | ||
| 2039 | ; | ||
| 2040 | ; AH IS NOW THE NUMBER OF SECTORS THAT WE CAN SUCCESSFULLY WRITE IN THIS | ||
| 2041 | ; SEGMENT. IF THIS NUMBER IS ABOVE OR EQUAL TO THE REQUESTED NUMBER, THEN WE | ||
| 2042 | ; CONTINUE THE OPERATION AS NORMAL. OTHERWISE, WE BREAK IT INTO PIECES. | ||
| 2043 | ; | ||
| 2044 | CMP AH,AL ; CAN WE FIT IT IN? | ||
| 2045 | JB DOBLOCK ; NO, PERFORM BLOCKING. | ||
| 2046 | ; | ||
| 2047 | ; YES, THE REQUEST FITS. LET IT HAPPEN | ||
| 2048 | ; | ||
| 2049 | MOV DH,BYTE PTR [BP.OLDDX+1] ; SET UP HEAD NUMBER | ||
| 2050 | CALL DOINT | ||
| 2051 | JMP BAD13 | ||
| 2052 | ; | ||
| 2053 | ; VERIFY THE GIVEN SECTORS. PLACE THE BUFFER POINTER INTO OUR SPACE. | ||
| 2054 | ; | ||
| 2055 | INTVERIFY: | ||
| 2056 | SAVEREG <ES,BX> | ||
| 2057 | PUSH CS | ||
| 2058 | POP ES | ||
| 2059 | DOSIMPLE: | ||
| 2060 | MOV BX,OFFSET DISKSECTOR | ||
| 2061 | PUSHF | ||
| 2062 | CALL ORIG13 | ||
| 2063 | RESTOREREG <BX,ES> | ||
| 2064 | RET 2 | ||
| 2065 | |||
| 2066 | ; | ||
| 2067 | ; FORMAT OPERATION. COPY THE PARAMETER TABLE INTO MEMORY | ||
| 2068 | ; | ||
| 2069 | INTFORMAT: | ||
| 2070 | SAVEREG <ES,BX> | ||
| 2071 | SAVEREG <SI,DI,DS> | ||
| 2072 | PUSH ES | ||
| 2073 | PUSH CS | ||
| 2074 | POP ES | ||
| 2075 | POP DS | ||
| 2076 | MOV SI,BX | ||
| 2077 | MOV DI,OFFSET DISKSECTOR | ||
| 2078 | CALL MOVE | ||
| 2079 | RESTOREREG <DS,DI,SI> | ||
| 2080 | JMP DOSIMPLE | ||
| 2081 | ; | ||
| 2082 | ; INLINE CONTINUATION OF OPERATION | ||
| 2083 | ; | ||
| 2084 | INTDONE: | ||
| 2085 | JMP ORIG13 | ||
| 2086 | |||
| 2087 | ; | ||
| 2088 | ; We can't fit the request into the entire block. Perform the operation on | ||
| 2089 | ; the first block. | ||
| 2090 | ; | ||
| 2091 | ; DoBlock is modified to correctly handle multi-sector disk I/O. -J.K. 4/10/86 | ||
| 2092 | ; Old DoBlock had added the number of sectors I/Oed (Ah in Old DoBlock) after | ||
| 2093 | ; the DoInt call to CL. Observing only the lower 6 bits of CL(=max. 64) can | ||
| 2094 | ; represent a starting sector, if AH was big, then CL would be clobbered. | ||
| 2095 | ; By the way, we still are going to use CL for this purpose since Checkwrap | ||
| 2096 | ; routine will use it as an input. To prevent CL from being clobbered, a | ||
| 2097 | ; safe number of sectors should be calculated like "63 - # of sectors/track". | ||
| 2098 | ; DoBlock will handle the first block of requested sectors within the | ||
| 2099 | ; boundary of this safe value. - J.K. 2/28/86 | ||
| 2100 | |||
| 2101 | DoBlock: | ||
| 2102 | ;Try to get the # of sectors/track from BDS via Rom drive number. | ||
| 2103 | ;For any mini disks installed, here we have to pray that they have the | ||
| 2104 | ;same # of sector/track as the main DOS partition disk drive. | ||
| 2105 | |||
| 2106 | Message ftestDisk,<"!!!DMA DoBlock!!!"> | ||
| 2107 | |||
| 2108 | mov dx, word ptr [bp.olddx] ;set head # | ||
| 2109 | push di | ||
| 2110 | push ds | ||
| 2111 | push ax ;AH - # of sectors before DMA boundary | ||
| 2112 | ;AL - User requeseted # of sectors for I/O. | ||
| 2113 | mov byte ptr CS:[phys_drv],1 | ||
| 2114 | mov al, dl | ||
| 2115 | call SetDrive ;get BDS pointer for this DISK. | ||
| 2116 | pop ax | ||
| 2117 | mov byte ptr CS:[phys_drv],0 | ||
| 2118 | test word ptr [DI].Flags, fNon_Removable ;don't have to worry | ||
| 2119 | jnz DoBlockHard ;about floppies. They are track by track operation. | ||
| 2120 | mov al, ah ;set al = ah for floppies | ||
| 2121 | jmp short DoBlockCont | ||
| 2122 | DoBlockHard: | ||
| 2123 | push cx | ||
| 2124 | xor cx, cx | ||
| 2125 | mov cx, [DI].SecLim ;# of sectors/track | ||
| 2126 | mov ch, 63 | ||
| 2127 | sub ch, cl | ||
| 2128 | mov al, ch | ||
| 2129 | xchg ah, al ;now ah - safe # of sectors | ||
| 2130 | ;al - # of sectors before DMA boundary | ||
| 2131 | pop cx | ||
| 2132 | DoBlockCont: | ||
| 2133 | pop ds | ||
| 2134 | pop di | ||
| 2135 | DoBlockContinue: | ||
| 2136 | Message ftestDisk,<"%%DMA DoBlock Loop%%"> | ||
| 2137 | cmp ah, al ;if safe_# >= #_of_sectors_to_go_before DMA, | ||
| 2138 | jae DoBlocklast ;then #_of_sectors_to_go as it is for DoInt. | ||
| 2139 | push ax ;save AH, AL | ||
| 2140 | mov al, ah ;Otherwise, set al to ah to operate. | ||
| 2141 | jmp short DoBlockDoInt ;DoInt will set AH to a proper function in [BP.Oldax] | ||
| 2142 | DoBlocklast: | ||
| 2143 | mov ah, al | ||
| 2144 | push ax ;save AH | ||
| 2145 | DoBlockDoInt: ;let AH = AL = # of sectors for this shot | ||
| 2146 | CALL DoInt | ||
| 2147 | JC BAD13 ;something happened, bye! | ||
| 2148 | pop ax | ||
| 2149 | SUB BYTE PTR [BP.oldax], AH ;decrement by the successful operation | ||
| 2150 | ADD CL,AH ;advance sector number. Safety gauranteed. | ||
| 2151 | ADD BH,AH ;advance DMA address | ||
| 2152 | ADD BH,AH ;twice for 512 byte sectors. | ||
| 2153 | cmp ah, al ;check the previous value | ||
| 2154 | je Buffer ;if #_of_sectors_to_go < safe_#, then we are done already. | ||
| 2155 | sub al, ah ;otherwise, #_sector_to_go = #_of_sector_to_go - safe_# | ||
| 2156 | call Check_Wrap ;get new CX, DH for the next operation. | ||
| 2157 | jmp short DoBlockContinue ;handles next sectors left. | ||
| 2158 | ;End of modificaion of DoBlock - J.K. 2/28/86 | ||
| 2159 | ;The following is the original one. | ||
| 2160 | ; PUSH AX | ||
| 2161 | ; MOV AL,AH ; get max to operate on | ||
| 2162 | ; MOV AH,BYTE PTR [BP.oldax+1]; get function | ||
| 2163 | ; mov dh,byte ptr [BP.olddx+1] ; set up head number | ||
| 2164 | ; CALL DoInt | ||
| 2165 | ; JC Bad13 ; something happened, bye! | ||
| 2166 | ; POP AX | ||
| 2167 | ; SUB BYTE PTR [BP.oldax],AH ; decrement by the successful operation | ||
| 2168 | ; ADD CL,AH ; advance sector number | ||
| 2169 | ; ADD BH,AH ; advance DMA address | ||
| 2170 | ; ADD BH,AH ; twice for 512 byte sectors. | ||
| 2171 | |||
| 2172 | ; | ||
| 2173 | ; THE NEXT REQUEST WILL WRAP THE 64K BOUNDARY. IF WE ARE WRITING, THEN COPY | ||
| 2174 | ; THE OFFENDING SECTOR INTO OUR SPACE. | ||
| 2175 | ; | ||
| 2176 | ; ES:BX POINTS TO THE SECTOR | ||
| 2177 | ; CX,DX CONTAIN THE CORRECT TRACK/SECTOR/HEAD/DRIVE INFO | ||
| 2178 | ; [BP.OLDAX] HAS CORRECT FUNCTION CODE | ||
| 2179 | ; | ||
| 2180 | BUFFER: | ||
| 2181 | PUSH BX | ||
| 2182 | MOV AH,BYTE PTR [BP.OLDAX+1] | ||
| 2183 | CMP AH,ROMWRITE | ||
| 2184 | JNZ DOREAD | ||
| 2185 | ; | ||
| 2186 | ; COPY THE OFFENDING SECTOR INTO LOCAL BUFFER | ||
| 2187 | ; | ||
| 2188 | SAVEREG <DS,ES,SI,DI> | ||
| 2189 | PUSH CS ; EXCHANGE SEGMENT REGISTERS | ||
| 2190 | PUSH ES | ||
| 2191 | POP DS | ||
| 2192 | POP ES | ||
| 2193 | MOV DI,OFFSET DISKSECTOR ; WHERE TO MOVE | ||
| 2194 | PUSH DI ; SAVE IT | ||
| 2195 | MOV SI,BX ; SOURCE | ||
| 2196 | CALL MOVE | ||
| 2197 | POP BX ; NEW TRANSFER ADDRESS | ||
| 2198 | RESTOREREG <DI,SI> | ||
| 2199 | MOV AL,1 | ||
| 2200 | ; SEE IF WE ARE WRAPPING AROUND A TRACK OR HEAD | ||
| 2201 | MOV DL,BYTE PTR [BP.OLDDX] ; GET DRIVE NUMBER | ||
| 2202 | CALL CHECK_WRAP ; SETS UP REGISTERS IF WRAP-AROUND | ||
| 2203 | ; | ||
| 2204 | ; AH IS FUNCTION | ||
| 2205 | ; AL IS 1 FOR SINGLE SECTOR TRANSFER | ||
| 2206 | ; ES:BX IS LOCAL TRANSFER ADDRES | ||
| 2207 | ; CX IS TRACK/SECTOR NUMBER | ||
| 2208 | ; DX IS HEAD/DRIVE NUMBER | ||
| 2209 | ; SI,DI UNCHANGED | ||
| 2210 | ; | ||
| 2211 | CALL DOINT | ||
| 2212 | RESTOREREG <ES,DS> | ||
| 2213 | JC BAD13 ; GO CLEAN UP | ||
| 2214 | JMP SHORT DOTAIL | ||
| 2215 | ; | ||
| 2216 | ; READING A SECTOR. DO INT FIRST, THEN MOVE THINGS AROUND | ||
| 2217 | ; | ||
| 2218 | DOREAD: | ||
| 2219 | SAVEREG <ES,BX> | ||
| 2220 | PUSH CS | ||
| 2221 | POP ES | ||
| 2222 | MOV BX,OFFSET DISKSECTOR | ||
| 2223 | MOV AL,1 | ||
| 2224 | ; SEE IF OUR REQUEST WILL WRAP A TRACK OR HEAD BOUNDARY | ||
| 2225 | MOV DL,BYTE PTR [BP.OLDDX] ; GET DRIVE NUMBER | ||
| 2226 | CALL CHECK_WRAP ; SETS UP REGISTERS IF WRAP-AROUND | ||
| 2227 | ; | ||
| 2228 | ; AH = FUNCTION | ||
| 2229 | ; AL = 1 FOR SINGLE SECTOR | ||
| 2230 | ; ES:BX POINTS TO LOCAL BUFFER | ||
| 2231 | ; CX, DX ARE TRACK/SECTOR, HEAD/DRIVE | ||
| 2232 | ; | ||
| 2233 | CALL DOINT | ||
| 2234 | RESTOREREG <BX,ES> | ||
| 2235 | JC BAD13 ; ERROR => CLEAN UP | ||
| 2236 | SAVEREG <DS,SI,DI> | ||
| 2237 | PUSH CS | ||
| 2238 | POP DS | ||
| 2239 | MOV DI,BX | ||
| 2240 | MOV SI,OFFSET DISKSECTOR | ||
| 2241 | CALL MOVE | ||
| 2242 | RESTOREREG <DI,SI,DS> | ||
| 2243 | ; | ||
| 2244 | ; NOTE THE FACT THAT WE'VE DONE 1 MORE SECTOR | ||
| 2245 | ; | ||
| 2246 | DOTAIL: | ||
| 2247 | POP BX ; RETRIEVE NEW DMA AREA | ||
| 2248 | ADD BH,2 ; ADVANCE OVER SECTOR | ||
| 2249 | INC CX | ||
| 2250 | MOV AL,BYTE PTR [BP.OLDAX] | ||
| 2251 | CLC | ||
| 2252 | DEC AL | ||
| 2253 | JZ BAD13 ; NO MORE I/O | ||
| 2254 | ; SEE IF WE WRAP AROUND A TRACK OR HEAD BOUNDARY WITH STARTING SECTOR | ||
| 2255 | ; WE ALREADY HAVE THE CORRECT HEAD NUMBER TO PASS TO CHECK_WRAP | ||
| 2256 | MOV DL,BYTE PTR [BP.OLDDX] ; GET DRIVE NUMBER | ||
| 2257 | CALL CHECK_WRAP ; SETS UP REGISTERS IF WRAP-AROUND | ||
| 2258 | CALL DOINT | ||
| 2259 | ; | ||
| 2260 | ; WE ARE DONE. AX HAS THE FINAL CODE; WE THROW AWAY WHAT WE GOT BEFORE | ||
| 2261 | ; | ||
| 2262 | BAD13: | ||
| 2263 | MOV SP,BP | ||
| 2264 | RESTOREREG <BP,BX,BX,CX,DX> | ||
| 2265 | RET 2 | ||
| 2266 | BLOCK13 ENDP | ||
| 2267 | PAGE | ||
| 2268 | INCLUDE MSIOCTL.INC | ||
| 2269 | PAGE | ||
| 2270 | ; CHECK_WRAP IS A ROUTINE THAT ADJUSTS THE STARTING SECTOR, STARTING HEAD | ||
| 2271 | ; AND STARTING CYLINDER FOR AN INT 13 REQUEST THAT REQUESTS I/O OF A LOT | ||
| 2272 | ; OF SECTORS. IT ONLY DOES THIS FOR FIXED DISKS. IT IS USED IN THE SECTIONS | ||
| 2273 | ; OF CODE THAT HANDLE ECC ERRORS AND DMA ERRORS. IT IS NECESSARY, BECAUSE | ||
| 2274 | ; ORDINARILY THE ROM WOULD TAKE CARE OF WRAPS AROUND HEADS AND CYLINDERS, | ||
| 2275 | ; BUT WE BREAK DOWN A REQUEST WHEN WE GET AN ECC OR DMA ERROR INTO SEVERAL | ||
| 2276 | ; I/O OF ONE OR MORE SECTORS. IN THIS CASE, WE MAY ALREADY BE BEYOND THE | ||
| 2277 | ; NUMBER OF SECTORS ON A TRACK ON THE MEDIUM, AND THE REQUEST WOULD FAIL. | ||
| 2278 | ; | ||
| 2279 | ; INPUT CONDITIONS: | ||
| 2280 | ; ALL REGISTERS SET UP FOR AN INT 13 REQUEST. | ||
| 2281 | ; | ||
| 2282 | ; OUTPUT: | ||
| 2283 | ; DH - CONTAINS STARTING HEAD NUMBER FOR REQUEST | ||
| 2284 | ; CX - CONTAINS STARTING SECTOR AND CYLINDER NUMBERS | ||
| 2285 | ; (THE ABOVE MAY OR MAY NOT HAVE BEEN CHANGED, AND ARE 0-BASED) | ||
| 2286 | ; ALL OTHER REGISTERS PRESERVED. | ||
| 2287 | ; | ||
| 2288 | PUBLIC CHECK_WRAP | ||
| 2289 | CHECK_WRAP: | ||
| 2290 | Message ftestDisk,<"Entering Check_Wrap...",cr,lf> | ||
| 2291 | SAVEREG <AX,BX,DS,DI> | ||
| 2292 | MOV BYTE PTR CS:[PHYS_DRV],1; USE PHYSICAL DRIVE IN AL TO GET BDS | ||
| 2293 | MOV AL,DL ; AL HAS PHYSICAL DRIVE NUMBER | ||
| 2294 | CALL SETDRIVE ; GET POINTER TO BDS FOR DRIVE | ||
| 2295 | MOV BYTE PTR CS:[PHYS_DRV],0; RESTORE FLAG TO USE LOGICAL DRIVE | ||
| 2296 | JC NO_WRAP ; DO NOTHING IF WRONG PHYSICAL DRIVE | ||
| 2297 | TEST WORD PTR [DI].FLAGS,FNON_REMOVABLE | ||
| 2298 | JZ NO_WRAP ; NO WRAPPING FOR REMOVABLE MEDIA | ||
| 2299 | MOV BX,[DI].SECLIM | ||
| 2300 | MOV AX,CX | ||
| 2301 | AND AX,003FH ; EXTRACT SECTOR NUMBER | ||
| 2302 | CMP AX,BX ; ARE WE GOING TO WRAP? | ||
| 2303 | JBE NO_WRAP | ||
| 2304 | DIV BL ; AH=NEW SECTOR #, AL=# OF HEAD WRAPS | ||
| 2305 | ; WE NEED TO BE CAREFUL HERE. IF THE NEW SECTOR # IS 0, THEN WE ARE ON THE | ||
| 2306 | ; LAST SECTOR ON THAT TRACK. | ||
| 2307 | OR AH,AH | ||
| 2308 | JNZ NOT_ON_BOUND | ||
| 2309 | MOV AH,BL ; SET SECTOR=SECLIM IF ON BOUNDARY | ||
| 2310 | DEC AL ; ALSO DECREMENT # OF HEAD WRAPS | ||
| 2311 | NOT_ON_BOUND: | ||
| 2312 | AND CL,0C0H ; ZERO OUT SECTOR # | ||
| 2313 | OR CL,AH ; OR IN NEW SECTOR # | ||
| 2314 | XOR AH,AH ; AX = # OF HEAD WRAPS | ||
| 2315 | INC AX | ||
| 2316 | ADD AL,DH ; ADD IN STARTING HEAD # | ||
| 2317 | ADC AH,0 ; CATCH ANY CARRY | ||
| 2318 | CMP AX,[DI].HDLIM ; ARE WE GOING TO WRAP AROUND A HEAD? | ||
| 2319 | JBE NO_WRAP_HEAD ; DO NOT LOSE NEW HEAD NUMBER!! | ||
| 2320 | PUSH DX ; PRESERVE DRIVE NUMBER AND HEAD NUMBER | ||
| 2321 | XOR DX,DX | ||
| 2322 | MOV BX,[DI].HDLIM | ||
| 2323 | DIV BX ; DX=NEW HEAD #, AX=# OF CYLINDER WRAPS | ||
| 2324 | ; CAREFUL HERE! IF NEW HEAD # IS 0, THEN WE ARE ON THE LAST HEAD. | ||
| 2325 | OR DX,DX | ||
| 2326 | JNZ NO_HEAD_BOUND | ||
| 2327 | MOV DX,BX ; ON BOUNDARY. SET TO HDLIM | ||
| 2328 | ; IF WE HAD SOME CYLINDER WRAPS, WE NEED TO REDUCE THEM BY ONE!! | ||
| 2329 | OR AX,AX | ||
| 2330 | JZ NO_HEAD_BOUND | ||
| 2331 | DEC AX ; REDUCE NUMBER OF CYLINDER WRAPS | ||
| 2332 | NO_HEAD_BOUND: | ||
| 2333 | MOV BH,DL ; BH HAS NEW HEAD NUMBER | ||
| 2334 | POP DX ; RESTORE DRIVE NUMBER AND HEAD NUMBER | ||
| 2335 | DEC BH ; GET IT 0-BASED | ||
| 2336 | MOV DH,BH ; SET UP NEW HEAD NUMBER IN DH | ||
| 2337 | MOV BH,CL | ||
| 2338 | AND BH,3FH ; PRESERVE SECTOR NUMBER | ||
| 2339 | MOV BL,6 | ||
| 2340 | XCHG CL,BL | ||
| 2341 | SHR BL,CL ; GET MS CYLINDER BITS TO LS END | ||
| 2342 | ADD CH,AL ; ADD IN CYLINDER WRAP | ||
| 2343 | ADC BL,AH ; ADD IN HIGH BYTE | ||
| 2344 | SHL BL,CL ; MOVE UP TO MS END | ||
| 2345 | XCHG BL,CL ; RESTORE CYLINDER BITS INTO CL | ||
| 2346 | OR CL,BH ; OR IN SECTOR NUMBER | ||
| 2347 | |||
| 2348 | NO_WRAP: | ||
| 2349 | CLC ; RESET CARRY | ||
| 2350 | RESTOREREG <DI,DS,BX,AX> | ||
| 2351 | RET | ||
| 2352 | |||
| 2353 | NO_WRAP_HEAD: | ||
| 2354 | MOV DH,AL ; DO NOT LOSE NEW HEAD NUMBER | ||
| 2355 | DEC DH ; GET IT 0-BASED | ||
| 2356 | JMP SHORT NO_WRAP | ||
| 2357 | |||
| 2358 | ; | ||
| 2359 | ; INT_2F_13: | ||
| 2360 | ; THIS CODE IS CHAINED INTO THE INT_2F INTERRUPT DURING BIOS | ||
| 2361 | ; INITIALIZATION. IT ALLOWS THE USER TO CHANGE THE ORIG13 INT_13 VECTOR | ||
| 2362 | ; AFTER BOOTING. THIS ALLOWS TESTING AND IMPLEMENTATION OF CUSTOM INT_13 | ||
| 2363 | ; HANDLERS, WITHOUT GIVING UP MS-DOS ERROR RECOVERY | ||
| 2364 | ; | ||
| 2365 | ; ENTRY CONDITIONS | ||
| 2366 | ; AH == RESET_INT_13 (13H) | ||
| 2367 | ; DS:DX == ADDRESS OF NEW INT_13 HANDLER | ||
| 2368 | ; ES:BX == ADDRESS OF NEW INT_13 VECTOR USED BY WARM BOOT | ||
| 2369 | ; (INT 19) | ||
| 2370 | ; | ||
| 2371 | ; EXIT CONDITIONS | ||
| 2372 | ; ORIG13 == ADDRESS OF NEW INT_13 HANDLER | ||
| 2373 | ; DS:DX == OLD ORIG13 VALUE | ||
| 2374 | ; ES:BX == OLD OLD13 VALUE | ||
| 2375 | |||
| 2376 | ASSUME CS:CODE,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 2377 | |||
| 2378 | PUBLIC INT_2F_13 | ||
| 2379 | INT_2F_13 PROC FAR | ||
| 2380 | |||
| 2381 | CMP AH,13H ; IF (INTERRUPT_VALUE != RESET_INT_13) | ||
| 2382 | JE CHG_ORIG13 | ||
| 2383 | JMP CS:[NEXT2F_13] ; THEN CONTINUE ON INT_2F CHAIN | ||
| 2384 | |||
| 2385 | CHG_ORIG13: ; ELSE | ||
| 2386 | PUSH WORD PTR CS:[ORIG13] ; SAVE OLD VALUE OF OLD13 AND | ||
| 2387 | PUSH WORD PTR CS:[ORIG13 + 2]; ORIG13 SO THAT WE CAN | ||
| 2388 | |||
| 2389 | PUSH WORD PTR CS:[OLD13] ; RETURN THEM TO CALLER | ||
| 2390 | PUSH WORD PTR CS:[OLD13 + 2] | ||
| 2391 | |||
| 2392 | MOV WORD PTR CS:[ORIG13],DX ; ORIG13 := ADDR. OF NEW INT_13 | ||
| 2393 | ; VECTOR | ||
| 2394 | MOV WORD PTR CS:[ORIG13+2],DS | ||
| 2395 | |||
| 2396 | MOV WORD PTR CS:[OLD13],BX ; OLD13 := ADDR. OF NEW | ||
| 2397 | ; BOOT_13 VECTOR | ||
| 2398 | MOV WORD PTR CS:[OLD13+2],ES | ||
| 2399 | |||
| 2400 | POP ES ; ES:BX := OLD OLD13 VECTOR | ||
| 2401 | POP BX | ||
| 2402 | |||
| 2403 | POP DS ; DS:DX := OLD ORIG13 VECTOR | ||
| 2404 | POP DX | ||
| 2405 | |||
| 2406 | IRET ; END ELSE | ||
| 2407 | |||
| 2408 | INT_2F_13 ENDP | ||
| 2409 | |||
| 2410 | MOVE PROC NEAR | ||
| 2411 | CLD | ||
| 2412 | PUSH CX | ||
| 2413 | MOV CX,512/2 | ||
| 2414 | ;J.K. Warning!!! Do not change the position of this label. | ||
| 2415 | ; The following three bytes will be NOPed out by MSINIT if the system | ||
| 2416 | ; does not support the DOUBLE WORD MOV instruction, i.e., (if | ||
| 2417 | ; not 386 base machine.) | ||
| 2418 | ;---------------------------------------------------------------------------- | ||
| 2419 | public DoubleWordMov | ||
| 2420 | DoubleWordMov: ;AN002; | ||
| 2421 | shr cx, 1 ;AN002;Make it a double word. | ||
| 2422 | db 66h ;AN002;Machine code for double word mov | ||
| 2423 | ;---------------------------------------------------------------------------- | ||
| 2424 | REP MOVSW | ||
| 2425 | POP CX | ||
| 2426 | RET | ||
| 2427 | MOVE ENDP | ||
| 2428 | |||
| 2429 | DOINT PROC NEAR | ||
| 2430 | MOV DL,BYTE PTR [BP.OLDDX] ; GET PHYSICAL DRIVE NUMBER | ||
| 2431 | XOR AH,AH | ||
| 2432 | OR AL,AL | ||
| 2433 | JZ DOINTDONE | ||
| 2434 | MOV AH,BYTE PTR [BP.OLDAX+1] ; GET REQUEST CODE | ||
| 2435 | PUSH [BP.OLDF] | ||
| 2436 | CALL ORIG13 | ||
| 2437 | PUSHF | ||
| 2438 | POP [BP.OLDF] | ||
| 2439 | DOINTDONE: | ||
| 2440 | RET | ||
| 2441 | DOINT ENDP | ||
| 2442 | CODE ENDS | ||
| 2443 | END | ||