DOS 3.30 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1256 lines
33 KiB

TITLE BIOS SYSTEM INITIALIZATION
TRUE EQU 0FFFFh
FALSE EQU 0
;IBMVER EQU TRUE
;IBM EQU IBMVER
STACKSW EQU TRUE ;Include Switchable Hardware Stks ;3.30
;IBMJAPVER EQU FALSE ;If TRUE set KANJI true also
;MSVER EQU FALSE
;ALTVECT EQU FALSE ;Switch to build ALTVECT version
;KANJI EQU FALSE
include version.inc
IF IBMJAPVER
NOEXEC EQU TRUE
ELSE
NOEXEC EQU FALSE
ENDIF
DOSSIZE EQU 0A000H
.xlist
include smdossym.inc ; Reduced version of DOSSYM.INC ;3.30
INCLUDE devsym.inc
include ioctl.inc
.list
IF NOT IBM
IF NOT IBMJAPVER
EXTRN RE_INIT:FAR
ENDIF
ENDIF
SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT' BYTE
ASSUME CS:SYSINITSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
EXTRN BADOPM:BYTE,CRLFM:BYTE,BADCOM:BYTE,BADMEM:BYTE,BADBLOCK:BYTE
EXTRN BADSIZ_PRE:BYTE,BADLD_PRE:BYTE
EXTRN BADSIZ_POST:BYTE,BADLD_POST:BYTE
EXTRN SYSSIZE:BYTE,BADCOUNTRY:BYTE
EXTRN dosinfo:dword,entry_point:dword,
EXTRN MEMORY_SIZE:WORD,fcbs:byte,keep:byte
EXTRN DEFAULT_DRIVE:BYTE,confbot:word,alloclim:word
EXTRN BUFFERS:WORD,zero:byte,sepchr:byte
EXTRN FILES:BYTE,stall:near
EXTRN count:word,chrptr:word
EXTRN bufptr:byte,memlo:word,prmblk:byte,memhi:word
EXTRN ldoff:word,area:word,PACKET:BYTE,UNITCOUNT:BYTE,
EXTRN BREAK_ADDR:DWORD,BPB_ADDR:DWORD,drivenumber:byte
PUBLIC Int24,Open_Dev,Organize,Mem_Err,Newline,CallDev,Badload
PUBLIC PrnDev,AuxDev,Config,Commnd,Condev,GetNum,BadFil,PrnErr
PUBLIC Round,Delim,Print,Set_Break
PUBLIC SetParms, ParseLine, DiddleBack
PUBLIC Skip_delim,SetDOSCountryInfo,Set_Country_Path,Move_Asciiz ;3.30
PUBLIC Cntry_Drv,Cntry_Root,Cntry_Path ;3.30
PUBLIC Delim ;3.30
ASSUME DS:SYSINITSEG
;
; The following set of routines is used to parse the DRIVPARM = command in
; the CONFIG.SYS file to change the default drive parameters.
;
SetParms:
push ds
push ax
push bx
push cx
push dx
xor bx,bx
mov bl,byte ptr drive
inc bl ; get it correct for IOCTL call (1=A,2=B...)
push cs
pop ds
mov dx,offset DeviceParameters
mov ah, IOCTL
mov al, GENERIC_IOCTL
mov ch, RAWIO
mov cl, SET_DEVICE_PARAMETERS
int 21H
pop dx
pop cx
pop bx
pop ax
pop ds
ret
;
; Replace default values for further DRIVPARM commands
;
DiddleBack:
mov word ptr DeviceParameters.DP_Cylinders,80
mov byte ptr DeviceParameters.DP_DeviceType, DEV_3INCH720KB
mov word ptr DeviceParameters.DP_DeviceAttributes,0
mov word ptr switches,0 ; zero all switches
ret
;
; Entry point is ParseLine. AL contains the first character in command line.
;
ParseLine: ; don't get character first time
push ds
push cs
pop ds
NextSwtch:
cmp al,13 ; carriage return?
jz done_line
cmp al,10 ; linefeed?
jz put_back ; put it back and done
; Anything less or equal to a space is ignored.
cmp al,' ' ; space?
jbe get_next ; skip over space
cmp al,'/'
jz getparm
stc ; mark error invalid-character-in-input
jmp short exitpl
getparm:
call Check_Switch
mov word ptr Switches,BX ; save switches read so far
jc swterr
get_next:
invoke getchr
jc done_line
jmp NextSwtch
swterr:
jmp exitpl ; exit if error
done_line:
test word ptr Switches,flagdrive ; see if drive specified
jnz okay
stc ; mark error no-drive-specified
jmp short exitpl
okay:
mov ax,word ptr switches
and ax,0003H ; get flag bits for changeline and non-rem
mov word ptr DeviceParameters.DP_DeviceAttributes,ax
mov word ptr DeviceParameters.DP_TrackTableEntries, 0
clc ; everything is fine
call SetDeviceParameters
exitpl:
pop ds
ret
put_back:
inc count ; one more char to scan
dec chrptr ; back up over linefeed
jmp short done_line
;
; Processes a switch in the input. It ensures that the switch is valid, and
; gets the number, if any required, following the switch. The switch and the
; number *must* be separated by a colon. Carry is set if there is any kind of
; error.
;
Check_Switch:
invoke getchr
jc err_check
and al,0DFH ; convert it to upper case
cmp al,'A'
jb err_check
cmp al,'Z'
ja err_check
push es
push cs
pop es
mov cl,byte ptr switchlist ; get number of valid switches
mov ch,0
mov di,1+offset switchlist ; point to string of valid switches
repne scasb
pop es
jnz err_check
mov ax,1
shl ax,cl ; set bit to indicate switch
mov bx,word ptr switches ; get switches so far
or bx,ax ; save this with other switches
mov cx,ax
test ax,7cH ; test against switches that require number to follow
jz done_swtch
invoke getchr
jc err_Swtch
cmp al,':'
jnz err_swtch
invoke getchr
push bx ; preserve switches
mov byte ptr cs:sepchr,' ' ; allow space separators
call GetNum
mov byte ptr cs:sepchr,0
pop bx ; restore switches
; Because GetNum does not consider carriage-return or line-feed as OK, we do
; not check for carry set here. If there is an error, it will be detected
; further on (hopefully).
call Process_Num
done_swtch:
clc
ret
err_swtch:
xor bx,cx ; remove this switch from the records
err_check:
stc
ret
;
; This routine takes the switch just input, and the number following (if any),
; and sets the value in the appropriate variable. If the number input is zero
; then it does nothing - it assumes the default value that is present in the
; variable at the beginning. Zero is OK for form factor and drive, however.
;
Process_Num:
test word ptr Switches,cx ; if this switch has been done before,
jnz done_ret ; ignore this one.
test cx,flagdrive
jz try_f
mov byte ptr drive,al
jmp short done_ret
try_f:
test cx,flagff
jz try_t
; Ensure that we do not get bogus form factors that are not supported
;cmp al,Max_Dev_Type
;ja done_ret
mov byte ptr DeviceParameters.DP_DeviceType,al
jmp short done_ret
try_t:
or ax,ax
jz done_ret ; if number entered was 0, assume default value
test cx,flagcyln
jz try_s
mov word ptr DeviceParameters.DP_Cylinders,ax
jmp short done_ret
try_s:
test cx,flagseclim
jz try_h
mov word ptr slim,ax
jmp short done_ret
;
; Must be for number of heads
try_h:
mov word ptr hlim,ax
done_ret:
clc
ret
;
; SetDeviceParameters sets up the recommended BPB in each BDS in the
; system based on the form factor. It is assumed that the BPBs for the
; various form factors are present in the BPBTable. For hard files,
; the Recommended BPB is the same as the BPB on the drive.
; No attempt is made to preserve registers since we are going to jump to
; SYSINIT straight after this routine.
;
SetDeviceParameters:
push es
push cs
pop es
ASSUME ES:SYSINITSEG
xor bx,bx
mov bl,byte ptr DeviceParameters.DP_DeviceType
cmp bl,DEV_5INCH
jnz Got_80
mov cx,40 ; 48tpi has 40 cylinders
mov word ptr DeviceParameters.DP_Cylinders,cx
Got_80:
shl bx,1 ; get index into BPB table
mov si,offset BPBTable
mov si,word ptr [si+bx] ; get address of BPB
Set_RecBPB:
mov di,offset DeviceParameters.DP_BPB ; es:di -> BPB
mov cx,size a_BPB
cld
repe movsb
pop es
ASSUME ES:NOTHING
test word ptr switches,flagseclim
jz see_heads
mov ax,word ptr slim
mov word ptr DeviceParameters.DP_BPB.BPB_SectorsPerTrack,ax
see_heads:
test word ptr switches,flagheads
jz Set_All_Done
mov ax,word ptr hlim
mov word ptr DeviceParameters.DP_BPB.BPB_Heads,ax
;
; We need to set the media byte and the total number of sectors to reflect the
; number of heads. We do this by multiplying the number of heads by the number
; of 'sectors per head'. This is not a fool-proof scheme!!
;
mov cx,ax ; cx has number of heads
dec cl ; get it 0-based
mov ax,DeviceParameters.DP_BPB.BPB_TotalSectors ; this is OK for two heads
sar ax,1 ; ax contains # of sectors/head
sal ax,cl
jc Set_All_Done ; We have too many sectors - overflow!!
mov DeviceParameters.DP_BPB.BPB_TotalSectors,ax
; Set up correct Media Descriptor Byte
cmp cl,1
mov bl,0F0H
mov al,2 ; AL contains sectors/cluster
ja Got_Correct_Mediad
mov bl,byte ptr DeviceParameters.DP_BPB.BPB_MediaDescriptor
je Got_Correct_Mediad
; We have one head - OK for 48tpi medium
mov al,1 ; AL contains sectors/cluster
mov ch,DeviceParameters.DP_DeviceType
cmp ch,DEV_5INCH
jz Dec_Mediad
mov bl,0F0H
jmp short Got_Correct_Mediad
Dec_Mediad:
dec bl ; adjust for one head
Got_Correct_Mediad:
mov byte ptr DeviceParameters.DP_BPB.BPB_MediaDescriptor,bl
mov byte ptr DeviceParameters.DP_BPB.BPB_SectorsPerCluster,al
clc
Set_All_Done:
RET
ASSUME DS:NOTHING, ES:NOTHING
NOCHAR1: STC
return
ORGANIZE:
MOV CX,[COUNT]
JCXZ NOCHAR1
CALL MAPCASE
XOR SI,SI
MOV DI,SI
ORG1: CALL GET ;SKIP LEADING CONTROL CHARACTERS
CMP AL,' '
JB ORG1
PUSH CX
PUSH SI
PUSH DI
MOV BP,SI
DEC BP
MOV SI,OFFSET COMTAB ;Prepare to search command table
MOV CH,0
FINDCOM:
MOV DI,BP
MOV CL,[SI]
INC SI
JCXZ NOCOM
REPE CMPSB
LAHF
ADD SI,CX ;Bump to next position without affecting flags
SAHF
LODSB ;Get indicator letter
JNZ FINDCOM
POP DI
POP SI
POP CX
JMP SHORT GOTCOM
NOCOM:
POP DI
POP SI
POP CX
MOV AL,'Z'
GOTCOM: STOSB ;SAVE INDICATOR CHAR IN BUFFER
ORG2: CALL GET2 ;SKIP NAME UNTIL DELIMITER
CALL DELIM ;
JNZ ORG2
CALL GET ;GET CHARS TO RIGHT OF EQUALS SIGN
STOSB
ORG4: CALL GET2
call delim ; 5/30/86. "device=filename/p..." ;3.30
jz ORG_EXT ; 5/30/86 ;3.30
STOSB
CMP AL,' '
JA ORG4
CMP AL,10
JZ ORG1
MOV BYTE PTR ES:[DI-1],0
ORG5: CALL GET2
STOSB
CMP AL,10
JNZ ORG5
JMP ORG1
ORG_EXT: ;3.30
mov byte ptr es:[di], 0 ;put 0 at DI to make it an ASCIIZ ;3.30
inc DI ; ;3.30
stosb ;and copy the delimeter char. ;3.30
jmp short ORG5 ;and continue as usual. ;3.30
GET2:
JCXZ NOGET
MOV AL,ES:[SI]
INC SI
DEC CX
return
GET: JCXZ NOGET
MOV AL,ES:[SI]
INC SI
DEC CX
CALL DELIM
JZ GET
return
DELIM: CMP AL,' '
retz
CMP AL,9
retz
CMP AL,'='
retz
CMP AL,','
retz
CMP AL,';'
retz ; 5/23/86 ;3.30
CMP AL,'/' ; 5/30/86. IBM will assume "/" delim ;3.30
retz ;3.30
cmp al, 0 ; 5/23/86 Special case for sysinit!!! ;3.30
return
NOGET: POP CX
MOV COUNT,DI
XOR SI,SI
MOV CHRPTR,SI
return
;
; NEWLINE RETURNS WITH FIRST CHARACTER OF NEXT LINE
;
NEWLINE:invoke GETCHR ;SKIP NON-CONTROL CHARACTERS
retc
CMP AL,10 ;LOOK FOR LINE FEED
JNZ NEWLINE
invoke GETCHR
return
MAPCASE:
PUSH CX
PUSH SI
PUSH DS
PUSH ES
POP DS
XOR SI,SI
CONVLOOP:
LODSB
IF KANJI
CALL TESTKANJ
JZ NORMCONV
INC SI ;Skip next char
DEC CX
JCXZ CONVDONE ;Just ignore 1/2 kanji error
;Fall through, know AL is not in 'a'-'z' range
NORMCONV:
ENDIF
CMP AL,'a'
JB NOCONV
CMP AL,'z'
JA NOCONV
SUB AL,20H
MOV [SI-1],AL
NOCONV:
LOOP CONVLOOP
CONVDONE:
POP DS
POP SI
POP CX
return
IF KANJI
TESTKANJ:
CMP AL,81H
JB NOTLEAD
CMP AL,9FH
JBE ISLEAD
CMP AL,0E0H
JB NOTLEAD
CMP AL,0FCH
JBE ISLEAD
NOTLEAD:
PUSH AX
XOR AX,AX ;Set zero
POP AX
return
ISLEAD:
PUSH AX
XOR AX,AX ;Set zero
INC AX ;Reset zero
POP AX
return
ENDIF
ASSUME DS:NOTHING
Yes_Break_Failed: ;dev drv Init failed and aborted. ;3.30
stc ;3.30
pop ax ;3.30
return ;3.30
SET_BREAK:
; 8/14/86 For DOS 3.3, this routine is modified to take care of the ;3.30
;Device driver's initialization error and abort. ;3.30
;If [break_addr+2] == [memhi] && [break_addr] = 0 then assume ;3.30
;that the device driver's initialization has an error and wanted to ;3.30
;abort the device driver. In this case, this routine will set carry ;3.30
;and return to the caller. ;3.30
; ;3.30
PUSH AX
MOV AX,WORD PTR [BREAK_ADDR+2] ;REMOVE THE INIT CODE
cmp ax, [MEMHI] ;3.30
jne Set_Break_Continue ;if not same, then O.K. ;3.30
;3.30
cmp word ptr [BREAK_ADDR],0 ;3.30
je Yes_Break_failed ;[Break_addr+2]=[MEMHI] & [Break_addr]=0 ;3.30
;3.30
Set_Break_Continue: ;3.30
MOV [MEMHI],AX
MOV AX,WORD PTR [BREAK_ADDR]
MOV [MEMLO],AX
POP AX ; NOTE FALL THROUGH
;
; Round the values in MEMLO and MEMHI to paragraph boundary.
; Perform bounds check.
;
ROUND:
PUSH AX
MOV AX,[MEMLO]
invoke ParaRound ; para round up
ADD [MEMHI],AX
MOV [MEMLO],0
mov ax,memhi ; ax = new memhi
CMP AX,[ALLOCLIM] ; if new memhi >= alloclim, error
JAE MEM_ERR
POP AX
clc ;clear carry ;3.30
return
MEM_ERR:
MOV DX,OFFSET BADMEM
PUSH CS
POP DS
CALL PRINT
JMP STALL
CALLDEV:MOV DS,WORD PTR CS:[ENTRY_POINT+2]
ADD BX,WORD PTR CS:[ENTRY_POINT] ;Do a little relocation
MOV AX,DS:[BX]
PUSH WORD PTR CS:[ENTRY_POINT]
MOV WORD PTR CS:[ENTRY_POINT],AX
MOV BX,OFFSET PACKET
CALL [ENTRY_POINT]
POP WORD PTR CS:[ENTRY_POINT]
return
BADNUM:
MOV sepchr,0
XOR AX,AX ; Set Zero flag, and AX = 0
pop bx ; ;3.30
stc ; AND carry set
return
ToDigit:
SUB AL,'0'
JB NotDig
CMP AL,9
JA NotDig
CLC
return
NotDig: STC
return
; GetNum parses a decimal number.
; Returns it in AX, sets zero flag if AX = 0 (MAY BE considered an
; error), if number is BAD carry is set, zero is set, AX=0.
GETNUM: push bx ; ;3.30
XOR BX,BX ; running count is zero
B2: CALL ToDigit ; do we have a digit
JC BadNum ; no, bomb
XCHG AX,BX ; put total in AX
PUSH BX ; save digit
MOV BX,10 ; base of arithmetic
MUL BX ; shift by one decimal di...
POP BX ; get back digit
ADD AL,BL ; get total
ADC AH,0 ; make that 16 bits
JC BADNUM ; too big a number
XCHG AX,BX ; stash total
invoke GETCHR ;GET NEXT DIGIT
JC B1 ; no more characters
cmp al, ' ' ; 5/23/86 space? ;3.30
jz B15 ; 5/23/86 then end of digits ;3.30
cmp al, ',' ; 5/23/86 ',' is a seperator! ;3.30
jz B15 ; 5/23/86 then end of digits. ;3.30
cmp al, 9 ; 5/23/86 TAB ;3.30
jz B15 ; ;3.30
CMP AL,SepChr ; allow , separators
JZ b15
cmp al,SWTCHR ; See if another switch follows
JZ b15
cmp al,10 ; Line-feed?
jz b15
cmp al,13 ; Carriage return?
jz b15
OR AL,AL ; end of line separator?
JNZ B2 ; no, try as a valid char...
b15: INC COUNT ; one more character to s...
DEC CHRPTR ; back up over separator
B1: MOV AX,BX ; get proper count
OR AX,AX ; Clears carry, sets Zero accordingly
pop bx ;3.30
return
SKIP_DELIM proc near ; ;3.30
;Skip the delimeters pointed by CHRPTR. AL will contain the first non delimete;3.30r
;character encountered and CHRPTR will point to the next character. ;3.30
;This rouitne will assume the second "," found as a non delimiter character. So;3.30
;in case if the string is " , , ", this routine will stop at the second ",". At;3.30
;this time, Zero flag is set. ;3.30
;If COUNT is exhausted, then carry will be set. ;3.30
Skip_delim_char: ;3.30
call getchr ;3.30
jc Skip_delim_exit ;3.30
cmp al, ',' ;the first comma? ;3.30
je Skip_delim_next ;3.30
call delim ;check the charater in AL. ;3.30
jz Skip_delim_char ;3.30
jmp short Skip_delim_exit ;found a non delim char ;3.30
Skip_delim_next: ;3.30
call getchr ;3.30
jc Skip_delim_exit ;3.30
cmp al, ',' ;the second comma? ;3.30
je Skip_delim_exit ;done ;3.30
call delim ;3.30
jz Skip_delim_next ;3.30
Skip_delim_exit: ;3.30
return ;3.30
SKIP_DELIM endp ;3.30
;3.30
; 5/26/86 *****************************************************************;3.30
SetDOSCountryInfo proc near ;3.30
;Input: ES:DI -> pointer to DOS_COUNTRY_CDPG_INFO ;3.30
; DS:0 -> buffer. ;3.30
; SI = 0 ;3.30
; AX = country id ;3.30
; DX = code page id. (If 0, then use ccSysCodePage as a default.) ;3.30
; BX = file handle ;3.30
; This routine can handle maxium 72 COUNTRY_DATA entries. ;3.30
;Output: DOS_country_cdpg_info set. ;3.30
; Carry set if any file read failure or wrong information in the file. ;3.30
; Carry set and CX = -1 if cannot find the matching COUNTRY_id, CODEPAGE;3.30
; _id in the file. ;3.30
;3.30
push di ;3.30
push ax ;3.30
push dx ;3.30
;3.30
xor cx,cx ;3.30
xor dx,dx ;3.30
mov ax, 512 ;read 512 bytes ;3.30
call ReadInControlBuffer ;Read the file header ;3.30
jc SetDOSData_fail ;3.30
push es ;3.30
push si ;3.30
push cs ;3.30
pop es ;3.30
mov di, offset COUNTRY_FILE_SIGNATURE ;3.30
mov cx, 8 ;length of the signature ;3.30
repz cmpsb ;3.30
pop si ;3.30
pop es ;3.30
jnz SetDOSData_fail ;signature mismatch ;3.30
;3.30
add si, 18 ;SI -> county info type ;3.30
cmp byte ptr ds:[si], 1 ;Only accept type 1 (Currently only 1 h;3.30eader type)
jne SetDOSData_fail ;cannot proceed. error return ;3.30
inc si ;SI -> file offset ;3.30
mov dx, word ptr ds:[si] ;Get the INFO file offset. ;3.30
mov cx, word ptr ds:[si+2] ;3.30
mov ax, 1024 ;read 1024 bytes. ;3.30
call ReadInControlBuffer ;Read INFO ;3.30
jc SetDOSData_fail ;3.30
mov cx, word ptr ds:[si] ;get the # of country, codepage combina;3.30tion entries
cmp cx, 72 ;cannot handle more than 72 entries. ;3.30
ja SetDOSData_fail ;3.30
inc si ;3.30
inc si ;SI -> entry information packet ;3.30
pop dx ;restore code page id ;3.30
pop ax ;restore country id ;3.30
pop di ;3.30
;3.30
SetDOSCntry_find: ;Search for desired country_id,codepage;3.30_id.
cmp ax, word ptr ds:[si+2] ;compare country_id ;3.30
jne SetDOSCntry_next ;3.30
cmp dx, 0 ;No user specified code page ? ;3.30
je SetDOSCntry_any_codepage;then no need to match code page id. ;3.30
cmp dx, word ptr ds:[si+4] ;compare code page id ;3.30
je SetDOSCntry_got_it ;3.30
SetDOSCntry_next: ;3.30
add si, word ptr ds:[si] ;next entry ;3.30
inc si ;3.30
inc si ;take a word for size of entry itself ;3.30
loop SetDOSCntry_find ;3.30
mov cx, -1 ;signals that bad country id entered. ;3.30
SetDOSCntry_fail: ;3.30
stc ;3.30
ret ;3.30
;3.30
SetDOSData_fail: ;3.30
pop si ;3.30
pop cx ;3.30
pop di ;3.30
jmp short SetDOSCntry_fail ;3.30
;3.30
SetDOSCntry_any_CodePage: ;use the code_page_id of the country_id;3.30 found.
mov dx, word ptr ds:[si+4] ;3.30
SetDOSCntry_got_it: ;found the matching entry ;3.30
mov cs:CntryCodePage_Id, dx ;save code page ID for this country. ;3.30
mov dx, word ptr ds:[si+10] ;get the file offset of country data ;3.30
mov cx, word ptr ds:[si+12] ;3.30
mov ax, 512 ;read 512 bytes ;3.30
call ReadInControlBuffer ;3.30
jc SetDOSCntry_fail ;3.30
mov cx, word ptr ds:[si] ;get the number of entries to handle. ;3.30
inc si ;3.30
inc si ;SI -> first entry ;3.30
;3.30
SetDOSCntry_data: ;3.30
push di ;ES:DI -> DOS_COUNTRY_CDPG_INFO ;3.30
push cx ;save # of entry left ;3.30
push si ;si -> current entry in Control buffer ;3.30
;3.30
mov al, byte ptr ds:[si+2] ;get data entry id ;3.30
call GetCountryDestination ;get the address of destination in ES:D;3.30I
jc SetDOSCntry_data_next ;No matching data entry id in DOS ;3.30
;3.30
;3.30
mov dx, word ptr ds:[si+4] ;get offset of data ;3.30
mov cx, word ptr ds:[si+6] ;3.30
mov ax, 4200h ;3.30
stc ;3.30
int 21h ;move pointer ;3.30
jc SetDOSData_fail ;3.30
mov dx, 512 ;start of data buffer ;3.30
mov cx, word ptr es:[di] ;length of the corresponding data in DO;3.30S.
add cx, 10 ;Signature + A word for the length itse;3.30lf
mov ah, 3fh ;3.30
stc ;3.30
int 21h ;read the country.sys data ;3.30
jc SetDOSData_fail ;read failure ;3.30
cmp ax, cx ;3.30
jne SetDOSData_fail ;3.30
;3.30
mov al, byte ptr ds:[si+2] ;save Data id for future use. ;3.30
mov si, (512+8) ;SI-> data buffer + id tag field ;3.30
mov cx, word ptr ds:[si] ;get the length of the file ;3.30
inc cx ;Take care of a word for lenght of tab ;3.30
inc cx ;itself. ;3.30
cmp cx, (2048 - 512 - 8) ;Fit into the buffer? ;3.30
ja SetDOSData_fail ;3.30
cmp al, SetCountryInfo ;is the data for SetCountryInfo table? ;3.30
jne SetDOSCntry_Mov ;no, don't worry ;3.30
push word ptr es:[di+24] ;Cannot destroy ccMono_ptr address. Sav;3.30e them.
push word ptr es:[di+26] ;3.30
push di ;save DI ;3.30
;3.30
push ax ;3.30
mov ax,cs:CntryCodePage_Id ;Do not use the Code Page info in Count;3.30ry_Info
mov ds:[si+4], ax ;Use the saved one for this !!!! ;3.30
pop ax ;3.30
;3.30
SetDOSCntry_Mov: ;3.30
rep movsb ;copy the table into DOS ;3.30
cmp al, SetCountryInfo ;was the ccMono_ptr saved? ;3.30
jne SetDOSCntry_data_next ;3.30
pop di ;restore DI ;3.30
pop word ptr es:[di+26] ;restore ccMono_ptr in DOS. ;3.30
pop word ptr es:[di+24] ;3.30
;3.30
SetDOSCntry_data_next: ;3.30
pop si ;restore control buffer pointer ;3.30
pop cx ;restore # of entries left ;3.30
pop di ;restore pointer to DSO_COUNTRY_CDPG ;3.30
add si, word ptr ds:[si] ;try to get the next entry ;3.30
inc si ;3.30
inc si ;take a word of entry length itself ;3.30
loop SetDOSCntry_data ;3.30
ret ;3.30
SetDOSCountryInfo endp ;3.30
; ;3.30
;3.30
GetCountryDestination proc near ;3.30
;Get the destination address in the DOS country info table. ;3.30
;Input: AL - Data ID ;3.30
; ES:DI -> DOS_COUNTRY_CDPG_INFO ;3.30
;On return: ;3.30
; ES:DI -> Destination address of the matching data id ;3.30
; carry set if no matching data id found in DOS. ;3.30
;3.30
push cx ;3.30
add di, ccNumber_of_entries ;skip the reserved area, syscodepage et;3.30c.
mov cx, word ptr es:[di] ;get the number of entries ;3.30
inc di ;3.30
inc di ;SI -> the first start entry id ;3.30
GetCntryDest: ;3.30
cmp byte ptr es:[di], al ;3.30
je GetCntryDest_OK ;3.30
cmp byte ptr es:[di], SetCountryInfo ;was it SetCountryInfo entry? ;3.30
je GetCntryDest_1 ;3.30
add di, 5 ;next data id ;3.30
jmp short GetCntryDest_loop ;3.30
GetCntryDest_1: ;3.30
add di, NEW_COUNTRY_SIZE + 3 ;next data id ;3.30
GetCntryDest_loop: ;3.30
loop GetCntryDest ;3.30
stc ;3.30
jmp short GetCntryDest_exit ;3.30
GetCntryDest_OK: ;3.30
cmp al, SetCountryInfo ;select country info? ;3.30
jne GetCntryDest_OK1 ;3.30
inc di ;now DI -> ccCountryInfoLen ;3.30
jmp short GetCntryDest_exit ;3.30
GetCntryDest_OK1: ;3.30
les di, dword ptr es:[di+1] ;get the destination in ES:DI ;3.30
GetCntryDest_Exit: ;3.30
pop cx ;3.30
ret ;3.30
GetCountryDestination endp ;3.30
;3.30
; ;3.30
ReadInControlBuffer proc near ;3.30
;Move file pointer to CX:DX ;3.30
;Read AX bytes into the control buffer. (Should be less than 2 Kb) ;3.30
;SI will be set to 0 hence DS:SI points to the control buffer. ;3.30
;Entry: CX,DX offset from the start of the file where the read/write pointer ;3.30
; be moved. ;3.30
; AX - # of bytes to read ;3.30
; BX - file handle ;3.30
; DS - buffer seg. ;3.30
;Return: The control data information is read into DS:0 - DS:0200. ;3.30
; CX,DX value destroyed. ;3.30
; Carry set if error in Reading file. ;3.30
; ;3.30
push ax ;# of bytes to read ;3.30
mov ax, 4200h ;3.30
stc ;3.30
int 21h ;move pointer ;3.30
pop cx ;# of bytes to read ;3.30
jc RICB_exit ;3.30
xor dx,dx ;ds:dx -> control buffer ;3.30
xor si,si ;3.30
mov ah,3fh ;read into the buffer ;3.30
stc ;3.30
int 21h ;should be less than 1024 bytes. ;3.30
RICB_exit: ;3.30
ret ;3.30
ReadInControlBuffer endp ;3.30
;3.30
; ;3.30
SET_COUNTRY_PATH proc near ;3.30
;In: DS - SYSINITSEG, ES - CONFBOT, SI -> start of the asciiz path string ;3.30
; DOSINFO_EXT, CNTRY_DRV, CNTRY_ROOT, CNTRY_PATH ;3.30
; Assumes current directory is the ROOT directory. ;3.30
;Out: DS:DI -> full path (CNTRY_DRV). ;3.30
; Set the CNTRY_DRV string from the COUNTRY=,,path command. ;3.30
; DS, ES, SI value saved. ;3.30
;3.30
push si ;3.30
push ds ;switch ds, es ;3.30
push es ;3.30
pop ds ;3.30
pop es ;now DS -> CONFBOT, ES -> SYSINITSEG ;3.30
;3.30
call chk_drive_letter ;current DS:[SI] is a drive letter? ;3.30
jc SCP_Default_drv ;no, use current default drive. ;3.30
mov al, byte ptr DS:[SI] ;3.30
inc si ;3.30
inc si ;SI -> next char after ":" ;3.30
jmp short SCP_SetDrv ;3.30
SCP_Default_drv: ;3.30
mov ah, 19h ;3.30
int 21h ;3.30
add al, "A" ;convert it to a character. ;3.30
SCP_SetDrv: ;3.30
mov cs:CNTRY_DRV, al ;set the drive letter. ;3.30
mov di, offset CNTRY_PATH ;3.30
mov al, byte ptr DS:[SI] ;3.30
cmp al, "\" ;3.30
je SCP_Root_Dir ;3.30
cmp al, cs:SWTCHR ;let's accept "/" as an directory delim;3.30
je SCP_Root_Dir ;3.30
jmp short SCP_Path ;3.30
SCP_Root_Dir: ;3.30
dec di ;DI -> CNTRY_ROOT ;3.30
SCP_Path: ;3.30
call MOVE_ASCIIZ ;copy it ;3.30
mov di, offset CNTRY_DRV ;3.30
SCPath_Exit: ;3.30
push ds ;switch ds, es ;3.30
push es ;3.30
pop ds ;3.30
pop es ;DS, ES value restored ;3.30
pop si ;3.30
RET ;3.30
SET_COUNTRY_PATH endp ;3.30
;3.30
; ;3.30
CHK_DRIVE_LETTER proc near ;3.30
;Check if DS:[SI] is a drive letter followed by ":". ;3.30
;Assume that every alpha charater is already converted to UPPER CASE. ;3.30
;Carry set if not. ;3.30
; ;3.30
push ax ;3.30
cmp byte ptr ds:[si], "A" ;3.30
jb CDLetter_NO ;3.30
cmp byte ptr ds:[si], "Z" ;3.30
ja CDLetter_NO ;3.30
cmp byte ptr ds:[si+1], ":" ;3.30
jne CDLetter_NO ;3.30
jmp short CDLetter_exit ;3.30
CDLetter_NO: ;3.30
stc ;3.30
CDLetter_exit: ;3.30
pop ax ;3.30
ret ;3.30
CHK_DRIVE_LETTER endp ;3.30
;3.30
; ;3.30
MOVE_ASCIIZ proc near ;3.30
;In: DS:SI -> source ES:DI -> target ;3.30
;Out: copy the string until 0. ;3.30
;Assumes there exists a 0. ;3.30
MASCIIZ_loop: ;3.30
movsb ;3.30
cmp byte ptr DS:[SI-1], 0 ;Was it 0? ;3.30
jne MASCIIZ_loop ;3.30
ret ;3.30
MOVE_ASCIIZ endp ;3.30
;
; DS:DX POINTS TO STRING TO OUTPUT (ASCIZ)
;
; PRINTS <BADLD_PRE> <STRING> <BADLD_POST>
;
;
;
BADFIL:
PUSH CS
POP ES
MOV SI,DX
BADLOAD:
MOV DX,OFFSET BADLD_PRE ;WANT TO PRINT CONFIG ERROR
MOV BX,OFFSET BADLD_POST
PRNERR:
PUSH CS
POP DS
MOV AH,STD_CON_STRING_OUTPUT
INT 21H
PRN1: MOV DL,ES:[SI]
OR DL,DL
JZ PRN2
MOV AH,STD_CON_OUTPUT
INT 21H
INC SI
JMP PRN1
PRN2: MOV DX,BX
PRINT: MOV AH,STD_CON_STRING_OUTPUT
INT 21H
return
IF NOEXEC
;
; LOAD NON EXE FILE CALLED [DS:DX] AT MEMORY LOCATION ES:BX
;
LDFIL:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DS
PUSH BX
XOR AX,AX ;OPEN THE FILE
MOV AH,OPEN
STC ;IN CASE OF INT 24
INT 21H
POP DX ;Clean stack in case jump
JC LDRET
PUSH DX
MOV BX,AX ;Handle in BX
XOR CX,CX
XOR DX,DX
MOV AX,(LSEEK SHL 8) OR 2
STC ;IN CASE OF INT 24
INT 21H ; Get file size in DX:AX
JC LDCLSP
OR DX,DX
JNZ LDERRP ; File >64K
POP DX
PUSH DX
MOV CX,ES ; CX:DX is xaddr
ADD DX,AX ; Add file size to Xaddr
JNC DOSIZE
ADD CX,1000H ; ripple carry
DOSIZE:
mov ax,dx
call ParaRound
mov dx,ax
ADD CX,DX
CMP CX,[ALLOCLIM]
JB OKLD
JMP MEM_ERR
OKLD:
XOR CX,CX
XOR DX,DX
MOV AX,LSEEK SHL 8 ;Reset pointer to beginning of file
STC ;IN CASE OF INT 24
INT 21H
JC LDCLSP
POP DX
PUSH ES ;READ THE FILE IN
POP DS ;Trans addr is DS:DX
MOV CX,0FF00H ; .COM files arn't any bigger than
; 64k-100H
MOV AH,READ
STC ;IN CASE OF INT 24
INT 21H
JC LDCLS
MOV SI,DX ;CHECK FOR EXE FILE
CMP WORD PTR [SI],"ZM"
CLC ; Assume OK
JNZ LDCLS ; Only know how to do .COM files
STC
JMP SHORT LDCLS
LDERRP:
STC
LDCLSP:
POP DX ;Clean stack
LDCLS:
PUSHF
MOV AH,CLOSE ;CLOSE THE FILE
STC
INT 21H
POPF
LDRET: POP DS
POP SI
POP DX
POP CX
POP BX
POP AX
return
ENDIF
;
; OPEN DEVICE POINTED TO BY DX, AL HAS ACCESS CODE
; IF UNABLE TO OPEN DO A DEVICE OPEN NULL DEVICE INSTEAD
;
OPEN_DEV:
CALL OPEN_FILE
JNC OPEN_DEV3
OPEN_DEV1:
MOV DX,OFFSET NULDEV
CALL OPEN_FILE
return
OPEN_DEV3:
MOV BX,AX ; Handle from open to BX
XOR AX,AX ; GET DEVICE INFO
MOV AH,IOCTL
INT 21H
TEST DL,10000000B
retnz
MOV AH,CLOSE
INT 21H
JMP OPEN_DEV1
OPEN_FILE:
MOV AH,OPEN
STC
INT 21H
return
INT24: ADD SP,6 ;RESTORE MACHINE STATE
POP AX
POP BX
POP CX
POP DX
POP SI
POP DI
POP BP
POP DS
POP ES
PUSH AX
MOV AH,GET_DEFAULT_DRIVE ;INITIALIZE DOS
INT 21H
POP AX
IRET ;BACK TO USER
IF ALTVECT
BOOTMES DB 13,10,"MS-DOS version "
DB MAJOR_VERSION + "0"
DB "."
DB (MINOR_VERSION / 10) + "0"
DB (MINOR_VERSION MOD 10) + "0"
DB 13,10
DB "Copyright 1981,82 Microsoft Corp.",13,10,"$"
ENDIF
NULDEV DB "NUL",0
CONDEV DB "CON",0
AUXDEV DB "AUX",0
PRNDEV DB "PRN",0
CONFIG DB "\CONFIG.SYS",0
CNTRY_DRV DB "A:" ;3.30
CNTRY_ROOT DB "\" ;3.30
CNTRY_PATH DB "COUNTRY.SYS",0 ;3.30
DB 52 DUP (0) ;3.30
;3.30
COUNTRY_FILE_SIGNATURE db 0FFh,'COUNTRY' ;3.30
;3.30
CntryCodePage_Id DW ? ;3.30
COMMND DB "\COMMAND.COM",0
DB 20 dup (0) ;3.30
COMTAB LABEL BYTE
;;;; DB 8,"AVAILDEV",'A' ; NO LONGER SUPPORTED
DB 7,"BUFFERS", 'B'
DB 5,"BREAK", 'C'
DB 6,"DEVICE", 'D'
DB 5,"FILES", 'F'
DB 4,"FCBS", 'X'
DB 9,"LASTDRIVE",'L'
DB 8,"DRIVPARM", 'P' ; RS for DOS 3.2
IF STACKSW ;3.30
DB 6,"STACKS", 'K' ; BAS for DOS 3.2 ;3.30
ENDIF ;3.30
DB 7,"COUNTRY", 'Q'
DB 5,"SHELL", 'S'
;;;; DB 8,"SWITCHAR",'W' ; NO LONGER SUPPORTED
DB 0
public DeviceParameters
DeviceParameters a_DeviceParameters <0,DEV_3INCH720KB,0,80>
hlim dw 2
slim dw 9
public drive
drive db ?
public switches
Switches dw ?
;
; The following are the recommended BPBs for the media that we know of so
; far.
; 48 tpi diskettes
BPB48T DW 512
DB 2
DW 1
DB 2
DW 112
DW 2*9*40
DB 0FDH
DW 2
DW 9
DW 2
Dd 0 ;hidden sectors - sp
Dd 0 ;big total sectors - sp
DB 6 DUP(?) ;reserved - sp
; 96tpi diskettes
BPB96T DW 512
DB 1
DW 1
DB 2
DW 224
DW 2*15*80
DB 0f9H
DW 7
DW 15
DW 2
Dd 0 ;hidden sectors - sp
Dd 0 ;big total sectors - sp
DB 6 DUP(?) ;reserved - sp
; 3 1/2 inch diskette BPB
BPB35 DW 512
DB 2
DW 1 ; Double sided with 9 sec/trk
DB 2
DW 70h
DW 2*9*80
DB 0f9H
DW 3
DW 9
DW 2
Dd 0 ;hidden sectors - sp
Dd 0 ;big total sectors - sp
DB 6 DUP(?) ;reserved - sp
BPBTable dw BPB48T ; 48tpi drives
dw BPB96T ; 96tpi drives
dw BPB35 ; 3.5" drives
; The following are not supported, so default to 3.5" media layout
dw BPB35 ; Not used - 8" drives
dw BPB35 ; Not Used - 8" drives
dw BPB35 ; Not Used - hard files
dw BPB35 ; Not Used - tape drives
dw BPB35 ; Not Used - Other
switchlist db 7,"FHSTDCN" ; Preserve the positions of N and C.
; The following depend on the positions of the various letters in SwitchList
flagdrive equ 0004H
flagcyln equ 0008H
flagseclim equ 0010H
flagheads equ 0020H
flagff equ 0040H
SWTCHR EQU "/" ; switch follows this character
SYSINITSEG ENDS
END