]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DEV/DRIVER/DRIVER.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DEV / DRIVER / DRIVER.ASM
1 PAGE 64,132 ;\ f
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