2 ; SCCSID = @(#)sysinit2.asm 1.13 85/10/15
3 TITLE BIOS SYSTEM INITIALIZATION
6 ;==============================================================================
8 ;AN000 - New for DOS Version 4.00 - J.K.
9 ;AC000 - Changed for DOS Version 4.00 - J.K.
10 ;AN00x - PTM number for DOS Version 4.00 - J.K.
11 ;==============================================================================
12 ;AN001; p132 Multiple character device installation problem. 6/27/87 J.K.
13 ;AN002; d24 MultiTrack= command added. 6/29/87 J.K.
14 ;AN003; p29 Extra space character in parameters passed.
15 ; (Modification on ORGANIZE routine for COMMENT= fixed this
16 ; problem too) 6/29/87 J.K.
17 ;AN004; d41 REM command in CONFIG.SYS 7/7/87 J.K.
18 ;AN005; d184 Set DEVMARK for MEM command 8/25/87 J.K.
19 ;AN006; p1820 New Message SKL file 10/20/87 J.K.
20 ;AN007; p1821 Include the COPYRIGH.INC file 10/22/87 J.K.
21 ;AN008; p2210 IBMDOS returns incorrect DBCS vector table length 11/02/87 J.K.
22 ;AN009; p2667 ccMono_Ptr problem 11/30/87 J.K.
23 ;AN010; p2792 Device?driver.sys /d:2 command should not work 12/09/87 J.K.
24 ;AN011; p3120 REM followed by CR, LF causes problem 01/13/88 J.K.
25 ;AN012; p3111 Take out the order dependency of the INSTALL= 01/25/88 J.K.
26 ;AN013; d479 New option to disable extended INT 16h function call 02/12/88 J.K.
27 ;AN014; D486 SHARE installation for big media 02/23/88 J.K.
28 ;AN015; D526 Add /NC parameter when installing SHARE.EXE 04/28/88 J.K.
29 ;==============================================================================
39 STACKSW EQU TRUE
;Include Switchable Hardware Stacks
40 IBMJAPVER EQU FALSE
;If TRUE set KANJI true also
42 ALTVECT EQU FALSE
;Switch to build ALTVECT version
55 include smdossym
.inc ;J.K. Reduced version of DOSSYM.INC
67 code segment public 'code'
71 SYSINITSEG
SEGMENT PUBLIC 'SYSTEM_INIT' BYTE
73 ASSUME
CS:SYSINITSEG
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
75 EXTRN BADOPM
:BYTE,CRLFM
:BYTE,BADCOM
:BYTE,BADMEM
:BYTE,BADBLOCK
:BYTE
76 EXTRN BADSIZ_PRE
:BYTE,BADLD_PRE
:BYTE
77 ; EXTRN BADSIZ_POST:BYTE,BADLD_POST:BYTE
78 EXTRN SYSSIZE
:BYTE,BADCOUNTRY
:BYTE
80 EXTRN dosinfo
:dword,entry_point
:dword,
81 EXTRN MEMORY_SIZE
:WORD,fcbs
:byte,keep
:byte
82 EXTRN DEFAULT_DRIVE
:BYTE,confbot
:word,alloclim
:word
83 EXTRN BUFFERS
:WORD,zero
:byte,sepchr
:byte
85 EXTRN count
:word,chrptr
:word
86 EXTRN bufptr
:byte,memlo
:word,prmblk
:byte,memhi
:word
87 EXTRN ldoff
:word,area
:word,PACKET
:BYTE,UNITCOUNT
:BYTE,
88 EXTRN BREAK_ADDR
:DWORD,BPB_ADDR
:DWORD,drivenumber
:byte
89 extrn COM_Level
:byte, CMMT
:byte, CMMT1
:byte, CMMT2
:byte
90 extrn Cmd_Indicator
:byte
91 extrn DoNotShowNum
:byte
92 extrn MultDeviceFlag
:byte
93 extrn DevMark_Addr
:word ;AN005;
94 extrn SetDevMarkFlag
:byte ;AN005;
95 extrn Org_Count
:word ;AN012;
100 PUBLIC Int24
,Open_Dev
,Organize
,Mem_Err
,Newline
,CallDev
,Badload
101 PUBLIC PrnDev
,AuxDev
,Config
,Commnd
,Condev
,GetNum
,BadFil
,PrnErr
102 PUBLIC Round
,Delim
,Print
,Set_Break
103 PUBLIC SetParms
, ParseLine
, DiddleBack
104 PUBLIC Skip_delim
,SetDOSCountryInfo
,Set_Country_Path
,Move_Asciiz
105 PUBLIC Cntry_Drv
,Cntry_Root
,Cntry_Path
107 public PathString
;AN014;
108 public LShare
;AN014;
111 ; The following set of routines is used to parse the DRIVPARM = command in
112 ; the CONFIG.SYS file to change the default drive parameters.
124 mov bl,byte ptr drive
125 inc bl ; get it correct for IOCTL call (1=A,2=B...)
126 mov dx,offset DeviceParameters
128 mov al, GENERIC_IOCTL
130 mov cl, SET_DEVICE_PARAMETERS
132 test word ptr Switches
, flagec35
135 mov cl, byte ptr drive
; which drive was this for?
136 mov ax, Code ; get Code segment
137 mov ds, ax ; set code segment
139 mov al, 1 ; assume drive 0
140 shl al, cl ; set proper bit depending on drive
141 or ds:EC35_Flag
, al ; set the bit in the permanent flags
144 pop dx ; fix up all the registers
153 ; Replace default values for further DRIVPARM commands
160 mov word ptr DeviceParameters
.DP_Cylinders
,80
161 mov byte ptr DeviceParameters
.DP_DeviceType
, DEV_3INCH720KB
162 mov word ptr DeviceParameters
.DP_DeviceAttributes
,0
163 mov word ptr switches
,0 ; zero all switches
169 ; Entry point is ParseLine. AL contains the first character in command line.
171 ParseLine: ; don't get character first time
177 cmp al,CR
; carriage return?
179 cmp al,LF
; linefeed?
180 jz put_back
; put it back and done
181 ; Anything less or equal to a space is ignored.
183 jbe get_next
; skip over space
186 stc ; mark error invalid-character-in-input
191 mov word ptr Switches
,BX ; save switches read so far
198 jmp exitpl
; exit if error
201 test word ptr Switches
,flagdrive
; see if drive specified
203 stc ; mark error no-drive-specified
207 mov ax,word ptr switches
208 and ax,0003H ; get flag bits for changeline and non-rem
209 mov word ptr DeviceParameters
.DP_DeviceAttributes
,ax
210 mov word ptr DeviceParameters
.DP_TrackTableEntries
, 0
211 clc ; everything is fine
212 call SetDeviceParameters
218 inc count
; one more char to scan
219 dec chrptr
; back up over linefeed
222 ; Processes a switch in the input. It ensures that the switch is valid, and
223 ; gets the number, if any required, following the switch. The switch and the
224 ; number *must* be separated by a colon. Carry is set if there is any kind of
230 and al,0DFH ; convert it to upper case
238 mov cl,byte ptr switchlist
; get number of valid switches
240 mov di,1+offset switchlist
; point to string of valid switches
245 shl ax,cl ; set bit to indicate switch
246 mov bx,word ptr switches
; get switches so far
247 or bx,ax ; save this with other switches
249 test ax, switchnum
; test against switches that require number to follow
256 push bx ; preserve switches
257 mov byte ptr cs:sepchr
,' ' ; allow space separators
259 mov byte ptr cs:sepchr
,0
260 pop bx ; restore switches
261 ; Because GetNum does not consider carriage-return or line-feed as OK, we do
262 ; not check for carry set here. If there is an error, it will be detected
263 ; further on (hopefully).
271 xor bx,cx ; remove this switch from the records
277 ; This routine takes the switch just input, and the number following (if any),
278 ; and sets the value in the appropriate variable. If the number input is zero
279 ; then it does nothing - it assumes the default value that is present in the
280 ; variable at the beginning. Zero is OK for form factor and drive, however.
283 test word ptr Switches
,cx ; if this switch has been done before,
284 jnz done_ret
; ignore this one.
287 mov byte ptr drive
,al
293 ; Ensure that we do not get bogus form factors that are not supported
296 mov byte ptr DeviceParameters
.DP_DeviceType
,al
301 jz done_ret
; if number entered was 0, assume default value
304 mov word ptr DeviceParameters
.DP_Cylinders
,ax
313 ; Must be for number of heads
322 ; SetDeviceParameters sets up the recommended BPB in each BDS in the
323 ; system based on the form factor. It is assumed that the BPBs for the
324 ; various form factors are present in the BPBTable. For hard files,
325 ; the Recommended BPB is the same as the BPB on the drive.
326 ; No attempt is made to preserve registers since we are going to jump to
327 ; SYSINIT straight after this routine.
335 mov bl,byte ptr DeviceParameters
.DP_DeviceType
338 mov cx,40 ; 48tpi has 40 cylinders
339 mov word ptr DeviceParameters
.DP_Cylinders
,cx
341 shl bx,1 ; get index into BPB table
342 mov si,offset BPBTable
343 mov si,word ptr [si+bx] ; get address of BPB
345 mov di,offset DeviceParameters
.DP_BPB
; es:di -> BPB
351 test word ptr switches
,flagseclim
354 mov word ptr DeviceParameters
.DP_BPB
.BPB_SectorsPerTrack
,ax
356 test word ptr switches
,flagheads
359 mov word ptr DeviceParameters
.DP_BPB
.BPB_Heads
,ax
361 ; We need to set the media byte and the total number of sectors to reflect the
362 ; number of heads. We do this by multiplying the number of heads by the number
363 ; of 'sectors per head'. This is not a fool-proof scheme!!
365 mov cx,ax ; cx has number of heads
366 dec cl ; get it 0-based
367 mov ax,DeviceParameters
.DP_BPB
.BPB_TotalSectors
; this is OK for two heads
368 sar ax,1 ; ax contains # of sectors/head
370 jc Set_All_Done
; We have too many sectors - overflow!!
371 mov DeviceParameters
.DP_BPB
.BPB_TotalSectors
,ax
372 ; Set up correct Media Descriptor Byte
375 mov al,2 ; AL contains sectors/cluster
376 ja Got_Correct_Mediad
377 mov bl,byte ptr DeviceParameters
.DP_BPB
.BPB_MediaDescriptor
378 je Got_Correct_Mediad
379 ; We have one head - OK for 48tpi medium
380 mov al,1 ; AL contains sectors/cluster
381 mov ch,DeviceParameters
.DP_DeviceType
385 jmp short Got_Correct_Mediad
387 dec bl ; adjust for one head
389 mov byte ptr DeviceParameters
.DP_BPB
.BPB_MediaDescriptor
,bl
390 mov byte ptr DeviceParameters
.DP_BPB
.BPB_SectorsPerCluster
,al
395 ASSUME
DS:NOTHING
, ES:NOTHING
409 ;ORG1: CALL GET ;SKIP LEADING CONTROL CHARACTERS
413 call Skip_Comment
;AN000;
414 jz End_Commd_Line
;AN000; found a comment string and skipped.
415 call Get2
;AN000; Not a comment string. Then get a char.
417 je End_Commd_Line
;AN000; starts with a blank line.
419 jbe Org1
;AN000; skip leading control characters
421 End_Commd_Line: ;AN000;
422 stosb ;AN000; store line feed char in buffer for the LineCount.
423 mov COM_Level
, 0 ;AN000; reset the command level.
431 MOV SI,OFFSET COMTAB
;Prepare to search command table
440 ADD SI,CX ;Bump to next position without affecting flags
442 LODSB ;Get indicator letter
444 cmp byte ptr es:[di], CR
;AN011;The next char might be CR,LF
445 je GotCom0
;AN011; such as in "REM",CR,LF case.
446 cmp byte ptr es:[di], LF
;AN011;
449 mov al, byte ptr es:[di] ;AN010;Now the next char. should be a delim.
464 stosb ;AN000; save indicator char.
467 cmp al, LF
;AN000; skip this bad command line
468 jne Skip_Line
;AN000;
469 jmp End_Commd_Line
;AN000; handle next command line
471 GOTCOM: STOSB ;SAVE INDICATOR CHAR IN BUFFER
472 mov Cmd_Indicator
, al ;AN000; save it for the future use.
474 ORG2: CALL GET2
;SKIP the commad name UNTIL DELIMITER
481 jmp short Org3
;AN011;
482 Org21: ;AN011;if CR or LF then
483 dec si ;AN011; undo SI, CX register
484 inc cx ;AN011; and continue
487 ; call Delim ;J.K. 5/30/86. To permit "device=filename/p..." stuff.
488 ; jz ORG_EXT ;J.K. 5/30/86
496 ; MOV BYTE PTR ES:[DI-1],0
499 cmp Cmd_Indicator
, 'Y' ;AN000; Comment= command?
500 je Get_Cmt_Token
;AN000;
501 cmp Cmd_Indicator
, 'I' ;AN000; Install= command?
503 cmp Cmd_Indicator
, 'D' ;AN000; Device= command?
505 cmp Cmd_Indicator
, 'J' ;AN000; IFS= command?
507 cmp Cmd_Indicator
, 'S' ;AN000; Shell= is a special one!!!
509 cmp Cmd_Indicator
, '1' ;AN013; SWITCHES= command?
510 je Org_Switch
;AN013;
513 call Skip_Comment
;AN013;
514 jz End_Commd_Line_Brdg
;AN013;
516 call Org_Delim
;AN013;
517 jz Org_Switch
;AN013;
520 Org_file: ;AN000; Get the filename and put 0 at end,
521 call Skip_Comment
;AN000;
522 jz Org_Put_Zero
;AN000;
523 call Get2
;AN000; Not a comment
525 jz Org_file
;AN000; Skip the possible delimeters
526 stosb ;AN000; copy the first non delim char found in buffer
527 Org_Copy_File: ;AN000;
528 call Skip_Comment
;AN000; comment char in the filename?
529 jz Org_Put_Zero
;AN000; then stop copying filename at that point
531 cmp al, '/' ;AN000; a switch char? (device=filename/xxx)
532 je End_File_slash
;AN000; this will be the special case.
533 stosb ;AN000; save the char. in buffer
535 jz End_Copy_File
;AN000;
537 ja Org_Copy_File
;AN000; keep copying
538 jmp End_Copy_File
;AN000; otherwise, assume end of the filename.
539 Get_Cmt_token: ;AN000; get the token. Just max. 2 char.
541 cmp al, ' ' ;AN000; skip white spaces or "=" char.
542 je Get_Cmt_Token
;AN000; (we are allowing the other special
543 cmp al, TAB
;AN000; charaters can used for comment id.
544 je Get_Cmt_Token
;AN000; character.)
545 cmp al, '=' ;AN000; = is special in this case.
546 je Get_Cmt_Token
;AN000;
548 je Get_Cmt_End
;AN000; cannot accept the carridge return
550 je Get_Cmt_End
;AN000;
551 mov CMMT1
, al ;AN000; store it
552 mov CMMT
, 1 ;AN000; 1 char. so far.
555 je Get_Cmt_End
;AN000;
557 je Get_Cmt_End
;AN000;
559 je Get_Cmt_End
;AN000;
561 je End_Commd_Line_Brdg
;AN000;
562 mov CMMT2
, al ;AN000;
567 jne Get_Cmt_End
;AN000; skip it.
568 End_Commd_Line_Brdg: jmp End_Commd_Line
;AN000; else jmp to End_Commd_Line
570 Org_Put_Zero: ;AN000; Make the filename in front of
571 mov byte ptr es:[di], 0 ;AN000; the comment string to be an asciiz.
573 jmp End_Commd_Line
;AN000; (Maybe null if device=/*)
574 End_file_slash: ;AN000; AL = "/" option char.
575 mov byte ptr es:[di],0 ;AN000; make a filename an asciiz
577 stosb ;AN000; store "/" after that.
578 jmp Org5
;AN000; continue with the rest of the line
580 End_Copy_File: ;AN000;
581 mov byte ptr es:[di-1], 0 ;AN000; make it an asciiz and handle the next char.
583 je End_Commd_Line_brdg
;AN000;
586 Org4: ;AN000; Org4 skips all delimiters after the command name except for '/'
587 call Skip_Comment
;AN000;
588 jz End_Commd_Line_brdg
;AN000;
590 call Org_Delim
;AN000; skip delimiters EXCEPT '/' (mrw 4/88)
593 Org5: ;AN000; rest of the line
594 call Skip_Comment
;AN000; Comment?
595 jz End_Commd_Line_brdg
;AN000;
596 call Get2
;AN000; Not a comment.
598 stosb ;AN000; copy the character
599 cmp al, '"' ;AN000; a quote ?
603 cmp al, LF
;AN000; line feed?
604 je Org1_brdg
;AN000; handles the next command line.
605 jmp Org5
;AN000; handles next char in this line.
606 Org1_brdg: jmp Org1
;AN000;
608 cmp COM_Level
, 0 ;AN000;
610 mov COM_Level
, 0 ;AN000; reset it.
613 inc COM_level
;AN000; set it.
625 ; je Org4_Cont ;then do not make an exception. Go back.
628 ; mov byte ptr es:[di], 0 ;put 0 at the current DI to make it an ASCIIZ
630 ; stosb ;and copy the delimeter char.
631 ; jmp short ORG5 ;and continue as usual.
650 ;J.K.Skip the commented string until LF, if current es:si-> a comment string.
651 ;J.K.In) ES:SI-> sting
653 ;J.K.Out) Zero flag not set if not found a comment string.
654 ;J.K. Zero flag set if found a comment string and skipped it. AL will contain
655 ;J.K. the line feed charater at this moment when return.
656 ;J.K. AX register destroyed.
657 ;J.K. If found, SI, CX register adjusted accordingly.
659 jcxz NoGet
;AN000; Get out of the Organize routine.
660 cmp COM_Level
, 0 ;AN000; only check it if parameter level is 0.
661 jne No_Commt
;AN000; (Not inside quotations)
665 mov al, es:[si] ;AN000;
666 cmp CMMT1
, al ;AN000;
669 jne Skip_Cmmt
;AN000;
670 mov al, es:[si+1] ;AN000;
671 cmp CMMT2
, al ;AN000;
674 jcxz NoGet
;AN000; get out of Organize routine.
675 mov al, es:[si] ;AN000;
678 cmp al, LF
;AN000; line feed?
679 jne Skip_Cmmt
;AN000;
685 CMP AL,'/' ;J.K. 5/30/86. IBM will assume "/" as an delimeter.
687 cmp al, 0 ;J.K. 5/23/86 Special case for sysinit!!!
689 Org_Delim: ;AN000; Used by Organize routine except for getting
690 CMP AL,' ' ;the filename.
704 mov Org_Count
, DI ;AN012;
709 ;Get3: jcxz NOGET ;J.K.do not consider '/',',' as a delim.
725 ; NEWLINE RETURNS WITH FIRST CHARACTER OF NEXT LINE
727 NEWLINE:invoke GETCHR
;SKIP NON-CONTROL CHARACTERS
729 CMP AL,LF
;LOOK FOR LINE FEED
747 INC SI ;Skip next char
749 JCXZ CONVDONE
;Just ignore 1/2 kanji error
750 ;Fall through, know AL is not in 'a'-'z' range
794 Yes_Break_Failed: ;device driver Init failed and aborted.
800 ;J.K. 8/14/86 For DOS 3.3, this routine is modified to take care of the
801 ;Device driver's initialization error and abort.
802 ;If [break_addr+2] == [memhi] && [break_addr] = 0 then assume
803 ;that the device driver's initialization has an error and wanted to
804 ;abort the device driver. In this case, this routine will set carry
805 ;and return to the caller.
806 ;J.K. 6/26/87 If MultDeviceFlag <> 0, then do not perform the check.
807 ;This is to allow the multiple character device driver which uses
808 ;the same ending address segment with the offset value 0 for each
812 MOV AX,WORD PTR [BREAK_ADDR
+2] ;REMOVE THE INIT CODE
813 cmp MultDeviceFlag
, 0 ;AN001;
814 jne Set_Break_Continue
;AN001;Do not check it.
816 jne Set_Break_Continue
;if not same, then O.K.
818 cmp word ptr [BREAK_ADDR
],0
819 je Yes_Break_failed
;[Break_addr+2]=[MEMHI] & [Break_addr]=0
823 MOV AX,WORD PTR [BREAK_ADDR
]
825 POP AX ; NOTE FALL THROUGH
826 or [SetDevMarkFlag
], SETBRKDONE
;AN005; Signal the successful Set_break
829 ; Round the values in MEMLO and MEMHI to paragraph boundary.
830 ; Perform bounds check.
836 invoke ParaRound
; para round up
840 mov ax,memhi
; ax = new memhi
841 CMP AX,[ALLOCLIM
] ; if new memhi >= alloclim, error
843 test cs:[SetDevMarkFlag
], FOR_DEVMARK
;AN005;
844 jz Skip_Set_DEVMARKSIZE
;AN005;
847 mov si, cs:[DevMark_Addr
] ;AN005;
851 mov es:[DEVMARK_SIZE
], ax ;AN005; Paragraph
852 and cs:[SetDevMarkFlag
], NOT_FOR_DEVMARK
;AN005;
855 Skip_Set_DEVMARKSIZE: ;AN005;
867 CALLDEV:MOV DS,WORD PTR CS:[ENTRY_POINT
+2]
868 ADD BX,WORD PTR CS:[ENTRY_POINT
] ;Do a little relocation
870 PUSH WORD PTR CS:[ENTRY_POINT
]
871 MOV WORD PTR CS:[ENTRY_POINT
],AX
874 POP WORD PTR CS:[ENTRY_POINT
]
879 XOR AX,AX ; Set Zero flag, and AX = 0
894 ; GetNum parses a decimal number.
895 ; Returns it in AX, sets zero flag if AX = 0 (MAY BE considered an
896 ; error), if number is BAD carry is set, zero is set, AX=0.
897 GETNUM: push bx ; J.K.
898 XOR BX,BX ; running count is zero
899 B2: CALL ToDigit
; do we have a digit
901 XCHG AX,BX ; put total in AX
903 MOV BX,10 ; base of arithmetic
904 MUL BX ; shift by one decimal di...
905 POP BX ; get back digit
906 ADD AL,BL ; get total
907 ADC AH,0 ; make that 16 bits
908 JC BADNUM
; too big a number
909 XCHG AX,BX ; stash total
911 invoke GETCHR
;GET NEXT DIGIT
912 JC B1
; no more characters
913 cmp al, ' ' ;J.K. 5/23/86 space?
914 jz B15
;J.K. 5/23/86 then end of digits
915 cmp al, ',' ;J.K. 5/23/86 ',' is a seperator!!!
916 jz B15
;J.K. 5/23/86 then end of digits.
917 cmp al, TAB
;J.K. 5/23/86 TAB
919 CMP AL,SepChr
; allow 0 or special separators
921 cmp al,SWTCHR
; See if another switch follows
923 cmp al,LF
; Line-feed?
925 cmp al,CR
; Carriage return?
927 OR AL,AL ; end of line separator?
928 JNZ B2
; no, try as a valid char...
929 b15: INC COUNT
; one more character to s...
930 DEC CHRPTR
; back up over separator
931 B1: MOV AX,BX ; get proper count
932 OR AX,AX ; Clears carry, sets Zero accordingly
936 SKIP_DELIM proc
near ;J.K.
937 ;Skip the delimeters pointed by CHRPTR. AL will contain the first non delimeter
938 ;character encountered and CHRPTR will point to the next character.
939 ;This rouitne will assume the second "," found as a non delimiter character. So
940 ;in case if the string is " , , ", this routine will stop at the second ",". At
941 ;this time, Zero flag is set.
942 ;If COUNT is exhausted, then carry will be set.
946 cmp al, ',' ;the first comma?
948 call delim
;check the charater in AL.
950 jmp short Skip_delim_exit
;found a non delim char
954 cmp al, ',' ;the second comma?
955 je Skip_delim_exit
;done
962 ;J.K. 5/26/86 *****************************************************************
963 SetDOSCountryInfo proc
near
964 ;Input: ES:DI -> pointer to DOS_COUNTRY_CDPG_INFO
968 ; DX = code page id. (If 0, then use ccSysCodePage as a default.)
970 ; This routine can handle maxium 72 COUNTRY_DATA entries.
971 ;Output: DOS_country_cdpg_info set.
972 ; Carry set if any file read failure or wrong information in the file.
973 ; Carry set and CX = -1 if cannot find the matching COUNTRY_id, CODEPAGE
982 mov ax, 512 ;read 512 bytes
983 call ReadInControlBuffer
;Read the file header
989 mov di, offset COUNTRY_FILE_SIGNATURE
990 mov cx, 8 ;length of the signature
994 jnz SetDOSData_fail
;signature mismatch
996 add si, 18 ;SI -> county info type
997 cmp byte ptr ds:[si], 1 ;Only accept type 1 (Currently only 1 header type)
998 jne SetDOSData_fail
;cannot proceed. error return
999 inc si ;SI -> file offset
1000 mov dx, word ptr ds:[si] ;Get the INFO file offset.
1001 mov cx, word ptr ds:[si+2]
1002 mov ax, 1024 ;read 1024 bytes.
1003 call ReadInControlBuffer
;Read INFO
1005 mov cx, word ptr ds:[si] ;get the # of country, codepage combination entries
1006 cmp cx, 72 ;cannot handle more than 72 entries.
1009 inc si ;SI -> entry information packet
1010 pop dx ;restore code page id
1011 pop ax ;restore country id
1014 SetDOSCntry_find: ;Search for desired country_id,codepage_id.
1015 cmp ax, word ptr ds:[si+2] ;compare country_id
1016 jne SetDOSCntry_next
1017 cmp dx, 0 ;No user specified code page ?
1018 je SetDOSCntry_any_codepage
;then no need to match code page id.
1019 cmp dx, word ptr ds:[si+4] ;compare code page id
1020 je SetDOSCntry_got_it
1022 add si, word ptr ds:[si] ;next entry
1024 inc si ;take a word for size of entry itself
1025 loop SetDOSCntry_find
1026 mov cx, -1 ;signals that bad country id entered.
1035 jmp short SetDOSCntry_fail
1037 SetDOSCntry_any_CodePage: ;use the code_page_id of the country_id found.
1038 mov dx, word ptr ds:[si+4]
1039 SetDOSCntry_got_it: ;found the matching entry
1040 mov cs:CntryCodePage_Id
, dx ;save code page ID for this country.
1041 mov dx, word ptr ds:[si+10] ;get the file offset of country data
1042 mov cx, word ptr ds:[si+12]
1043 mov ax, 512 ;read 512 bytes
1044 call ReadInControlBuffer
1046 mov cx, word ptr ds:[si] ;get the number of entries to handle.
1048 inc si ;SI -> first entry
1051 push di ;ES:DI -> DOS_COUNTRY_CDPG_INFO
1052 push cx ;save # of entry left
1053 push si ;si -> current entry in Control buffer
1055 mov al, byte ptr ds:[si+2] ;get data entry id
1056 call GetCountryDestination
;get the address of destination in ES:DI
1057 jc SetDOSCntry_data_next
;No matching data entry id in DOS
1060 mov dx, word ptr ds:[si+4] ;get offset of data
1061 mov cx, word ptr ds:[si+6]
1064 int 21h
;move pointer
1066 mov dx, 512 ;start of data buffer
1067 ; mov cx, word ptr es:[di] ;length of the corresponding data in DOS.
1068 ; add cx, 10 ;Signature + A word for the length itself
1069 mov cx, 20 ;read 20 bytes only. We only need to
1070 mov ah, 3fh
;look at the length of the data in the file.
1072 int 21h
;read the country.sys data
1073 jc SetDOSData_fail
;read failure
1077 mov dx, word ptr ds:[si+4] ;AN008;get offset of data again.
1078 mov cx, word ptr ds:[si+6] ;AN008;
1079 mov ax, 4200h
;AN008;
1081 int 21h
;AN008;move pointer back again
1082 jc SetDOSData_fail
;AN008;
1085 mov si, (512+8) ;AN008;get length of the data from the file
1086 mov cx, word ptr ds:[si] ;AN008;
1088 mov dx, 512 ;AN008;start of data buffer
1089 add cx, 10 ;AN008;Signature + A word for the length itself
1090 mov ah, 3fh
;AN008;Read the data from the file.
1093 jc SetDOSData_fail
;AN008;
1095 jne SetDOSData_fail
;AN008;
1097 mov al, byte ptr ds:[si+2] ;save Data id for future use.
1098 mov si, (512+8) ;SI-> data buffer + id tag field
1099 mov cx, word ptr ds:[si] ;get the length of the file
1100 inc cx ;Take care of a word for lenght of tab
1102 cmp cx, (2048 - 512 - 8) ;Fit into the buffer?
1104 cmp al, SetCountryInfo
;is the data for SetCountryInfo table?
1105 jne SetDOSCntry_Mov
;no, don't worry
1106 push word ptr es:[di+ccMono_Ptr
-ccCountryInfoLen
] ;AN009;Cannot destroy ccMono_ptr address. Save them.
1107 push word ptr es:[di+ccMono_Ptr
-ccCountryInfoLen
+2] ;AN009;At this time DI -> ccCountryInfoLen
1111 mov ax,cs:CntryCodePage_Id
;Do not use the Code Page info in Country_Info
1112 mov ds:[si+4], ax ;Use the saved one for this !!!!
1116 rep movsb ;copy the table into DOS
1117 cmp al, SetCountryInfo
;was the ccMono_ptr saved?
1118 jne SetDOSCntry_data_next
1120 pop word ptr es:[di+ccMono_Ptr
-ccCountryInfoLen
+2] ;AN009;restore
1121 pop word ptr es:[di+ccMono_Ptr
-ccCountryInfoLen
] ;AN009;
1123 SetDOSCntry_data_next:
1124 pop si ;restore control buffer pointer
1125 pop cx ;restore # of entries left
1126 pop di ;restore pointer to DSO_COUNTRY_CDPG
1127 add si, word ptr ds:[si] ;try to get the next entry
1129 inc si ;take a word of entry length itself
1130 ; loop SetDOSCntry_data
1133 je SetDOSCntry_OK
;AN008;
1134 jmp SetDOSCntry_data
;AN008;
1135 SetDOSCntry_OK: ;AN008;
1137 SetDOSCountryInfo endp
1140 GetCountryDestination proc
near
1141 ;Get the destination address in the DOS country info table.
1142 ;Input: AL - Data ID
1143 ; ES:DI -> DOS_COUNTRY_CDPG_INFO
1145 ; ES:DI -> Destination address of the matching data id
1146 ; carry set if no matching data id found in DOS.
1149 add di, ccNumber_of_entries
;skip the reserved area, syscodepage etc.
1150 mov cx, word ptr es:[di] ;get the number of entries
1152 inc di ;SI -> the first start entry id
1154 cmp byte ptr es:[di], al
1156 cmp byte ptr es:[di], SetCountryInfo
;was it SetCountryInfo entry?
1158 add di, 5 ;next data id
1159 jmp short GetCntryDest_loop
1161 add di, NEW_COUNTRY_SIZE
+ 3 ;next data id
1165 jmp short GetCntryDest_exit
1167 cmp al, SetCountryInfo
;select country info?
1168 jne GetCntryDest_OK1
1169 inc di ;now DI -> ccCountryInfoLen
1170 jmp short GetCntryDest_exit
1172 les di, dword ptr es:[di+1] ;get the destination in ES:DI
1176 GetCountryDestination endp
1179 ReadInControlBuffer proc
near
1180 ;Move file pointer to CX:DX
1181 ;Read AX bytes into the control buffer. (Should be less than 2 Kb)
1182 ;SI will be set to 0 hence DS:SI points to the control buffer.
1183 ;Entry: CX,DX offset from the start of the file where the read/write pointer
1185 ; AX - # of bytes to read
1188 ;Return: The control data information is read into DS:0 - DS:0200.
1189 ; CX,DX value destroyed.
1190 ; Carry set if error in Reading file.
1192 push ax ;# of bytes to read
1195 int 21h
;move pointer
1196 pop cx ;# of bytes to read
1198 xor dx,dx ;ds:dx -> control buffer
1200 mov ah,3fh
;read into the buffer
1202 int 21h
;should be less than 1024 bytes.
1205 ReadInControlBuffer endp
1208 SET_COUNTRY_PATH proc
near
1209 ;In: DS - SYSINITSEG, ES - CONFBOT, SI -> start of the asciiz path string
1210 ; DOSINFO_EXT, CNTRY_DRV, CNTRY_ROOT, CNTRY_PATH
1211 ; Assumes current directory is the ROOT directory.
1212 ;Out: DS:DI -> full path (CNTRY_DRV).
1213 ; Set the CNTRY_DRV string from the COUNTRY=,,path command.
1214 ; DS, ES, SI value saved.
1217 push ds ;switch ds, es
1220 pop es ;now DS -> CONFBOT, ES -> SYSINITSEG
1222 call chk_drive_letter
;current DS:[SI] is a drive letter?
1223 jc SCP_Default_drv
;no, use current default drive.
1224 mov al, byte ptr DS:[SI]
1226 inc si ;SI -> next char after ":"
1227 jmp short SCP_SetDrv
1231 add al, "A" ;convert it to a character.
1233 mov cs:CNTRY_DRV
, al ;set the drive letter.
1234 mov di, offset CNTRY_PATH
1235 mov al, byte ptr DS:[SI]
1238 cmp al, cs:SWTCHR ;let's accept "/" as an directory delim
1242 dec di ;DI -> CNTRY_ROOT
1244 call MOVE_ASCIIZ ;copy it
1245 mov di, offset CNTRY_DRV
1247 push ds ;switch ds, es
1250 pop es ;DS, ES value restored
1253 SET_COUNTRY_PATH endp
1256 CHK_DRIVE_LETTER proc near
1257 ;Check if DS:[SI] is a drive letter followed by ":".
1258 ;Assume that every alpha charater is already converted to UPPER CASE.
1262 cmp byte ptr ds:[si], "A
"
1264 cmp byte ptr ds:[si], "Z"
1266 cmp byte ptr ds:[si+1], ":"
1268 jmp short CDLetter_exit
1274 CHK_DRIVE_LETTER endp
1277 MOVE_ASCIIZ proc near
1278 ;In: DS:SI -> source ES:DI -> target
1279 ;Out: copy the string until 0.
1280 ;Assumes there exists a 0.
1283 cmp byte ptr DS:[SI-1], 0 ;Was it 0?
1289 ; DS:DX POINTS TO STRING TO OUTPUT (ASCIZ)
1291 ; PRINTS <BADLD_PRE> <STRING> <BADLD_POST>
1300 MOV DX,OFFSET BADLD_PRE ;WANT TO PRINT CONFIG ERROR
1301 ; MOV BX,OFFSET BADLD_POST
1302 mov bx, offset CRLFM ;AN006;
1307 PRN1: MOV DL,ES:[SI]
1310 MOV AH,STD_CON_OUTPUT
1316 cmp DoNotShowNum, 1 ;AN000; suppress line number when handling COMMAND.COM
1322 PRINT: MOV AH,STD_CON_STRING_OUTPUT
1329 ; LOAD NON EXE FILE CALLED [DS:DX] AT MEMORY LOCATION ES:BX
1339 XOR AX,AX ;OPEN THE FILE
1341 STC ;IN CASE OF INT 24
1343 POP DX ;Clean stack in case jump
1346 MOV BX,AX ;Handle in BX
1349 MOV AX,(LSEEK SHL 8) OR 2
1350 STC ;IN CASE OF INT 24
1351 INT 21H ; Get file size in DX:AX
1354 JNZ LDERRP ; File >64K
1357 MOV CX,ES ; CX:DX is xaddr
1358 ADD DX,AX ; Add file size to Xaddr
1360 ADD CX,1000H ; ripple carry
1374 MOV AX,LSEEK SHL 8 ;Reset pointer to beginning of file
1375 STC ;IN CASE OF INT 24
1379 PUSH ES ;READ THE FILE IN
1380 POP DS ;Trans addr is DS:DX
1381 MOV CX,0FF00H ; .COM files arn't any bigger than
1384 STC ;IN CASE OF INT 24
1387 MOV SI,DX ;CHECK FOR EXE FILE
1388 CMP WORD PTR [SI],"ZM
"
1390 JNZ LDCLS ; Only know how to do .COM files
1400 MOV AH,CLOSE ;CLOSE THE FILE
1415 ; OPEN DEVICE POINTED TO BY DX, AL HAS ACCESS CODE
1416 ; IF UNABLE TO OPEN DO A DEVICE OPEN NULL DEVICE INSTEAD
1422 MOV DX,OFFSET NULDEV
1427 MOV BX,AX ; Handle from open to BX
1428 XOR AX,AX ; GET DEVICE INFO
1443 ;J.K. TEST INT24. Return back to DOS with the fake user response of "FAIL
"
1445 mov al, 3 ;AN000; Fail the system call
1446 iret ;AN000; Return back to DOS.
1449 ;INT24: ADD SP,6 ;RESTORE MACHINE STATE
1460 ; MOV AH,GET_DEFAULT_DRIVE ;INITIALIZE DOS
1463 ; IRET ;BACK TO USER
1466 BOOTMES DB 13,10,"MS-DOS version
"
1467 DB MAJOR_VERSION + "0"
1469 DB (MINOR_VERSION / 10) + "0"
1470 DB (MINOR_VERSION MOD 10) + "0"
1472 DB "Copyright
1981,88 Microsoft Corp
.",13,10,"$"
1475 include copyrigh.inc ;P1821; Copyright statement
1482 CONFIG DB "\CONFIG
.SYS
",0
1486 CNTRY_PATH
DB "COUNTRY.SYS",0
1489 COUNTRY_FILE_SIGNATURE db 0FFh,'COUNTRY'
1491 CntryCodePage_Id
DW ?
1493 COMMND
DB "\COMMAND.COM",0
1496 PathString db 64 dup (0) ;AN014;
1497 LShare db "SHARE.EXE",0,"/NC",0Dh,0Ah ;AN014;AN015;To be used by Load/exec.
1498 ;/NC parm will disable file sharing check.
1501 ;;;; DB 8,"AVAILDEV",'A' ; NO LONGER SUPPORTED
1507 DB 9,"LASTDRIVE",'L'
1508 db 10,"MULTITRACK", 'M' ;AN002;
1509 DB 8,"DRIVPARM", 'P' ; RS for DOS 3.2
1511 DB 6,"STACKS", 'K' ; BAS for DOS 3.2
1515 db 7,"INSTALL", 'I' ;AN000;
1516 db 3,"IFS", 'J' ;AN000;
1517 db 4,"CPSW", 'W' ;AN000;
1518 ;;;; DB 8,"SWITCHAR",'W' ; NO LONGER SUPPORTED
1519 db 7,"COMMENT", 'Y' ;AN000;
1520 db 3,"REM", '0' ;AN004;
1521 db 8,"SWITCHES", '1' ;AN013;
1524 public DeviceParameters
1525 DeviceParameters a_DeviceParameters
<0,DEV_3INCH720KB
,0,80>
1537 ; The following are the recommended BPBs for the media that we know of so
1570 ; 3 1/2 inch diskette BPB
1598 BPBTable dw BPB48T
; 48tpi drives
1599 dw BPB96T
; 96tpi drives
1600 dw BPB35
; 3.5" drives
1601 ; The following are not supported, so default to 3.5" media layout
1602 dw BPB35
; Not used - 8" drives
1603 dw BPB35
; Not Used - 8" drives
1604 dw BPB35
; Not Used - hard files
1605 dw BPB35
; Not Used - tape drives
1606 dw BPB35H
; 3-1/2" 1.44MB drive
1608 switchlist db 8,"FHSTDICN" ; Preserve the positions of N and C.
1610 ; The following depend on the positions of the various letters in SwitchList
1612 switchnum equ
11111000B ; which switches require number
1614 flagec35 equ
00000100B ; electrically compatible 3.5 inch disk drive
1615 flagdrive equ
00001000B
1616 flagcyln equ
00010000B
1617 flagseclim equ
00100000B
1618 flagheads equ
01000000B
1619 flagff equ
10000000B
1621 SWTCHR EQU
"/" ; switch follows this character