summaryrefslogtreecommitdiff
path: root/v4.0/src/DEV/DRIVER
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/DEV/DRIVER')
-rw-r--r--v4.0/src/DEV/DRIVER/DRIVER.ASM1296
-rw-r--r--v4.0/src/DEV/DRIVER/DRIVER.LNK3
-rw-r--r--v4.0/src/DEV/DRIVER/DRIVER.MAK19
-rw-r--r--v4.0/src/DEV/DRIVER/DRIVER.SKL21
-rw-r--r--v4.0/src/DEV/DRIVER/MAKEFILE23
5 files changed, 1362 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
29code segment byte public
30assume cs:code,ds:code,es:code
31
32;AN000;
33.xlist
34include SYSMSG.INC ;equates and macros
35.list
36MSG_UTILNAME <DRIVER>
37
38iTEST = 0
39;---------------------------------------------------
40;
41; Device entry point
42;
43DSKDEV 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
48DRVMAX DB 1
49
50;
51; Various equates
52;
53CMDLEN equ 0 ;LENGTH OF THIS COMMAND
54UNIT equ 1 ;SUB UNIT SPECIFIER
55CMD equ 2 ;COMMAND CODE
56STATUS equ 3 ;STATUS
57MEDIA equ 13 ;MEDIA DESCRIPTOR
58TRANS equ 14 ;TRANSFER ADDRESS
59COUNT equ 18 ;COUNT OF BLOCKS OR CHARACTERS
60START equ 20 ;FIRST BLOCK TO TRANSFER
61EXTRA equ 22 ;Usually a pointer to Vol Id for error 15
62CONFIG_ERRMSG equ 23 ;AN009; To set this field to Non-zero
63 ; to display "Error in CONFIG.SYS..."
64
65PTRSAV DD 0
66
67
68STRATP PROC FAR
69
70STRATEGY:
71 MOV WORD PTR CS:[PTRSAV],BX
72 MOV WORD PTR CS:[PTRSAV+2],ES
73 RET
74
75STRATP ENDP
76
77DSK$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
86not_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
103exitp proc far
104DOS_Exit:
105 pop ax
106 POP BX
107 POP ES
108 RET ;RESTORE REGS AND RETURN
109EXITP ENDP
110
111include msbds.inc ; include BDS structures
112;include versiona.inc
113
114BDS DW -1 ;Link to next structure
115 DW -1
116 DB 1 ;Int 13 Drive Number
117 DB 3 ;Logical Drive Letter
118FDRIVE:
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
134OPCNT1 DW 0 ;Open Ref. Count
135 DB 2 ;Form factor
136FLAGS1 DW 0020H ;Various flags
137 DW 80 ;Number of cylinders in device
138RecBPB1 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;
153TRACK1 DB -1 ;Last track accessed on this drive
154TIM_LO1 DW -1 ;Keep these two contiguous (?)
155TIM_HI1 DW -1
156VOLID1 DB "NO NAME ",0 ;Volume ID for this disk
157VOLSER dd 0 ;AN000;
158FILE_ID db "FAT12 ",0 ;AN000;
159
160DOS_Drive_Letter db ? ; Logical drive associated with this unit
161
162ENDCODE LABEL WORD ; Everything below this is thrown away
163 ; after initialisation.
164
165DskDrv dw offset FDRIVE ; "array" of BPBs
166
167;AN000; For system parser;
168
169FarSW equ 0 ; Near call expected
170
171DateSW equ 0 ; Check date format
172
173TimeSW equ 0 ; Check time format
174
175FileSW equ 0 ; Check file specification
176
177CAPSW equ 0 ; Perform CAPS if specified
178
179CmpxSW equ 0 ; Check complex list
180
181NumSW equ 1 ; Check numeric value
182
183KeySW equ 0 ; Support keywords
184
185SwSW equ 1 ; Support switches
186
187Val1SW equ 1 ; Support value definition 1
188
189Val2SW equ 1 ; Support value definition 2
190
191Val3SW equ 0 ; Support value definition 3
192
193DrvSW equ 0 ; Support drive only format
194
195QusSW equ 0 ; Support quoted string format
196;---------------------------------------------------
197;.xlist
198assume ds:nothing ;AN007;!!!Parse.ASM sometimes assumes DS
199 ; to access its own variable!!!
200 include PARSE.ASM ;together with PSDATA.INC
201assume ds:code ;AN007;
202;.list
203;Control block definitions for PARSER.
204;---------------------------------------------------
205Parms label byte
206 dw Parmsx ;AN000;
207 db 0 ;AN000;No extras
208
209Parmsx 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
219D_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
225Switch_D label byte ;AN000;
226 db '/D',0 ;AN000;
227
228D_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
235Result_Val label byte ;AN000;
236 db ? ;AN000;
237Item_Tag label byte ;AN000;
238 db ? ;AN000;
239Synonym_ptr label word ;AN000;
240 dw ? ;AN000;es:offset -> found Synonym
241RV_Byte label byte ;AN000;
242RV_Word label word ;AN000;
243RV_Dword label dword ;AN000;
244 dd ? ;AN000;value if number, or seg:off to string
245
246T_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
252Switch_T label byte ;AN000;
253 db '/T',0 ;AN000;
254
255T_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
261HS_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
267Switch_H label byte ;AN000;
268 db '/H',0 ;AN000;
269Switch_S label byte ;AN000;
270 db '/S',0 ;AN000;
271
272HS_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
278CN_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;
285Switch_C label byte ;AN000;
286 db '/C',0 ;AN000;
287;Switch_N label byte ;AN000;
288; db '/N',0 ;AN000;
289
290Noval db 0 ;AN000;
291
292F_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
298Switch_F label byte ;AN000;
299 db '/F',0 ;AN000;
300
301F_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
305F_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
319MSG_SERVICES <MSGDATA>
320
321;AN000;Place the messages here
322MSG_SERVICES <DRIVER.CL1, DRIVER.CL2, DRIVER.CLA>
323
324;AN000;Put messages handler code here.
325MSG_SERVICES <LOADmsg,DISPLAYmsg,CHARmsg>
326.xall
327
328;
329; Sets ds:di -> BDS for this drive
330;
331SetDrive:
332 push cs
333 pop ds
334 mov di,offset BDS
335 ret
336
337;
338; Place for DSK$INIT to exit
339;
340ERR$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
347Public EXIT
348EXIT: MOV AH,00000001B
349ERR1: LDS BX,CS:[PTRSAV]
350 MOV WORD PTR [BX].STATUS,AX ;MARK OPERATION COMPLETE
351
352RestoreRegsAndReturn:
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
363drivenumb db 5
364cyln dw 80
365heads dw 2
366ffactor db 2
367slim dw 9
368
369Switches dw 0
370
371Drive_Let_Sublist label dword
372 db 11 ;AN000;length of this table
373 db 0 ;AN000;reserved
374 dw D_Letter;AN000;
375D_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
382D_Letter db "A"
383
384if iTEST
385Message:
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
395extrn nodrive:byte,loadokmsg:byte,letter:byte, badvermsg:byte
396endif
397
398
399if iTEST
400%OUT Testing On
401initmsg db "Initializing device driver",13,10,"$"
402stratmsg db "In strategy of driver",10,13,"$"
403dskinmsg db "In DSKIN part of driver",10,13,"$"
404outinitmsg db "Out of init code ",10,13,"$"
405exitmsg db "Exiting from driver",10,13,"$"
406parsemsg db "Parsing switches",10,13,"$"
407errmsg db "Error occurred",10,13,"$"
408linemsg db "Parsed line",10,13,"$"
409int2fokmsg db "****************Int2f loaded**************",10,13,"$"
410mediamsg db "Media check ok",10,13,"$"
411getbpbmsg db "getbpb ok",10,13,"$"
412iookmsg db "Successful I/O",10,13,"$"
413parseokmsg db "Parsing done fine",10,13,"$"
414nummsg db "Number read is "
415number db "00 ",10,13,"$"
416drvmsg db "Process drive "
417driven db "0",10,13,"$"
418cylnmsg db "Process cylinder ",10,13,"$"
419slimmsg db "Process sec/trk ",10,13,"$"
420hdmsg db "Process head "
421hdnum db "0",10,13,"$"
422ffmsg db "Process form factor "
423ffnum db "0",10,13,"$"
424nxtmsg db "Next switch ",10,13,"$"
425msg48tpi db "Got a 48 tpi drive",10,13,"$"
426
427ENDIF
428
429DSK$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
479GoodVer:
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
532err$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.
539Skip_Over_Name:
540 call scanblanks
541loop_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
549End_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
625ParseLine 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
662SysP_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;
672SysP_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;
682SysP_Fail: ;AN000;
683 mov dh, 2 ;AN000; parse error
684 mov cx, 0 ;AN000;
685 call Show_Message ;AN000; Show parse error
686SysP_Err: ;AN003;
687 stc ;AN000;
688 jmp short PL_Ret ;AN000;
689SysP_Ok: ;AN000;
690 clc ;AN000;
691PL_Ret: ;AN000;
692 pop di ;AN000;restore BDS pointer
693 ret ;AN000;
694ParseLine endp
695
696;
697Get_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;
746Stch_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;
753Stch_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;
760Stch_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;
767Stch_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;
778Stch_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;
793GR_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;
801GR_Not_Found_Ret:
802 pop ax ;AN006;adjust stack
803GR_Done_Ret:
804 ret ;AN000;
805Get_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;
812ScanBlanks:
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;
1006SetDrvParms:
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
1015formfcont:
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
1041IF iTEST
1042 mov dx,offset msg48tpi
1043 call message
1044ENDIF
1045 mov cx,40
1046 mov cs:[cyln],cx
1047Got_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
1051Set_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
1086Set_All_Done_BRG:jmp Set_All_Done
1087SINGLE_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
1092SINGLE_9_SEC:
1093 MOV BL, 0FCh
1094 JMP GOT_CORRECT_MEDIAD
1095HEAD_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
1107DOUBLE_9_SEC:
1108 MOV BL, 0FDh
1109 JMP GOT_CORRECT_MEDIAD
1110NOT_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
1116NOT_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
1144Got_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
1171Set_All_Ok: ;AN005;
1172 clc
1173Set_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;
1182Handle_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
1192no_cyln:
1193 test cs:switches,flagseclim
1194 jz no_seclim
1195 mov ax,cs:[slim]
1196 mov word ptr [di].RSeclim,ax
1197no_seclim:
1198 test cs:switches,flagheads
1199 jz done_handle
1200 mov ax,cs:[heads]
1201 mov word ptr [di].RHdlim,ax
1202done_handle:
1203 RET
1204
1205
1206Show_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;
1218Show_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
1226BPB48T 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
1240BPB96T 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
1252BPBSIZ = $-BPB96T
1253
1254; 3 1/2 inch diskette BPB
1255
1256BPB35 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
1269BPBTable 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
1279switchlist 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
1283flagdrive equ 0004H
1284flagcyln equ 0008H
1285flagseclim equ 0010H
1286flagheads equ 0020H
1287flagff equ 0040H
1288
1289;AN000;
1290;Equates for message number
1291NODRIVE_MSG_NUM equ 2
1292LOADOK_MSG_NUM equ 3
1293
1294code ends
1295
1296end
diff --git a/v4.0/src/DEV/DRIVER/DRIVER.LNK b/v4.0/src/DEV/DRIVER/DRIVER.LNK
new file mode 100644
index 0000000..6dbd484
--- /dev/null
+++ b/v4.0/src/DEV/DRIVER/DRIVER.LNK
@@ -0,0 +1,3 @@
1DRIVER.OBJ
2DRIVER.EXE;
3 \ No newline at end of file
diff --git a/v4.0/src/DEV/DRIVER/DRIVER.MAK b/v4.0/src/DEV/DRIVER/DRIVER.MAK
new file mode 100644
index 0000000..8748f44
--- /dev/null
+++ b/v4.0/src/DEV/DRIVER/DRIVER.MAK
@@ -0,0 +1,19 @@
1COM=..\COMMON
2MSG=..\MESSAGES
3country=usa
4
5
6DRIVER.CTL: DRIVER.SKL $(MSG)\$(COUNTRY).MSG
7 MSGBUILD DRIVER.SKL
8
9DRIVER.OBJ: DRIVER.ASM $(COM)\IBMBDS.INC $(COM)\VERSIONA.INC \
10 $(COM)\PARSE.ASM $(COM)\PSDATA.INC \
11 DRIVER.CTL $(COM)\SYSMSG.INC $(COM)\MSGSERV.ASM
12 ASM87 DRIVER
13
14DRIVER.SYS: DRIVER.OBJ $(COM)\setver.bat DRIVER.ARF
15 LINK @DRIVER.ARF
16 EXE2BIN DRIVER.EXE DRIVER.SYS
17 TAG DRIVER.SYS
18 DEL DRIVER.EXE
19 \ No newline at end of file
diff --git a/v4.0/src/DEV/DRIVER/DRIVER.SKL b/v4.0/src/DEV/DRIVER/DRIVER.SKL
new file mode 100644
index 0000000..4fb910f
--- /dev/null
+++ b/v4.0/src/DEV/DRIVER/DRIVER.SKL
@@ -0,0 +1,21 @@
1;================================================
2; DRIVER.SYS Message Skeleton File
3;================================================
4
5:util DRIVER
6:class 2
7:use PARSE1
8:use PARSE2
9:use PARSE3
10:use PARSE4
11:use PARSE6
12:use PARSE7
13:use PARSE8
14
15:class A
16:use 1 COMMON1 ;"Incorrect DOS version"
17:def 2 "No Drive Specified",CR,LF,"$"
18:def 3 "Loaded External Disk Driver for Drive %1",CR,LF,"$"
19
20:end
21 \ No newline at end of file
diff --git a/v4.0/src/DEV/DRIVER/MAKEFILE b/v4.0/src/DEV/DRIVER/MAKEFILE
new file mode 100644
index 0000000..5f382d6
--- /dev/null
+++ b/v4.0/src/DEV/DRIVER/MAKEFILE
@@ -0,0 +1,23 @@
1#************************ makefile for dev\driver ************************
2
3msg =..\..\messages
4dos =..\..\dos
5inc =..\..\inc
6hinc =..\..\h
7
8#
9####################### dependencies begin here. #########################
10#
11
12all: driver.sys
13
14driver.ctl: driver.skl $(msg)\$(COUNTRY).msg
15
16driver.obj: driver.asm $(inc)\msbds.inc $(inc)\versiona.inc \
17 $(inc)\parse.asm $(inc)\psdata.inc \
18 driver.ctl $(inc)\sysmsg.inc $(inc)\msgserv.asm
19
20driver.sys: driver.obj driver.lnk
21 link @driver.lnk
22 exe2bin driver.exe driver.sys
23 del driver.exe