diff options
Diffstat (limited to '')
| -rw-r--r-- | v4.0/src/DEV/DRIVER/DRIVER.ASM | 1296 |
1 files changed, 1296 insertions, 0 deletions
diff --git a/v4.0/src/DEV/DRIVER/DRIVER.ASM b/v4.0/src/DEV/DRIVER/DRIVER.ASM new file mode 100644 index 0000000..4832e07 --- /dev/null +++ b/v4.0/src/DEV/DRIVER/DRIVER.ASM | |||
| @@ -0,0 +1,1296 @@ | |||
| 1 | PAGE 64,132 ; | ||
| 2 | ; SCCSID = @(#)driver.asm 4.13 85/10/15 | ||
| 3 | ; SCCSID = @(#)driver.asm 4.13 85/10/15 | ||
| 4 | ; | ||
| 5 | ; External block device driver | ||
| 6 | ; Hooks into existing routines in IBMBIO block driver via Int 2F mpx # 8. | ||
| 7 | ; This technique minimizes the size of the driver. | ||
| 8 | ; | ||
| 9 | |||
| 10 | ; Revised Try_h: to test for flagheads as msg was being displayed on FormFactor | ||
| 11 | ; this caused the FormFactor to be set in the Head | ||
| 12 | ; Revised the # of sectors/cluster for F0h to 1 | ||
| 13 | ;============================================================================== | ||
| 14 | ;REVISION HISTORY: | ||
| 15 | ;AN000 - New for DOS Version 4.00 - J.K. | ||
| 16 | ;AC000 - Changed for DOS Version 4.00 - J.K. | ||
| 17 | ;AN00x - PTM number for DOS Version 4.00 - J.K. | ||
| 18 | ;============================================================================== | ||
| 19 | ;AN001 - d55 Unable the fixed disk accessibility of DRIVER.SYS. 7/7/87 J.K. | ||
| 20 | ;AN002 - p196 Driver.sys does not signal init. failure 8/17/87 J.K. | ||
| 21 | ;AN003 - p267 "No driver letter..." message 8/19/87 J.K. | ||
| 22 | ;AN004 - p268 "Too many parameter..." message 8/20/87 J.K. | ||
| 23 | ;AN005 - p300 "Bad 1.44MB BPB information..." 8/20/87 J.K. | ||
| 24 | ;AN006 - p490 Driver should reject identical parms 8/28/87 J.K. | ||
| 25 | ;AN007 - p921 Parser.ASM problem 9/18/87 J.K. | ||
| 26 | ;AN008 - d493 New init request structure 2/25/88 J.K. | ||
| 27 | ;============================================================================== | ||
| 28 | |||
| 29 | code segment byte public | ||
| 30 | assume cs:code,ds:code,es:code | ||
| 31 | |||
| 32 | ;AN000; | ||
| 33 | .xlist | ||
| 34 | include SYSMSG.INC ;equates and macros | ||
| 35 | .list | ||
| 36 | MSG_UTILNAME <DRIVER> | ||
| 37 | |||
| 38 | iTEST = 0 | ||
| 39 | ;--------------------------------------------------- | ||
| 40 | ; | ||
| 41 | ; Device entry point | ||
| 42 | ; | ||
| 43 | DSKDEV LABEL WORD | ||
| 44 | DW -1,-1 ; link to next device | ||
| 45 | DW 0000100001000000B ; bit 6 indicates DOS 3.20 driver | ||
| 46 | DW STRATEGY | ||
| 47 | DW DSK$IN | ||
| 48 | DRVMAX DB 1 | ||
| 49 | |||
| 50 | ; | ||
| 51 | ; Various equates | ||
| 52 | ; | ||
| 53 | CMDLEN equ 0 ;LENGTH OF THIS COMMAND | ||
| 54 | UNIT equ 1 ;SUB UNIT SPECIFIER | ||
| 55 | CMD equ 2 ;COMMAND CODE | ||
| 56 | STATUS equ 3 ;STATUS | ||
| 57 | MEDIA equ 13 ;MEDIA DESCRIPTOR | ||
| 58 | TRANS equ 14 ;TRANSFER ADDRESS | ||
| 59 | COUNT equ 18 ;COUNT OF BLOCKS OR CHARACTERS | ||
| 60 | START equ 20 ;FIRST BLOCK TO TRANSFER | ||
| 61 | EXTRA equ 22 ;Usually a pointer to Vol Id for error 15 | ||
| 62 | CONFIG_ERRMSG equ 23 ;AN009; To set this field to Non-zero | ||
| 63 | ; to display "Error in CONFIG.SYS..." | ||
| 64 | |||
| 65 | PTRSAV DD 0 | ||
| 66 | |||
| 67 | |||
| 68 | STRATP PROC FAR | ||
| 69 | |||
| 70 | STRATEGY: | ||
| 71 | MOV WORD PTR CS:[PTRSAV],BX | ||
| 72 | MOV WORD PTR CS:[PTRSAV+2],ES | ||
| 73 | RET | ||
| 74 | |||
| 75 | STRATP ENDP | ||
| 76 | |||
| 77 | DSK$IN: | ||
| 78 | push es | ||
| 79 | push bx | ||
| 80 | push ax | ||
| 81 | les bx,cs:[ptrsav] | ||
| 82 | cmp byte ptr es:[bx].cmd,0 | ||
| 83 | jnz Not_Init | ||
| 84 | jmp DSK$INIT | ||
| 85 | |||
| 86 | not_init: | ||
| 87 | ; Because we are passing the call onto the block driver in IBMBIO, we need to | ||
| 88 | ; ensure that the unit number corresponds to the logical (DOS) unit number, as | ||
| 89 | ; opposed to the one that is relevant to this device driver. | ||
| 90 | mov al,byte ptr cs:[DOS_Drive_Letter] | ||
| 91 | mov byte ptr es:[bx].UNIT,al | ||
| 92 | mov ax,0802H | ||
| 93 | int 2fH | ||
| 94 | ; | ||
| 95 | ; We need to preserve the flags that are returned by IBMBIO. YUK!!!!! | ||
| 96 | ; | ||
| 97 | pushf | ||
| 98 | pop bx | ||
| 99 | add sp,2 | ||
| 100 | push bx | ||
| 101 | popf | ||
| 102 | |||
| 103 | exitp proc far | ||
| 104 | DOS_Exit: | ||
| 105 | pop ax | ||
| 106 | POP BX | ||
| 107 | POP ES | ||
| 108 | RET ;RESTORE REGS AND RETURN | ||
| 109 | EXITP ENDP | ||
| 110 | |||
| 111 | include msbds.inc ; include BDS structures | ||
| 112 | ;include versiona.inc | ||
| 113 | |||
| 114 | BDS DW -1 ;Link to next structure | ||
| 115 | DW -1 | ||
| 116 | DB 1 ;Int 13 Drive Number | ||
| 117 | DB 3 ;Logical Drive Letter | ||
| 118 | FDRIVE: | ||
| 119 | DW 512 ;Physical sector size in bytes | ||
| 120 | DB -1 ;Sectors/allocation unit | ||
| 121 | DW 1 ;Reserved sectors for DOS | ||
| 122 | DB 2 ;No. allocation tables | ||
| 123 | DW 64 ;Number directory entries | ||
| 124 | DW 9*40 ;Number sectors (at 512 bytes ea.) | ||
| 125 | DB 00000000B ;Media descriptor, initially 00H. | ||
| 126 | DW 2 ;Number of FAT sectors | ||
| 127 | DW 9 ;Sector limit | ||
| 128 | DW 1 ;Head limit | ||
| 129 | DW 0 ;Hidden sector count | ||
| 130 | dw 0 ;AN000; Hidden sector count (High) | ||
| 131 | dw 0 ;AN000; Number sectors (low) | ||
| 132 | dw 0 ;AN000; Number sectors (high) | ||
| 133 | DB 0 ; TRUE => Large fats | ||
| 134 | OPCNT1 DW 0 ;Open Ref. Count | ||
| 135 | DB 2 ;Form factor | ||
| 136 | FLAGS1 DW 0020H ;Various flags | ||
| 137 | DW 80 ;Number of cylinders in device | ||
| 138 | RecBPB1 DW 512 ; default is that of 3.5" disk | ||
| 139 | DB 2 | ||
| 140 | DW 1 | ||
| 141 | DB 2 | ||
| 142 | DW 70h | ||
| 143 | DW 2*9*80 | ||
| 144 | DB 0F9H | ||
| 145 | DW 3 | ||
| 146 | DW 9 | ||
| 147 | DW 2 | ||
| 148 | DW 0 | ||
| 149 | dw 0 ;AN000; | ||
| 150 | dw 0 ;AN000; | ||
| 151 | dw 0 ;AN000; | ||
| 152 | db 6 dup (0) ;AC000; | ||
| 153 | TRACK1 DB -1 ;Last track accessed on this drive | ||
| 154 | TIM_LO1 DW -1 ;Keep these two contiguous (?) | ||
| 155 | TIM_HI1 DW -1 | ||
| 156 | VOLID1 DB "NO NAME ",0 ;Volume ID for this disk | ||
| 157 | VOLSER dd 0 ;AN000; | ||
| 158 | FILE_ID db "FAT12 ",0 ;AN000; | ||
| 159 | |||
| 160 | DOS_Drive_Letter db ? ; Logical drive associated with this unit | ||
| 161 | |||
| 162 | ENDCODE LABEL WORD ; Everything below this is thrown away | ||
| 163 | ; after initialisation. | ||
| 164 | |||
| 165 | DskDrv dw offset FDRIVE ; "array" of BPBs | ||
| 166 | |||
| 167 | ;AN000; For system parser; | ||
| 168 | |||
| 169 | FarSW equ 0 ; Near call expected | ||
| 170 | |||
| 171 | DateSW equ 0 ; Check date format | ||
| 172 | |||
| 173 | TimeSW equ 0 ; Check time format | ||
| 174 | |||
| 175 | FileSW equ 0 ; Check file specification | ||
| 176 | |||
| 177 | CAPSW equ 0 ; Perform CAPS if specified | ||
| 178 | |||
| 179 | CmpxSW equ 0 ; Check complex list | ||
| 180 | |||
| 181 | NumSW equ 1 ; Check numeric value | ||
| 182 | |||
| 183 | KeySW equ 0 ; Support keywords | ||
| 184 | |||
| 185 | SwSW equ 1 ; Support switches | ||
| 186 | |||
| 187 | Val1SW equ 1 ; Support value definition 1 | ||
| 188 | |||
| 189 | Val2SW equ 1 ; Support value definition 2 | ||
| 190 | |||
| 191 | Val3SW equ 0 ; Support value definition 3 | ||
| 192 | |||
| 193 | DrvSW equ 0 ; Support drive only format | ||
| 194 | |||
| 195 | QusSW equ 0 ; Support quoted string format | ||
| 196 | ;--------------------------------------------------- | ||
| 197 | ;.xlist | ||
| 198 | assume ds:nothing ;AN007;!!!Parse.ASM sometimes assumes DS | ||
| 199 | ; to access its own variable!!! | ||
| 200 | include PARSE.ASM ;together with PSDATA.INC | ||
| 201 | assume ds:code ;AN007; | ||
| 202 | ;.list | ||
| 203 | ;Control block definitions for PARSER. | ||
| 204 | ;--------------------------------------------------- | ||
| 205 | Parms label byte | ||
| 206 | dw Parmsx ;AN000; | ||
| 207 | db 0 ;AN000;No extras | ||
| 208 | |||
| 209 | Parmsx label byte ;AN000; | ||
| 210 | db 0,0 ;AN000;No positionals | ||
| 211 | db 5 ;AN000;5 switch control definitions | ||
| 212 | dw D_Control ;AN000;/D | ||
| 213 | dw T_Control ;AN000;/T | ||
| 214 | dw HS_Control ;AN000;/H, /S | ||
| 215 | dw CN_Control ;AN000;/C, /N | ||
| 216 | dw F_Control ;AN000;/F | ||
| 217 | db 0 ;AN000;no keywords | ||
| 218 | |||
| 219 | D_Control label word ;AN000; | ||
| 220 | dw 8000h ;AN000;numeric value | ||
| 221 | dw 0 ;AN000;no functions | ||
| 222 | dw Result_Val ;AN000;result buffer | ||
| 223 | dw D_Val ;AN000;value defintions | ||
| 224 | db 1 ;AN000;# of switch in the following list | ||
| 225 | Switch_D label byte ;AN000; | ||
| 226 | db '/D',0 ;AN000; | ||
| 227 | |||
| 228 | D_Val label byte ;AN000; | ||
| 229 | db 1 ;AN000;# of value defintions | ||
| 230 | db 1 ;AN000;# of ranges | ||
| 231 | db 1 ;AN000;Tag value when match | ||
| 232 | ; dd 0,255 ;AN000; | ||
| 233 | dd 0,127 ;AN001;Do not allow a Fixed disk. | ||
| 234 | |||
| 235 | Result_Val label byte ;AN000; | ||
| 236 | db ? ;AN000; | ||
| 237 | Item_Tag label byte ;AN000; | ||
| 238 | db ? ;AN000; | ||
| 239 | Synonym_ptr label word ;AN000; | ||
| 240 | dw ? ;AN000;es:offset -> found Synonym | ||
| 241 | RV_Byte label byte ;AN000; | ||
| 242 | RV_Word label word ;AN000; | ||
| 243 | RV_Dword label dword ;AN000; | ||
| 244 | dd ? ;AN000;value if number, or seg:off to string | ||
| 245 | |||
| 246 | T_Control label word ;AN000; | ||
| 247 | dw 8000h ;AN000;numeric value | ||
| 248 | dw 0 ;AN000;no functions | ||
| 249 | dw Result_Val ;AN000;result buffer | ||
| 250 | dw T_Val ;AN000;value defintions | ||
| 251 | db 1 ;AN000;# of switch in the following list | ||
| 252 | Switch_T label byte ;AN000; | ||
| 253 | db '/T',0 ;AN000; | ||
| 254 | |||
| 255 | T_Val label byte ;AN000; | ||
| 256 | db 1 ;AN000;# of value defintions | ||
| 257 | db 1 ;AN000;# of ranges | ||
| 258 | db 1 ;AN000;Tag value when match | ||
| 259 | dd 1,999 ;AN000; | ||
| 260 | |||
| 261 | HS_Control label word ;AN000; | ||
| 262 | dw 8000h ;AN000;numeric value | ||
| 263 | dw 0 ;AN000;no function flag | ||
| 264 | dw Result_Val ;AN000;Result_buffer | ||
| 265 | dw HS_VAL ;AN000;value definition | ||
| 266 | db 2 ;AN000;# of switch in following list | ||
| 267 | Switch_H label byte ;AN000; | ||
| 268 | db '/H',0 ;AN000; | ||
| 269 | Switch_S label byte ;AN000; | ||
| 270 | db '/S',0 ;AN000; | ||
| 271 | |||
| 272 | HS_Val label byte ;AN000; | ||
| 273 | db 1 ;AN000;# of value defintions | ||
| 274 | db 1 ;AN000;# of ranges | ||
| 275 | db 1 ;AN000;Tag value when match | ||
| 276 | dd 1,99 ;AN000; | ||
| 277 | |||
| 278 | CN_Control label word ;AN000; | ||
| 279 | dw 0 ;AN000;no match flags | ||
| 280 | dw 0 ;AN000;no function flag | ||
| 281 | dw Result_Val ;AN000;no values returned | ||
| 282 | dw NoVal ;AN000;no value definition | ||
| 283 | ; db 2 ;AN000;# of switch in following list | ||
| 284 | db 1 ;AN001; | ||
| 285 | Switch_C label byte ;AN000; | ||
| 286 | db '/C',0 ;AN000; | ||
| 287 | ;Switch_N label byte ;AN000; | ||
| 288 | ; db '/N',0 ;AN000; | ||
| 289 | |||
| 290 | Noval db 0 ;AN000; | ||
| 291 | |||
| 292 | F_Control label word ;AN000; | ||
| 293 | dw 8000h ;AN000;numeric value | ||
| 294 | dw 0 ;AN000;no function flag | ||
| 295 | dw Result_Val ;AN000;Result_buffer | ||
| 296 | dw F_VAL ;AN000;value definition | ||
| 297 | db 1 ;AN000;# of switch in following list | ||
| 298 | Switch_F label byte ;AN000; | ||
| 299 | db '/F',0 ;AN000; | ||
| 300 | |||
| 301 | F_Val label byte ;AN000; | ||
| 302 | db 2 ;AN000;# of value definitions (Order dependent) | ||
| 303 | db 0 ;AN000;no ranges | ||
| 304 | db 4 ;AN000;# of numeric choices | ||
| 305 | F_Choices label byte ;AN000; | ||
| 306 | db 1 ;AN000;1st choice (item tag) | ||
| 307 | dd 0 ;AN000;0 | ||
| 308 | db 2 ;AN000;2nd choice | ||
| 309 | dd 1 ;AN000;1 | ||
| 310 | db 3 ;AN000;3rd choice | ||
| 311 | dd 2 ;AN000;2 | ||
| 312 | db 4 ;AN000;4th choice | ||
| 313 | dd 7 ;AN000;7 | ||
| 314 | |||
| 315 | |||
| 316 | ;AN000;System messages handler data | ||
| 317 | ;AN000;Put the data here | ||
| 318 | .sall | ||
| 319 | MSG_SERVICES <MSGDATA> | ||
| 320 | |||
| 321 | ;AN000;Place the messages here | ||
| 322 | MSG_SERVICES <DRIVER.CL1, DRIVER.CL2, DRIVER.CLA> | ||
| 323 | |||
| 324 | ;AN000;Put messages handler code here. | ||
| 325 | MSG_SERVICES <LOADmsg,DISPLAYmsg,CHARmsg> | ||
| 326 | .xall | ||
| 327 | |||
| 328 | ; | ||
| 329 | ; Sets ds:di -> BDS for this drive | ||
| 330 | ; | ||
| 331 | SetDrive: | ||
| 332 | push cs | ||
| 333 | pop ds | ||
| 334 | mov di,offset BDS | ||
| 335 | ret | ||
| 336 | |||
| 337 | ; | ||
| 338 | ; Place for DSK$INIT to exit | ||
| 339 | ; | ||
| 340 | ERR$EXIT: | ||
| 341 | MOV AH,10000001B ;MARK ERROR RETURN | ||
| 342 | lds bx, cs:[ptrsav] | ||
| 343 | mov byte ptr ds:[bx.MEDIA], 0 ;AN002; # of units | ||
| 344 | mov word ptr ds:[bx.CONFIG_ERRMSG], -1 ;AN009;Show IBMBIO error message too. | ||
| 345 | JMP SHORT ERR1 | ||
| 346 | |||
| 347 | Public EXIT | ||
| 348 | EXIT: MOV AH,00000001B | ||
| 349 | ERR1: LDS BX,CS:[PTRSAV] | ||
| 350 | MOV WORD PTR [BX].STATUS,AX ;MARK OPERATION COMPLETE | ||
| 351 | |||
| 352 | RestoreRegsAndReturn: | ||
| 353 | POP DS | ||
| 354 | POP BP | ||
| 355 | POP DI | ||
| 356 | POP DX | ||
| 357 | POP CX | ||
| 358 | POP AX | ||
| 359 | POP SI | ||
| 360 | jmp dos_exit | ||
| 361 | |||
| 362 | |||
| 363 | drivenumb db 5 | ||
| 364 | cyln dw 80 | ||
| 365 | heads dw 2 | ||
| 366 | ffactor db 2 | ||
| 367 | slim dw 9 | ||
| 368 | |||
| 369 | Switches dw 0 | ||
| 370 | |||
| 371 | Drive_Let_Sublist label dword | ||
| 372 | db 11 ;AN000;length of this table | ||
| 373 | db 0 ;AN000;reserved | ||
| 374 | dw D_Letter;AN000; | ||
| 375 | D_Seg dw ? ;AN000;Segment value. Should be CS | ||
| 376 | db 1 ;AN000;DRIVER.SYS has only %1 | ||
| 377 | db 00000000b ;AN000;left align(in fact, Don't care), a character. | ||
| 378 | db 1 ;AN000;max field width 1 | ||
| 379 | db 1 ;AN000;min field width 1 | ||
| 380 | db ' ' ;AN000;character for pad field (Don't care). | ||
| 381 | |||
| 382 | D_Letter db "A" | ||
| 383 | |||
| 384 | if iTEST | ||
| 385 | Message: | ||
| 386 | push ax | ||
| 387 | push ds | ||
| 388 | push cs | ||
| 389 | pop ds | ||
| 390 | mov ah,9 | ||
| 391 | int 21h | ||
| 392 | pop ds | ||
| 393 | pop ax | ||
| 394 | ret | ||
| 395 | extrn nodrive:byte,loadokmsg:byte,letter:byte, badvermsg:byte | ||
| 396 | endif | ||
| 397 | |||
| 398 | |||
| 399 | if iTEST | ||
| 400 | %OUT Testing On | ||
| 401 | initmsg db "Initializing device driver",13,10,"$" | ||
| 402 | stratmsg db "In strategy of driver",10,13,"$" | ||
| 403 | dskinmsg db "In DSKIN part of driver",10,13,"$" | ||
| 404 | outinitmsg db "Out of init code ",10,13,"$" | ||
| 405 | exitmsg db "Exiting from driver",10,13,"$" | ||
| 406 | parsemsg db "Parsing switches",10,13,"$" | ||
| 407 | errmsg db "Error occurred",10,13,"$" | ||
| 408 | linemsg db "Parsed line",10,13,"$" | ||
| 409 | int2fokmsg db "****************Int2f loaded**************",10,13,"$" | ||
| 410 | mediamsg db "Media check ok",10,13,"$" | ||
| 411 | getbpbmsg db "getbpb ok",10,13,"$" | ||
| 412 | iookmsg db "Successful I/O",10,13,"$" | ||
| 413 | parseokmsg db "Parsing done fine",10,13,"$" | ||
| 414 | nummsg db "Number read is " | ||
| 415 | number db "00 ",10,13,"$" | ||
| 416 | drvmsg db "Process drive " | ||
| 417 | driven db "0",10,13,"$" | ||
| 418 | cylnmsg db "Process cylinder ",10,13,"$" | ||
| 419 | slimmsg db "Process sec/trk ",10,13,"$" | ||
| 420 | hdmsg db "Process head " | ||
| 421 | hdnum db "0",10,13,"$" | ||
| 422 | ffmsg db "Process form factor " | ||
| 423 | ffnum db "0",10,13,"$" | ||
| 424 | nxtmsg db "Next switch ",10,13,"$" | ||
| 425 | msg48tpi db "Got a 48 tpi drive",10,13,"$" | ||
| 426 | |||
| 427 | ENDIF | ||
| 428 | |||
| 429 | DSK$INIT: | ||
| 430 | PUSH SI | ||
| 431 | PUSH AX | ||
| 432 | PUSH CX | ||
| 433 | PUSH DX | ||
| 434 | PUSH DI | ||
| 435 | PUSH BP | ||
| 436 | PUSH DS | ||
| 437 | |||
| 438 | LDS BX,CS:[PTRSAV] ;GET POINTER TO I/O PACKET | ||
| 439 | |||
| 440 | MOV AL,BYTE PTR DS:[BX].UNIT ;AL = UNIT CODE | ||
| 441 | MOV AH,BYTE PTR DS:[BX].MEDIA ;AH = MEDIA DESCRIP | ||
| 442 | MOV CX,WORD PTR DS:[BX].COUNT ;CX = COUNT | ||
| 443 | MOV DX,WORD PTR DS:[BX].START ;DX = START SECTOR | ||
| 444 | |||
| 445 | LES DI,DWORD PTR DS:[BX].TRANS | ||
| 446 | |||
| 447 | PUSH CS | ||
| 448 | POP DS | ||
| 449 | |||
| 450 | ASSUME DS:CODE | ||
| 451 | |||
| 452 | cld | ||
| 453 | push cs ;AN000; Initialize Segment of Sub list. | ||
| 454 | pop [D_Seg] ;AN000; | ||
| 455 | call SYSLOADMSG ;AN000; linitialize message handler | ||
| 456 | jnc GoodVer ;AN000; Error. Do not install driver. | ||
| 457 | mov cx, 0 ;AN000; No substitution | ||
| 458 | mov dh, -1 ;AN000; Utility message | ||
| 459 | call Show_Message ;AN000; Show message | ||
| 460 | jmp err$exitj2 ;AN000; and exit | ||
| 461 | |||
| 462 | ;; check for correct DOS version | ||
| 463 | ; mov ah,30h | ||
| 464 | ; int 21H | ||
| 465 | |||
| 466 | ; cmp ax,expected_version | ||
| 467 | ; je GoodVer | ||
| 468 | |||
| 469 | ; cmp al,DOSVER_HI | ||
| 470 | ; jnz BadDOSVer | ||
| 471 | ; cmp ah,DOSVER_LO | ||
| 472 | ; jz GoodVer | ||
| 473 | |||
| 474 | ;BadDOSVer: | ||
| 475 | ; Mov dx,offset BadVerMsg | ||
| 476 | ; call message | ||
| 477 | ; jmp err$exitj2 ; do not install driver | ||
| 478 | |||
| 479 | GoodVer: | ||
| 480 | mov ax,0800H | ||
| 481 | int 2fH ; see if installed | ||
| 482 | cmp al,0FFH | ||
| 483 | jnz err$exitj2 ; do not install driver if not present | ||
| 484 | lds bx,[ptrsav] | ||
| 485 | mov si,word ptr [bx].count ; get pointer to line to be parsed | ||
| 486 | mov ax,word ptr [bx].count+2 | ||
| 487 | mov ds,ax | ||
| 488 | call Skip_Over_Name ; skip over file name of driver | ||
| 489 | mov di,offset BDS ; point to BDS for drive | ||
| 490 | push cs | ||
| 491 | pop es ; es:di -> BDS | ||
| 492 | Call ParseLine | ||
| 493 | jc err$exitj2 | ||
| 494 | LDS BX,cs:[PTRSAV] | ||
| 495 | mov al,byte ptr [bx].extra ; get DOS drive letter | ||
| 496 | mov byte ptr es:[di].DriveLet,al | ||
| 497 | mov cs:[DOS_Drive_Letter],al | ||
| 498 | add al,"A" | ||
| 499 | ; mov cs:[letter],al ; set up for printing final message | ||
| 500 | mov cs:[D_Letter], al ;AN000; | ||
| 501 | call SetDrvParms ; Set up BDS according to switches | ||
| 502 | jc err$exitj2 | ||
| 503 | mov ah,8 ; Int 2f multiplex number | ||
| 504 | mov al,1 ; install the BDS into the list | ||
| 505 | push cs | ||
| 506 | pop ds ; ds:di -> BDS for drive | ||
| 507 | mov di,offset BDS | ||
| 508 | int 2FH | ||
| 509 | lds bx,dword ptr cs:[ptrsav] | ||
| 510 | mov ah,1 | ||
| 511 | mov cs:[DRVMAX],ah | ||
| 512 | mov byte ptr [bx].media,ah | ||
| 513 | mov ax,offset ENDCODE | ||
| 514 | mov word ptr [bx].TRANS,AX ; set address of end of code | ||
| 515 | mov word ptr [bx].TRANS+2,CS | ||
| 516 | mov word ptr [bx].count,offset DskDrv | ||
| 517 | mov word ptr [bx].count+2,cs | ||
| 518 | |||
| 519 | push dx | ||
| 520 | push cs | ||
| 521 | pop ds | ||
| 522 | mov si, offset Drive_Let_SubList ;AC000; | ||
| 523 | mov ax, LOADOK_MSG_NUM ;load ok message | ||
| 524 | mov cx, 1 ;AN000; 1 substitution | ||
| 525 | mov dh, -1 ;AN000; utility message | ||
| 526 | call Show_Message | ||
| 527 | ; mov dx,offset loadokmsg | ||
| 528 | ; call message | ||
| 529 | pop dx | ||
| 530 | jmp EXIT | ||
| 531 | |||
| 532 | err$exitj2: | ||
| 533 | stc | ||
| 534 | jmp err$exit | ||
| 535 | |||
| 536 | ; | ||
| 537 | ; Skips over characters at ds:si until it hits a `/` which indicates a switch | ||
| 538 | ; J.K. If it hits 0Ah or 0Dh, then will return with SI points to that character. | ||
| 539 | Skip_Over_Name: | ||
| 540 | call scanblanks | ||
| 541 | loop_name: | ||
| 542 | lodsb | ||
| 543 | cmp al,CR ;AN003; | ||
| 544 | je End_SkipName ;AN003; | ||
| 545 | cmp al,LF ;AN003; | ||
| 546 | je End_SkipName ;AN003; | ||
| 547 | cmp al,'/' | ||
| 548 | jnz loop_name | ||
| 549 | End_SkipName: ;AN003; | ||
| 550 | dec si ; go back one character | ||
| 551 | RET | ||
| 552 | |||
| 553 | ;ParseLine: | ||
| 554 | ; push di | ||
| 555 | ; push ds | ||
| 556 | ; push si | ||
| 557 | ; push es | ||
| 558 | ;Next_Swt: | ||
| 559 | ;IF iTEST | ||
| 560 | ; mov dx,offset nxtmsg | ||
| 561 | ; call message | ||
| 562 | ;ENDIF | ||
| 563 | ; call ScanBlanks | ||
| 564 | ; lodsb | ||
| 565 | ; cmp al,'/' | ||
| 566 | ; jz getparm | ||
| 567 | ; cmp al,13 ; carriage return | ||
| 568 | ; jz done_line | ||
| 569 | ; CMP AL,10 ; line feed | ||
| 570 | ; jz done_line | ||
| 571 | ; cmp al,0 ; null string | ||
| 572 | ; jz done_line | ||
| 573 | ; mov ax,-2 ; mark error invalid-character-in-input | ||
| 574 | ; stc | ||
| 575 | ; jmp short exitparse | ||
| 576 | ; | ||
| 577 | ;getparm: | ||
| 578 | ; call Check_Switch | ||
| 579 | ; mov cs:Switches,BX ; save switches read so far | ||
| 580 | ; jnc Next_Swt | ||
| 581 | ; cmp ax,-1 ; mark error number-too-large | ||
| 582 | ; stc | ||
| 583 | ; jz exitparse | ||
| 584 | ; mov ax,-2 ; mark invalid parameter | ||
| 585 | ; stc | ||
| 586 | ; jmp short exitparse | ||
| 587 | ; | ||
| 588 | ;done_line: | ||
| 589 | ; test cs:Switches,flagdrive ; see if drive specified | ||
| 590 | ; jnz okay | ||
| 591 | ; push dx | ||
| 592 | ; mov ax, 2 | ||
| 593 | ; call Show_Message | ||
| 594 | ; mov dx,offset nodrive | ||
| 595 | ; call message | ||
| 596 | ; pop dx | ||
| 597 | ; mov ax,-3 ; mark error no-drive-specified | ||
| 598 | ; stc | ||
| 599 | ; jmp short exitparse | ||
| 600 | ; | ||
| 601 | ;okay: | ||
| 602 | ; call SetDrive ; ds:di points to BDS now. | ||
| 603 | ; mov ax,cs:Switches | ||
| 604 | ; and ax,fChangeline+fNon_Removable ; get switches for Non_Removable and Changeline | ||
| 605 | ; or ds:[di].flags,ax | ||
| 606 | ; xor ax,ax ; everything is fine | ||
| 607 | ; | ||
| 608 | ;; | ||
| 609 | ;; Can detect status of parsing by examining value in AX. | ||
| 610 | ;; 0 ==> Successful | ||
| 611 | ;; -1 ==> Number too large | ||
| 612 | ;; -2 ==> Invalid character in input | ||
| 613 | ;; -3 ==> No drive specified | ||
| 614 | ; | ||
| 615 | ; clc | ||
| 616 | ;exitparse: | ||
| 617 | ; pop es | ||
| 618 | ; pop si | ||
| 619 | ; pop ds | ||
| 620 | ; pop di | ||
| 621 | ; ret | ||
| 622 | |||
| 623 | |||
| 624 | |||
| 625 | ParseLine proc near | ||
| 626 | ;In) DS:SI -> Input string | ||
| 627 | ; ES = CS | ||
| 628 | ; ES:DI -> BDS table inside this program | ||
| 629 | ; | ||
| 630 | ;Out) | ||
| 631 | ; if successfule, then { AX will be set according to the switch | ||
| 632 | ; flag value. BDS.Flag, Drivenumb, cylin, | ||
| 633 | ; slim, heads ffactor are set } | ||
| 634 | ; else | ||
| 635 | ; { | ||
| 636 | ; If (no drive specified) then { display messages }; | ||
| 637 | ; Set carry; | ||
| 638 | ; } | ||
| 639 | ; | ||
| 640 | ;Subroutine to be called: | ||
| 641 | ; SYSPARSE:NEAR, SHOW_MESSAGE:NEAR, GET_RESULT:NEAR | ||
| 642 | ; | ||
| 643 | ;Logic: | ||
| 644 | ;{ While (Not end_of_Line) | ||
| 645 | ; { | ||
| 646 | ; SYSPARSE (); | ||
| 647 | ; if (no error) then | ||
| 648 | ; GET_RESULT () | ||
| 649 | ; else | ||
| 650 | ; Set carry; | ||
| 651 | ; }; | ||
| 652 | ; | ||
| 653 | ; if (carry set) then Exit; /* Initialization failed */ | ||
| 654 | ; if (No drive number entered) /* Drive number is a requirement */ | ||
| 655 | ; then { Show_Message (); | ||
| 656 | ; exit; | ||
| 657 | ; }; | ||
| 658 | ; | ||
| 659 | assume ds:nothing ;AN000;make sure | ||
| 660 | push di ;AN000;save BDS pointer | ||
| 661 | mov di, offset PARMS ;AN000;now, es:di -> parse control definition | ||
| 662 | SysP_While: ;AN000; | ||
| 663 | xor cx, cx ;AN004; I don't have positionals. | ||
| 664 | xor dx, dx ;AN000; | ||
| 665 | call SYSPARSE ;AN000; | ||
| 666 | cmp ax, $P_RC_EOL ;AN000;end of line? | ||
| 667 | je SysP_End ;AN000; | ||
| 668 | cmp ax, $P_NO_ERROR ;AN000;no error? | ||
| 669 | jne SysP_Fail ;AN000; | ||
| 670 | call Get_Result ;AN000; | ||
| 671 | jmp SysP_While ;AN000; | ||
| 672 | SysP_End: ;AN000; | ||
| 673 | test Switches, FLAGDRIVE ;AN000;drive number specified? | ||
| 674 | jnz SysP_Ok ;AN000;Drive number is a requirement | ||
| 675 | push ds ;AN000; | ||
| 676 | mov ax, NODRIVE_MSG_NUM ;AN000;no drive specification | ||
| 677 | mov cx, 0 ;AN000;no substitutions | ||
| 678 | mov dh, -1 ;AN000;utility message | ||
| 679 | call Show_Message ;AN000; | ||
| 680 | pop ds ;AN000; | ||
| 681 | jmp short SysP_Err ;AN003; | ||
| 682 | SysP_Fail: ;AN000; | ||
| 683 | mov dh, 2 ;AN000; parse error | ||
| 684 | mov cx, 0 ;AN000; | ||
| 685 | call Show_Message ;AN000; Show parse error | ||
| 686 | SysP_Err: ;AN003; | ||
| 687 | stc ;AN000; | ||
| 688 | jmp short PL_Ret ;AN000; | ||
| 689 | SysP_Ok: ;AN000; | ||
| 690 | clc ;AN000; | ||
| 691 | PL_Ret: ;AN000; | ||
| 692 | pop di ;AN000;restore BDS pointer | ||
| 693 | ret ;AN000; | ||
| 694 | ParseLine endp | ||
| 695 | |||
| 696 | ; | ||
| 697 | Get_Result proc near | ||
| 698 | ;In) A successful result of SYSPARSE in Result_Val | ||
| 699 | ; es = cs, ds = command line segment | ||
| 700 | ;Out) | ||
| 701 | ; Switches set according to the user option. | ||
| 702 | ; Drivenumb, Cyln, Heads, Slim, ffactor set if specified. | ||
| 703 | ;Logic) | ||
| 704 | ; Switch (Synonym_Ptr) | ||
| 705 | ; { case Switch_D: Switches = Switches | FLAGDRIVE; /* Set switches */ | ||
| 706 | ; Drivenumb = Reg_DX.Value_L; | ||
| 707 | ; break; | ||
| 708 | ; | ||
| 709 | ; case Switch_T: Switches = Switches | Flagcyln; | ||
| 710 | ; Cyln = Reg_DX.Value_L; | ||
| 711 | ; break; | ||
| 712 | ; | ||
| 713 | ; case Switch_H: Switches = Switches | Flagheads; | ||
| 714 | ; Heads = Reg_DX.Value_L; | ||
| 715 | ; break; | ||
| 716 | ; | ||
| 717 | ; case Switch_S: Switches = Switches | FlagSecLim; | ||
| 718 | ; Slim = Reg_DX.Value_L; | ||
| 719 | ; break; | ||
| 720 | ; | ||
| 721 | ; case Switch_C: Switches = Switches | fChangeline; | ||
| 722 | ; break; | ||
| 723 | ; | ||
| 724 | ;; case Switch_N: Switches = Switches | fNon_Removable; | ||
| 725 | ;; break; | ||
| 726 | ; | ||
| 727 | ; case Switch_F: Switches = Switches | Flagff; | ||
| 728 | ; Reg_DX = (Reg_DX.ITEM_Tag - 1)*5;/*Get the offset of | ||
| 729 | ; /*the choice. | ||
| 730 | ; ffactor = byte ptr (F_Choices + DX + 1); | ||
| 731 | ; /*Get the value of it */ | ||
| 732 | ; break; | ||
| 733 | ; | ||
| 734 | ; } | ||
| 735 | ; | ||
| 736 | |||
| 737 | |||
| 738 | mov ax, Synonym_Ptr ;AN000; | ||
| 739 | push ax ;AN006; save Synonym_ptr | ||
| 740 | cmp ax, offset Switch_D ;AN000; | ||
| 741 | jne Stch_T ;AN000; | ||
| 742 | or Switches, FLAGDRIVE ;AN000; | ||
| 743 | mov al, RV_Byte ;AN000; | ||
| 744 | mov Drivenumb, al ;AN000; | ||
| 745 | jmp GR_Ret ;AN000; | ||
| 746 | Stch_T: ;AN000; | ||
| 747 | cmp ax, offset Switch_T ;AN000; | ||
| 748 | jne Stch_H ;AN000; | ||
| 749 | or Switches, FLAGCYLN ;AN000; | ||
| 750 | mov ax, RV_Word ;AN000; | ||
| 751 | mov Cyln, ax ;AN000; | ||
| 752 | jmp GR_Ret ;AN000; | ||
| 753 | Stch_H: ;AN000; | ||
| 754 | cmp ax, offset Switch_H ;AN000; | ||
| 755 | jne Stch_S ;AN000; | ||
| 756 | or Switches, FLAGHEADS ;AN000; | ||
| 757 | mov ax, RV_Word ;AN000; | ||
| 758 | mov Heads, ax ;AN000; | ||
| 759 | jmp GR_Ret ;AN000; | ||
| 760 | Stch_S: ;AN000; | ||
| 761 | cmp ax, offset Switch_S ;AN000; | ||
| 762 | jne Stch_C ;AN000; | ||
| 763 | or Switches, FLAGSECLIM ;AN000; | ||
| 764 | mov ax, RV_Word ;AN000; | ||
| 765 | mov Slim, ax ;AN000; | ||
| 766 | jmp GR_Ret ;AN000; | ||
| 767 | Stch_C: ;AN000; | ||
| 768 | cmp ax, offset Switch_C ;AN000; | ||
| 769 | ; jne Stch_N ;AN000; | ||
| 770 | jne Stch_F ;AN001; | ||
| 771 | or Switches, fCHANGELINE ;AN000; | ||
| 772 | jmp GR_Ret ;AN000; | ||
| 773 | ;Stch_N: ;AN000; | ||
| 774 | ; cmp ax, offset Switch_N ;AN000; | ||
| 775 | ; jne Stch_F ;AN000; | ||
| 776 | ; or Switches, fNON_REMOVABLE ;AN000; | ||
| 777 | ; jmp GR_Ret ;AN000; | ||
| 778 | Stch_F: ;AN000; | ||
| 779 | cmp ax, offset Switch_F ;AN000; | ||
| 780 | jne GR_Not_Found_Ret ;AN000;error in SYSPARSE | ||
| 781 | or Switches, FLAGFF ;AN000; | ||
| 782 | push si ;AN004; | ||
| 783 | mov si, offset F_Choices ;AN000; | ||
| 784 | xor ax, ax ;AN000; | ||
| 785 | mov al, Item_Tag ;AN000; | ||
| 786 | dec al ;AN000; | ||
| 787 | mov cl, 5 ;AN000; | ||
| 788 | mul cl ;AN000; | ||
| 789 | add si, ax ;AN000; | ||
| 790 | mov al, byte ptr es:[si+1] ;AN000;get the result of choices | ||
| 791 | mov ffactor, al ;AN000;set form factor | ||
| 792 | pop si ;AN004; | ||
| 793 | GR_Ret: ;AN000; | ||
| 794 | pop ax ;AN006; Restore Synonym ptr | ||
| 795 | push di ;AN006; Save di | ||
| 796 | push ax ;AN006; | ||
| 797 | pop di ;AN006; | ||
| 798 | mov byte ptr es:[di], ' ' ;AN006;We don't have this switch any more. | ||
| 799 | pop di ;AN006; | ||
| 800 | jmp short Gr_Done_Ret ;AN006; | ||
| 801 | GR_Not_Found_Ret: | ||
| 802 | pop ax ;AN006;adjust stack | ||
| 803 | GR_Done_Ret: | ||
| 804 | ret ;AN000; | ||
| 805 | Get_Result endp | ||
| 806 | |||
| 807 | |||
| 808 | ; | ||
| 809 | ; Scans an input line for blank or tab characters. On return, the line pointer | ||
| 810 | ; will be pointing to the next non-blank character. | ||
| 811 | ; | ||
| 812 | ScanBlanks: | ||
| 813 | lodsb | ||
| 814 | cmp al,' ' | ||
| 815 | jz ScanBlanks | ||
| 816 | cmp al,9 ; Tab character | ||
| 817 | jz ScanBlanks | ||
| 818 | dec si | ||
| 819 | ret | ||
| 820 | |||
| 821 | ; | ||
| 822 | ; Gets a number from the input stream, reading it as a string of characters. | ||
| 823 | ; It returns the number in AX. It assumes the end of the number in the input | ||
| 824 | ; stream when the first non-numeric character is read. It is considered an error | ||
| 825 | ; if the number is too large to be held in a 16 bit register. In this case, AX | ||
| 826 | ; contains -1 on return. | ||
| 827 | ; | ||
| 828 | ;GetNum: | ||
| 829 | ; push bx | ||
| 830 | ; push dx | ||
| 831 | ; xor ax,ax | ||
| 832 | ; xor bx,bx | ||
| 833 | ; xor dx,dx | ||
| 834 | ; | ||
| 835 | ;next_char: | ||
| 836 | ; lodsb | ||
| 837 | ; cmp al,'0' ; check for valid numeric input | ||
| 838 | ; jb num_ret | ||
| 839 | ; cmp al,'9' | ||
| 840 | ; ja num_ret | ||
| 841 | ; sub al,'0' | ||
| 842 | ; xchg ax,bx ; save intermediate value | ||
| 843 | ; push bx | ||
| 844 | ; mov bx,10 | ||
| 845 | ; mul bx | ||
| 846 | ; pop bx | ||
| 847 | ; add al,bl | ||
| 848 | ; adc ah,0 | ||
| 849 | ; xchg ax,bx ; stash total | ||
| 850 | ; jc got_large | ||
| 851 | ; cmp dx,0 | ||
| 852 | ; jz next_char | ||
| 853 | ;got_large: | ||
| 854 | ; mov ax,-1 | ||
| 855 | ; jmp short get_ret | ||
| 856 | ; | ||
| 857 | ;num_ret: | ||
| 858 | ; mov ax,bx | ||
| 859 | ; dec si ; put last character back into buffer | ||
| 860 | ; | ||
| 861 | ;get_ret: | ||
| 862 | ; pop dx | ||
| 863 | ; pop bx | ||
| 864 | ; ret | ||
| 865 | |||
| 866 | |||
| 867 | ; | ||
| 868 | ; Processes a switch in the input. It ensures that the switch is valid, and | ||
| 869 | ; gets the number, if any required, following the switch. The switch and the | ||
| 870 | ; number *must* be separated by a colon. Carry is set if there is any kind of | ||
| 871 | ; error. | ||
| 872 | ; | ||
| 873 | ;Check_Switch: | ||
| 874 | ; lodsb | ||
| 875 | ; and al,0DFH ; convert it to upper case | ||
| 876 | ; cmp al,'A' | ||
| 877 | ; jb err_swtch | ||
| 878 | ; cmp al,'Z' | ||
| 879 | ; ja err_swtch | ||
| 880 | ; mov cl,cs:switchlist ; get number of valid switches | ||
| 881 | ; mov ch,0 | ||
| 882 | ; push es | ||
| 883 | ; push cs | ||
| 884 | ; pop es ; set es:di -> switches | ||
| 885 | ; push di | ||
| 886 | ; mov di,1+offset switchlist ; point to string of valid switches | ||
| 887 | ; repne scasb | ||
| 888 | ; pop di | ||
| 889 | ; pop es | ||
| 890 | ; jnz err_swtch | ||
| 891 | ; mov ax,1 | ||
| 892 | ; shl ax,cl ; set bit to indicate switch | ||
| 893 | ; mov bx,cs:switches | ||
| 894 | ; or bx,ax ; save this with other switches | ||
| 895 | ; mov cx,ax | ||
| 896 | ; test ax,7cH ; test against switches that require number to follow | ||
| 897 | ; jz done_swtch | ||
| 898 | ; lodsb | ||
| 899 | ; cmp al,':' | ||
| 900 | ; jnz reset_swtch | ||
| 901 | ; call ScanBlanks | ||
| 902 | ; call GetNum | ||
| 903 | ; cmp ax,-1 ; was number too large? | ||
| 904 | ; jz reset_swtch | ||
| 905 | ;IF iTEST | ||
| 906 | ; push ax | ||
| 907 | ; add al,'0' | ||
| 908 | ; add ah,'0' | ||
| 909 | ; mov cs:number,ah | ||
| 910 | ; mov cs:number+1,al | ||
| 911 | ; mov dx,offset nummsg | ||
| 912 | ; call message | ||
| 913 | ; pop ax | ||
| 914 | ;ENDIF | ||
| 915 | ; call Process_Num | ||
| 916 | ; | ||
| 917 | ;done_swtch: | ||
| 918 | ; ret | ||
| 919 | ; | ||
| 920 | ;reset_swtch: | ||
| 921 | ; xor bx,cx ; remove this switch from the records | ||
| 922 | ;err_swtch: | ||
| 923 | ; stc | ||
| 924 | ; jmp short done_swtch | ||
| 925 | |||
| 926 | ; | ||
| 927 | ; This routine takes the switch just input, and the number following (if any), | ||
| 928 | ; and sets the value in the appropriate variable. If the number input is zero | ||
| 929 | ; then it does nothing - it assumes the default value that is present in the | ||
| 930 | ; variable at the beginning. | ||
| 931 | ; | ||
| 932 | ;Process_Num: | ||
| 933 | ; push ds | ||
| 934 | ; push cs | ||
| 935 | ; pop ds | ||
| 936 | ; test Switches,cx ; if this switch has been done before, | ||
| 937 | ; jnz done_ret ; ignore this one. | ||
| 938 | ; test cx,flagdrive | ||
| 939 | ; jz try_f | ||
| 940 | ; mov drivenumb,al | ||
| 941 | ;IF iTEST | ||
| 942 | ; add al,"0" | ||
| 943 | ; mov driven,al | ||
| 944 | ; mov dx,offset drvmsg | ||
| 945 | ; call message | ||
| 946 | ;ENDIF | ||
| 947 | ; jmp short done_ret | ||
| 948 | ; | ||
| 949 | ;try_f: | ||
| 950 | ; test cx,flagff | ||
| 951 | ; jz try_t | ||
| 952 | ; mov ffactor,al | ||
| 953 | ;IF iTEST | ||
| 954 | ; add al,"0" | ||
| 955 | ; mov ffnum,al | ||
| 956 | ; mov dx,offset ffmsg | ||
| 957 | ; call message | ||
| 958 | ;ENDIF | ||
| 959 | ; | ||
| 960 | ;try_t: | ||
| 961 | ; cmp ax,0 | ||
| 962 | ; jz done_ret ; if number entered was 0, assume default value | ||
| 963 | ; test cx,flagcyln | ||
| 964 | ; jz try_s | ||
| 965 | ; mov cyln,ax | ||
| 966 | ;IF iTEST | ||
| 967 | ; mov dx,offset cylnmsg | ||
| 968 | ; call message | ||
| 969 | ;ENDIF | ||
| 970 | ; jmp short done_ret | ||
| 971 | ; | ||
| 972 | ;try_s: | ||
| 973 | ; test cx,flagseclim | ||
| 974 | ; jz try_h | ||
| 975 | ; mov slim,ax | ||
| 976 | ;IF iTEST | ||
| 977 | ; mov dx,offset slimmsg | ||
| 978 | ; call message | ||
| 979 | ;ENDIF | ||
| 980 | ; jmp short done_ret | ||
| 981 | ; | ||
| 982 | ;; Switch must be one for number of Heads. | ||
| 983 | ;try_h: | ||
| 984 | ; test cx,flagheads | ||
| 985 | ; jz done_ret | ||
| 986 | ; mov heads,ax | ||
| 987 | ;IF iTEST | ||
| 988 | ; add al,"0" | ||
| 989 | ; mov hdnum,al | ||
| 990 | ; mov dx,offset hdmsg | ||
| 991 | ; call message | ||
| 992 | ;ENDIF | ||
| 993 | ; | ||
| 994 | ;done_ret: | ||
| 995 | ; pop ds | ||
| 996 | ; ret | ||
| 997 | |||
| 998 | ; | ||
| 999 | ; SetDrvParms sets up the recommended BPB in each BDS in the system based on | ||
| 1000 | ; the form factor. It is assumed that the BPBs for the various form factors | ||
| 1001 | ; are present in the BPBTable. For hard files, the Recommended BPB is the same | ||
| 1002 | ; as the BPB on the drive. | ||
| 1003 | ; No attempt is made to preserve registers since we are going to jump to | ||
| 1004 | ; SYSINIT straight after this routine. | ||
| 1005 | ; | ||
| 1006 | SetDrvParms: | ||
| 1007 | push cs | ||
| 1008 | pop es | ||
| 1009 | xor bx,bx | ||
| 1010 | call SetDrive ; ds:di -> BDS | ||
| 1011 | ;test cs:switches,flagff ; has formfactor been specified? | ||
| 1012 | ;jz formfcont | ||
| 1013 | mov bl,cs:[ffactor] | ||
| 1014 | mov byte ptr [di].formfactor,bl ; replace with new value | ||
| 1015 | formfcont: | ||
| 1016 | mov bl,[di].FormFactor | ||
| 1017 | ;AC000; The followings are redundanat since there is no input specified for Hard file. | ||
| 1018 | ; cmp bl,ffHardFile | ||
| 1019 | ; jnz NotHardFF | ||
| 1020 | ; mov ax,[di].DrvLim | ||
| 1021 | ; cmp ax, 0 ;AN000;32 bit sector number? | ||
| 1022 | ; push ax | ||
| 1023 | ; mov ax,word ptr [di].hdlim | ||
| 1024 | ; mul word ptr [di].seclim | ||
| 1025 | ; mov cx,ax ; cx has # sectors per cylinder | ||
| 1026 | ; pop ax | ||
| 1027 | ; xor dx,dx ; set up for div | ||
| 1028 | ; div cx ; div #sec by sec/cyl to get # cyl | ||
| 1029 | ; or dx,dx | ||
| 1030 | ; jz No_Cyl_Rnd ; came out even | ||
| 1031 | ; inc ax ; round up | ||
| 1032 | ;No_Cyl_Rnd: | ||
| 1033 | ; mov cs:[cyln],ax | ||
| 1034 | ; mov si,di | ||
| 1035 | ; add si,BytePerSec ; ds:si -> BPB for hard file | ||
| 1036 | ; jmp short Set_RecBPB | ||
| 1037 | ;NotHardFF: | ||
| 1038 | ;AC000; End of deletion. | ||
| 1039 | cmp bl,ff48tpi | ||
| 1040 | jnz Got_80_cyln | ||
| 1041 | IF iTEST | ||
| 1042 | mov dx,offset msg48tpi | ||
| 1043 | call message | ||
| 1044 | ENDIF | ||
| 1045 | mov cx,40 | ||
| 1046 | mov cs:[cyln],cx | ||
| 1047 | Got_80_cyln: | ||
| 1048 | shl bx,1 ; bx is word index into table of BPBs | ||
| 1049 | mov si,offset BPBTable | ||
| 1050 | mov si,word ptr [si+bx] ; get address of BPB | ||
| 1051 | Set_RecBPB: | ||
| 1052 | add di,RBytePerSec ; es:di -> Recommended BPB | ||
| 1053 | mov cx,BPBSIZ | ||
| 1054 | cld | ||
| 1055 | repe movsb ; move BPBSIZ bytes | ||
| 1056 | |||
| 1057 | call Handle_Switches ; replace with 'new' values as | ||
| 1058 | ; specified in switches. | ||
| 1059 | ; | ||
| 1060 | ; We need to set the media byte and the total number of sectors to reflect the | ||
| 1061 | ; number of heads. We do this by multiplying the number of heads by the number | ||
| 1062 | ; of 'sectors per head'. This is not a fool-proof scheme!! | ||
| 1063 | ; | ||
| 1064 | mov ax,[di].Rdrvlim ; this is OK for two heads | ||
| 1065 | sar ax,1 ; ax contains # of sectors/head | ||
| 1066 | mov cx,[di].Rhdlim | ||
| 1067 | dec cl ; get it 0-based | ||
| 1068 | sal ax,cl | ||
| 1069 | jc Set_All_Done_BRG ; We have too many sectors - overflow!! | ||
| 1070 | mov [di].Rdrvlim,ax | ||
| 1071 | cmp cl,1 | ||
| 1072 | ; We use media descriptor byte F0H for any type of medium that is not currently | ||
| 1073 | ; defined i.e. one that does not fall into the categories defined by media | ||
| 1074 | ; bytes F8H, F9H, FCH-FFH. | ||
| 1075 | |||
| 1076 | JE HEAD_2_DRV | ||
| 1077 | MOV AL, 1 ;1 sector/cluster | ||
| 1078 | MOV BL, BYTE PTR [DI].Rmediad | ||
| 1079 | CMP BYTE PTR [DI].FormFactor, ffOther | ||
| 1080 | JE GOT_CORRECT_MEDIAD | ||
| 1081 | MOV CH, BYTE PTR [DI].FormFactor | ||
| 1082 | CMP CH, ff48tpi | ||
| 1083 | JE SINGLE_MEDIAD | ||
| 1084 | MOV BL, 0F0h | ||
| 1085 | JMP GOT_CORRECT_MEDIAD | ||
| 1086 | Set_All_Done_BRG:jmp Set_All_Done | ||
| 1087 | SINGLE_MEDIAD: | ||
| 1088 | CMP WORD PTR [DI].RSecLim, 8 ;8 SEC/TRACK? | ||
| 1089 | JNE SINGLE_9_SEC | ||
| 1090 | MOV BL, 0FEh | ||
| 1091 | JMP GOT_CORRECT_MEDIAD | ||
| 1092 | SINGLE_9_SEC: | ||
| 1093 | MOV BL, 0FCh | ||
| 1094 | JMP GOT_CORRECT_MEDIAD | ||
| 1095 | HEAD_2_DRV: | ||
| 1096 | MOV BL, 0F0h ;default 0F0h | ||
| 1097 | MOV AL, 1 ;1 sec/cluster | ||
| 1098 | CMP BYTE PTR [DI].FormFactor, ffOther | ||
| 1099 | JE GOT_CORRECT_MEDIAD | ||
| 1100 | CMP BYTE PTR [DI].FormFactor, ff48tpi | ||
| 1101 | JNE NOT_48TPI | ||
| 1102 | MOV AL, 2 | ||
| 1103 | CMP WORD PTR [DI].RSecLim, 8 ;8 SEC/TRACK? | ||
| 1104 | JNE DOUBLE_9_SEC | ||
| 1105 | MOV BL, 0FFh | ||
| 1106 | JMP GOT_CORRECT_MEDIAD | ||
| 1107 | DOUBLE_9_SEC: | ||
| 1108 | MOV BL, 0FDh | ||
| 1109 | JMP GOT_CORRECT_MEDIAD | ||
| 1110 | NOT_48TPI: | ||
| 1111 | CMP BYTE PTR [DI].FormFactor, ff96tpi | ||
| 1112 | JNE NOT_96TPI | ||
| 1113 | MOV AL, 1 ;1 sec/cluster | ||
| 1114 | MOV BL, 0F9h | ||
| 1115 | JMP GOT_CORRECT_MEDIAD | ||
| 1116 | NOT_96TPI: | ||
| 1117 | CMP BYTE PTR [DI].FormFactor, ffSmall ;3-1/2, 720kb | ||
| 1118 | JNE GOT_CORRECT_MEDIAD ;Not ffSmall. Strange Media device. | ||
| 1119 | MOV AL, 2 ;2 sec/cluster | ||
| 1120 | MOV BL, 0F9h | ||
| 1121 | |||
| 1122 | ;J.K. 12/9/86 THE ABOVE IS A QUICK FIX FOR 3.3 DRIVER.SYS PROB. OLD LOGIC IS COMMENTED OUT. | ||
| 1123 | ; mov bl,0F0H ; assume strange media | ||
| 1124 | ; mov al,1 ; AL is sectors/cluster - match 3.3 bio dcl. 6/27/86 | ||
| 1125 | ; ja Got_Correct_Mediad | ||
| 1126 | ;; We check to see if the form factor specified was "other" | ||
| 1127 | ; cmp byte ptr [di].FormFactor,ffOther | ||
| 1128 | ; jz Got_Correct_Mediad | ||
| 1129 | ;; We must have 1 or 2 heads (0 is ignored) | ||
| 1130 | ; mov bl,byte ptr [di].Rmediad | ||
| 1131 | ; cmp cl,1 | ||
| 1132 | ; jz Got_Correct_Mediad | ||
| 1133 | ;; We must have one head - OK for 48tpi media | ||
| 1134 | ; mov al,1 ; AL is sectors/cluster | ||
| 1135 | ; mov ch,byte ptr [di].FormFactor | ||
| 1136 | ; cmp ch,ff48tpi | ||
| 1137 | ; jz Dec_Mediad | ||
| 1138 | ; mov bl,0F0H | ||
| 1139 | ; jmp short Got_Correct_Mediad | ||
| 1140 | ;Dec_Mediad: | ||
| 1141 | ; dec bl ; adjust for one head | ||
| 1142 | ;J.K. END OF OLD LOGIC | ||
| 1143 | |||
| 1144 | Got_Correct_Mediad: | ||
| 1145 | mov byte ptr [di].RSecPerClus,al | ||
| 1146 | mov byte ptr [di].Rmediad,bl | ||
| 1147 | ; Calculate the correct number of Total Sectors on medium | ||
| 1148 | mov ax,word ptr [di].Ccyln | ||
| 1149 | mov bx,word ptr [di].RHdLim | ||
| 1150 | mul bx | ||
| 1151 | mov bx,word ptr [di].RSecLim | ||
| 1152 | mul bx | ||
| 1153 | ; AX contains the total number of sectors on the disk | ||
| 1154 | mov word ptr [di].RDrvLim,ax | ||
| 1155 | ;J.K. For ffOther type of media, we should set Sec/FAT, and # of Root directory | ||
| 1156 | ;J.K. accordingly. | ||
| 1157 | cmp byte ptr [di].FormFactor, ffOther ;AN005; | ||
| 1158 | jne Set_All_Ok ;AN005; | ||
| 1159 | xor dx, dx ;AN005; | ||
| 1160 | dec ax ;AN005; DrvLim - 1. | ||
| 1161 | mov bx, 3 ;AN005; Assume 12 bit fat. | ||
| 1162 | mul bx ;AN005; = 1.5 byte | ||
| 1163 | mov bx, 2 ;AN005; | ||
| 1164 | div bx ;AN005; | ||
| 1165 | xor dx, dx ;AN005; | ||
| 1166 | mov bx, 512 ;AN005; | ||
| 1167 | div bx ;AN005; | ||
| 1168 | inc ax ;AN005; | ||
| 1169 | mov [di].RCSecFat, ax ;AN005; | ||
| 1170 | mov [di].RCDir, 0E0h ;AN005; directory entry # = 224 | ||
| 1171 | Set_All_Ok: ;AN005; | ||
| 1172 | clc | ||
| 1173 | Set_All_Done: | ||
| 1174 | RET | ||
| 1175 | |||
| 1176 | ; | ||
| 1177 | ; Handle_Switches replaces the values that were entered on the command line in | ||
| 1178 | ; config.sys into the recommended BPB area in the BDS. | ||
| 1179 | ; NOTE: | ||
| 1180 | ; No checking is done for a valid BPB here. | ||
| 1181 | ; | ||
| 1182 | Handle_Switches: | ||
| 1183 | call setdrive ; ds:di -> BDS | ||
| 1184 | test cs:switches,flagdrive | ||
| 1185 | jz done_handle ; if drive not specified, exit | ||
| 1186 | mov al,cs:[drivenumb] | ||
| 1187 | mov byte ptr [di].DriveNum,al | ||
| 1188 | ; test cs:switches,flagcyln | ||
| 1189 | ; jz no_cyln | ||
| 1190 | mov ax,cs:[cyln] | ||
| 1191 | mov word ptr [di].cCyln,ax | ||
| 1192 | no_cyln: | ||
| 1193 | test cs:switches,flagseclim | ||
| 1194 | jz no_seclim | ||
| 1195 | mov ax,cs:[slim] | ||
| 1196 | mov word ptr [di].RSeclim,ax | ||
| 1197 | no_seclim: | ||
| 1198 | test cs:switches,flagheads | ||
| 1199 | jz done_handle | ||
| 1200 | mov ax,cs:[heads] | ||
| 1201 | mov word ptr [di].RHdlim,ax | ||
| 1202 | done_handle: | ||
| 1203 | RET | ||
| 1204 | |||
| 1205 | |||
| 1206 | Show_Message proc near | ||
| 1207 | ;In) AX = message number | ||
| 1208 | ; DS:SI -> Substitution list if necessary. | ||
| 1209 | ; CX = 0 or n depending on the substitution number | ||
| 1210 | ; DH = -1 FOR UTILITY MSG CLASS, 2 FOR PARSE ERROR | ||
| 1211 | ;Out) Message displayed using DOS function 9 with no keyboard input. | ||
| 1212 | push cs ;AN000; | ||
| 1213 | pop ds ;AN000; | ||
| 1214 | mov bx, -1 ;AN000; | ||
| 1215 | mov dl, 0 ;AN000;no input | ||
| 1216 | call SYSDISPMSG ;AN000; | ||
| 1217 | ret ;AN000; | ||
| 1218 | Show_Message endp | ||
| 1219 | |||
| 1220 | ; | ||
| 1221 | ; The following are the recommended BPBs for the media that we know of so | ||
| 1222 | ; far. | ||
| 1223 | |||
| 1224 | ; 48 tpi diskettes | ||
| 1225 | |||
| 1226 | BPB48T DW 512 | ||
| 1227 | DB 2 | ||
| 1228 | DW 1 | ||
| 1229 | DB 2 | ||
| 1230 | DW 112 | ||
| 1231 | DW 2*9*40 | ||
| 1232 | DB 0FDH | ||
| 1233 | DW 2 | ||
| 1234 | DW 9 | ||
| 1235 | DW 2 | ||
| 1236 | DW 0 | ||
| 1237 | |||
| 1238 | ; 96tpi diskettes | ||
| 1239 | |||
| 1240 | BPB96T DW 512 | ||
| 1241 | DB 1 | ||
| 1242 | DW 1 | ||
| 1243 | DB 2 | ||
| 1244 | DW 224 | ||
| 1245 | DW 2*15*80 | ||
| 1246 | DB 0F9H | ||
| 1247 | DW 7 | ||
| 1248 | DW 15 | ||
| 1249 | DW 2 | ||
| 1250 | DW 0 | ||
| 1251 | |||
| 1252 | BPBSIZ = $-BPB96T | ||
| 1253 | |||
| 1254 | ; 3 1/2 inch diskette BPB | ||
| 1255 | |||
| 1256 | BPB35 DW 512 | ||
| 1257 | DB 2 | ||
| 1258 | DW 1 ; Double sided with 9 sec/trk | ||
| 1259 | DB 2 | ||
| 1260 | DW 70h | ||
| 1261 | DW 2*9*80 | ||
| 1262 | DB 0F9H | ||
| 1263 | DW 3 | ||
| 1264 | DW 9 | ||
| 1265 | DW 2 | ||
| 1266 | DW 0 | ||
| 1267 | |||
| 1268 | |||
| 1269 | BPBTable dw BPB48T ; 48tpi drives | ||
| 1270 | dw BPB96T ; 96tpi drives | ||
| 1271 | dw BPB35 ; 3.5" drives | ||
| 1272 | ; The following are not supported, so we default to 3.5" layout | ||
| 1273 | dw BPB35 ; Not used - 8" drives | ||
| 1274 | dw BPB35 ; Not Used - 8" drives | ||
| 1275 | dw BPB35 ; Not Used - hard files | ||
| 1276 | dw BPB35 ; Not Used - tape drives | ||
| 1277 | dw BPB35 ; Not Used - Other | ||
| 1278 | |||
| 1279 | switchlist db 7,"FHSTDCN" ; Preserve the positions of N and C. | ||
| 1280 | |||
| 1281 | ; The following depend on the positions of the various letters in SwitchList | ||
| 1282 | |||
| 1283 | flagdrive equ 0004H | ||
| 1284 | flagcyln equ 0008H | ||
| 1285 | flagseclim equ 0010H | ||
| 1286 | flagheads equ 0020H | ||
| 1287 | flagff equ 0040H | ||
| 1288 | |||
| 1289 | ;AN000; | ||
| 1290 | ;Equates for message number | ||
| 1291 | NODRIVE_MSG_NUM equ 2 | ||
| 1292 | LOADOK_MSG_NUM equ 3 | ||
| 1293 | |||
| 1294 | code ends | ||
| 1295 | |||
| 1296 | end | ||