468 lines
15 KiB
NASM
468 lines
15 KiB
NASM
|
PAGE ,132
|
||
|
TITLE DXINI.ASM -- Dos Extender INI File Processing
|
||
|
|
||
|
; Copyright (c) Microsoft Corporation 1989-1991. All Rights Reserved.
|
||
|
|
||
|
;***********************************************************************
|
||
|
;
|
||
|
; DXINI.ASM -- Dos Extender INI FIle Processing
|
||
|
;
|
||
|
;-----------------------------------------------------------------------
|
||
|
;
|
||
|
; This module provides the 286 DOS extender's ...
|
||
|
;
|
||
|
;-----------------------------------------------------------------------
|
||
|
;
|
||
|
; 09/27/89 jimmat Modified to use FindFile instead of using its
|
||
|
; own file search logic
|
||
|
; 05/24/89 w-glenns Original (UNCUT, UNCENSORED!) version
|
||
|
;
|
||
|
;***********************************************************************
|
||
|
|
||
|
.286
|
||
|
|
||
|
; -------------------------------------------------------
|
||
|
; INCLUDE FILE DEFINITIONS
|
||
|
; -------------------------------------------------------
|
||
|
|
||
|
.xlist
|
||
|
.sall
|
||
|
include segdefs.inc
|
||
|
include gendefs.inc
|
||
|
include intmac.inc
|
||
|
.list
|
||
|
|
||
|
; -------------------------------------------------------
|
||
|
; GENERAL SYMBOL DEFINITIONS
|
||
|
; -------------------------------------------------------
|
||
|
|
||
|
CR equ 13
|
||
|
LF equ 10
|
||
|
TAB equ 9
|
||
|
EOF equ 26
|
||
|
|
||
|
|
||
|
; -------------------------------------------------------
|
||
|
; EXTERNAL SYMBOL DEFINITIONS
|
||
|
; -------------------------------------------------------
|
||
|
|
||
|
extrn strcpy:NEAR
|
||
|
extrn FindFile:NEAR
|
||
|
|
||
|
; -------------------------------------------------------
|
||
|
; DATA SEGMENT DEFINITIONS
|
||
|
; -------------------------------------------------------
|
||
|
|
||
|
DXDATA segment
|
||
|
|
||
|
extrn rgbXfrBuf1:BYTE
|
||
|
|
||
|
DXDATA ends
|
||
|
|
||
|
; -------------------------------------------------------
|
||
|
subttl Read INI File Routine
|
||
|
page
|
||
|
; -------------------------------------------------------
|
||
|
; READ INI FILE ROUTINE
|
||
|
; -------------------------------------------------------
|
||
|
|
||
|
DXCODE segment
|
||
|
assume cs:DXCODE
|
||
|
|
||
|
;******************************************************************************
|
||
|
;
|
||
|
; ReadIniFile
|
||
|
;
|
||
|
; DESCRIPTION: read and parse a .INI file for the 286 DOS Extender
|
||
|
; initialization.
|
||
|
;
|
||
|
; ENTRY: dx points to the file name
|
||
|
; bx points to structure to fill with ini fields
|
||
|
;
|
||
|
; EXIT: Carry set, if file not found, or not enough memory
|
||
|
;
|
||
|
; USES: ax, cx
|
||
|
;
|
||
|
;==============================================================================
|
||
|
|
||
|
assume ds:DGROUP
|
||
|
public ReadIniFile
|
||
|
|
||
|
ReadIniFile PROC NEAR
|
||
|
|
||
|
push es
|
||
|
push bx
|
||
|
push si
|
||
|
push di
|
||
|
|
||
|
push ds
|
||
|
pop es
|
||
|
assume es:DGROUP
|
||
|
|
||
|
push bx ; ptr to ini structure to fill
|
||
|
|
||
|
mov si,dx
|
||
|
mov di,offset RELOC_BUFFER ; FindFile wants the name here
|
||
|
call strcpy
|
||
|
|
||
|
call FindFile ; locate the .INI file
|
||
|
jc ri_error
|
||
|
|
||
|
mov ax,3D00h ; open the .INI file
|
||
|
mov dx,offset EXEC_PROGNAME ; FindFile puts path name here
|
||
|
int 21h
|
||
|
jc ri_error ; shouldn't happen, but...
|
||
|
|
||
|
mov si, ax ; file handle
|
||
|
|
||
|
mov ah, 48h ; alloc DOS conventional memory
|
||
|
mov bx, 4096d ; want 64k block
|
||
|
int 21h
|
||
|
jc ri_error
|
||
|
|
||
|
pop dx ; ptr to ini structure to fill
|
||
|
|
||
|
call parse_ini ; do the work, and come back
|
||
|
assume es:NOTHING
|
||
|
|
||
|
pushf ; save parse_ini flags
|
||
|
|
||
|
mov ah, 49h ; dealloc DOS conventional memory
|
||
|
int 21h ; es already points to block
|
||
|
|
||
|
npopf ; carry set = problem
|
||
|
ri_end:
|
||
|
pop di
|
||
|
pop si
|
||
|
pop bx
|
||
|
pop es
|
||
|
ret
|
||
|
|
||
|
ri_error: ; error exit
|
||
|
pop bx ; clear stack
|
||
|
stc ; force carry on
|
||
|
jmp short ri_end ; split
|
||
|
|
||
|
ReadIniFile ENDP
|
||
|
|
||
|
|
||
|
;******************************************************************************
|
||
|
;
|
||
|
; Parse_Ini
|
||
|
;
|
||
|
; DESCRIPTION: Read in, and parse the ini file opened
|
||
|
; and find the variable values specified
|
||
|
;
|
||
|
; ENTRY: ax points to the memory block for the file image buffer
|
||
|
; dx points to structure to fill with ini fields
|
||
|
; si has the handle to the file opened
|
||
|
;
|
||
|
; EXIT: Carry set, if file not found, or not enough memory
|
||
|
;
|
||
|
; USES: ax, bx, cx, es
|
||
|
;
|
||
|
;==============================================================================
|
||
|
|
||
|
Parse_Ini PROC NEAR
|
||
|
|
||
|
push bp
|
||
|
push dx
|
||
|
mov bp,dx ; bp = index into structure (es:)
|
||
|
|
||
|
assume ds:NOTHING
|
||
|
push ds
|
||
|
|
||
|
mov ds, ax ; ptr to mem block
|
||
|
|
||
|
mov ah, 3Fh
|
||
|
mov bx, si
|
||
|
mov cx, 0FFFFh ; guess extremely high
|
||
|
xor dx, dx ; offset 0
|
||
|
int 21h
|
||
|
|
||
|
pop es
|
||
|
assume es:DGROUP ; NOTE:!!! es is now data segment !!!
|
||
|
|
||
|
pushf ; save flags from read
|
||
|
push ax ; save # bytes read
|
||
|
|
||
|
mov ah, 3Eh ; close file
|
||
|
mov bx, si
|
||
|
int 21h
|
||
|
|
||
|
pop di ; number bytes read
|
||
|
npopf ; CY flag
|
||
|
|
||
|
jnc @f
|
||
|
jmp parse_done_jump ; if couldn't read, return bad
|
||
|
@@:
|
||
|
|
||
|
mov byte ptr ds:[di], EOF ; write EOF char'r in case none present
|
||
|
|
||
|
; ds:si points to the file image buffer
|
||
|
; es:di/bx structure to fill with ini stuff
|
||
|
xor si,si
|
||
|
|
||
|
; search until section found
|
||
|
find_section:
|
||
|
call Get_Char
|
||
|
jc short parse_done_jump ; end of file, and section not found
|
||
|
cmp al, '[' ; a section ?
|
||
|
jne short find_section
|
||
|
|
||
|
mov di, bp ; point to ini structure
|
||
|
; a section has been found, but is it the right one ?
|
||
|
xor bx, bx ; use as secondary index
|
||
|
cmp_section:
|
||
|
mov al, byte ptr ds:[si+bx] ; char'r from section name in file
|
||
|
|
||
|
inc bx ; bx starts at zero for file pointer
|
||
|
; index, and starts at one for
|
||
|
; structure index
|
||
|
mov ah, byte ptr es:[di+bx]
|
||
|
or ah, ah
|
||
|
jz short find_keyword_start ; yes: found the right section !
|
||
|
|
||
|
call Conv_Char_Lower ; convert char'r in AL to lower case
|
||
|
cmp al, ah ; same so far ?
|
||
|
jne short find_section
|
||
|
jmp short cmp_section
|
||
|
|
||
|
find_keyword_start:
|
||
|
add si,bx ; update file pointer past section name
|
||
|
|
||
|
add bp,bx ; update structure ptr past section name
|
||
|
|
||
|
; now that section is found, want to find keywords
|
||
|
find_keyword:
|
||
|
call Get_Char ; points to 1st char'r of next keyword
|
||
|
jc short parse_done_jump ; end of file, and keyword not found
|
||
|
|
||
|
cmp al, '[' ; new section ?
|
||
|
je short parse_done_jump ; hit a new section, so we're done
|
||
|
|
||
|
search_keyword:
|
||
|
xor di,di
|
||
|
; use beginning of file image buffer for temporary storage of the
|
||
|
; keyword name currently being checked
|
||
|
|
||
|
find_keyword_loop:
|
||
|
mov byte ptr ds:[di], al ; copy the char'r
|
||
|
inc di
|
||
|
|
||
|
mov dx,si ; save position in file image buffer
|
||
|
call Get_Char ; points to 1st char'r of next keyword
|
||
|
jc short parse_done_jump ; end of file, and keyword not found
|
||
|
pushf
|
||
|
cmp al, '='
|
||
|
je short compare_keyword
|
||
|
; yes: found a keyword, lets do some comparisons
|
||
|
|
||
|
npopf
|
||
|
jz short find_keyword_loop ; no white space yet...copy keyword
|
||
|
|
||
|
skip_keyword:
|
||
|
; white space has been skipped, yet there is no '='
|
||
|
; must be an error...ignore, and get next keyword
|
||
|
mov si,dx ; point to last char'r in keyword
|
||
|
mov byte ptr ds:[si], ';'
|
||
|
; fake a comment, so that the rest of the
|
||
|
; line is ignored in the next Get_Char call
|
||
|
; and the next keyword is pointed to
|
||
|
jmp short find_keyword
|
||
|
|
||
|
|
||
|
parse_done_jump:
|
||
|
jmp parse_done
|
||
|
|
||
|
; char'r is an equals, so compare this keyword to the list
|
||
|
compare_keyword:
|
||
|
npopf ; clean top-of-stack
|
||
|
mov byte ptr ds:[di], 0 ; NULL at end of keyword for compare
|
||
|
mov bx,bp ; get index into INI structure in
|
||
|
; data segment DGROUP (where es points)
|
||
|
|
||
|
cmp_keyword1:
|
||
|
xor di,di ; point to start of keyword found
|
||
|
|
||
|
cmp_keyword:
|
||
|
inc bx
|
||
|
mov ah, byte ptr es:[bx] ; next char'r in ini struct keyword
|
||
|
mov al, byte ptr ds:[di] ; next char'r of found keyword
|
||
|
inc di
|
||
|
or al, ah
|
||
|
jz short convert_number ; yes: found the right keyword
|
||
|
|
||
|
call Conv_Char_Lower ; convert char'r in AL to lower case
|
||
|
cmp al, ah ; same so far ?
|
||
|
je short cmp_keyword
|
||
|
|
||
|
xor al,al
|
||
|
dec bx
|
||
|
cmp_keyword_loop:
|
||
|
inc bx
|
||
|
cmp byte ptr es:[bx], al ; next keyword yet?
|
||
|
jne cmp_keyword_loop ; nope: go back until done
|
||
|
|
||
|
; keywords don't match..try next key word in ini structure
|
||
|
inc bx
|
||
|
inc bx ; jump over variable space (1 word)
|
||
|
cmp byte ptr es:[bx+1], al ; more keywords to compare with ?
|
||
|
jne short cmp_keyword1 ; yes: compare the next one
|
||
|
jmp short skip_keyword
|
||
|
; no: search file for next keyword
|
||
|
|
||
|
convert_number:
|
||
|
push si ; save current file pointer
|
||
|
call Get_Char
|
||
|
dec si ; point to first char'r position in number to convert
|
||
|
|
||
|
xor di,di
|
||
|
mov ax,di
|
||
|
mov cx,ax
|
||
|
|
||
|
cmp byte ptr ds:[si], '+' ; positive number ? (default)
|
||
|
jne short cn_1
|
||
|
|
||
|
inc si ; just skip the char'r - positive is default anyway
|
||
|
|
||
|
cn_1: cmp byte ptr ds:[si], '-' ; negative number ?
|
||
|
jne short cn_2
|
||
|
|
||
|
inc si
|
||
|
inc cl ; negative number - flag so we can negate it later
|
||
|
|
||
|
cn_2: push bx
|
||
|
mov bx,si ; save ptr in file buffer - check later if it changed
|
||
|
push cx ; save flag
|
||
|
|
||
|
convert_get_loop:
|
||
|
mov cl, byte ptr ds:[si]
|
||
|
cmp cl, '0'
|
||
|
jb short convert_done
|
||
|
cmp cl, '9'
|
||
|
ja short convert_done
|
||
|
|
||
|
sub cx,'0' ; de-ascii'ize cx ==> 0h - 09h
|
||
|
|
||
|
inc si ; increment pointer
|
||
|
mov dx,010d
|
||
|
mul dx ; multiply ax by 10 : dx is set to zero
|
||
|
add ax,cx ; add number in
|
||
|
jmp short convert_get_loop
|
||
|
|
||
|
convert_done:
|
||
|
pop cx ; restore -ve/+ve flag
|
||
|
jcxz convert_done_1 ; Q: -ve number ?
|
||
|
|
||
|
neg ax ; negate the number
|
||
|
|
||
|
convert_done_1:
|
||
|
cmp si,bx ; Q: has index changed, i.e.
|
||
|
; is the first char'r invalid ?
|
||
|
pop bx
|
||
|
je short convert_done_2 ; Y: don't save number
|
||
|
|
||
|
inc bx ; N: point to number in structure
|
||
|
mov word ptr es:[bx], ax ; save value into ini structure
|
||
|
|
||
|
convert_done_2:
|
||
|
pop si ; get old file pointer
|
||
|
mov byte ptr ds:[si], ';'
|
||
|
; fake a comment, so that the rest of the
|
||
|
; line is ignored in the next Get_Char call
|
||
|
; and the next keyword is pointed to
|
||
|
jmp find_keyword ; go back & get another
|
||
|
|
||
|
|
||
|
; *** single exit point for parsing code
|
||
|
parse_done:
|
||
|
mov ax,es ; swap extended and data segment ptrs
|
||
|
mov bx,ds
|
||
|
mov es,bx
|
||
|
mov ds,ax
|
||
|
|
||
|
pop dx
|
||
|
pop bp
|
||
|
ret
|
||
|
|
||
|
Parse_Ini ENDP
|
||
|
|
||
|
;******************************************************************************
|
||
|
;
|
||
|
; Get_Char
|
||
|
;
|
||
|
; DESCRIPTION: Local routine which gets the next valid ascii
|
||
|
; character from the file image, while skipping white
|
||
|
; space.
|
||
|
;
|
||
|
; ENTRY: ds:si -> buffer pointer
|
||
|
;
|
||
|
; EXIT: ds:si -> new buffer pointer
|
||
|
; al --> character
|
||
|
; Z flag --> set = no white space between last char'r and current
|
||
|
; C flag --> set = reached end of file
|
||
|
;
|
||
|
; USES: cx
|
||
|
;
|
||
|
;==============================================================================
|
||
|
|
||
|
Get_Char PROC NEAR
|
||
|
|
||
|
mov cx,si
|
||
|
inc cx
|
||
|
|
||
|
get_char_loop:
|
||
|
lodsb ; get char from file image
|
||
|
cmp al,EOF
|
||
|
je short get_char_EOF
|
||
|
cmp al,CR
|
||
|
je short get_char_loop
|
||
|
cmp al,LF
|
||
|
je short get_char_loop
|
||
|
cmp al,TAB
|
||
|
je short get_char_loop
|
||
|
cmp al,' '
|
||
|
je short get_char_loop
|
||
|
cmp al,';'
|
||
|
je short get_char_skip_comment
|
||
|
|
||
|
; must have got a good character finally...
|
||
|
call Conv_Char_Lower
|
||
|
cmp cx,si ; skipped a white space ?
|
||
|
clc ; continue
|
||
|
ret
|
||
|
|
||
|
get_char_EOF:
|
||
|
stc ; flag end of the file
|
||
|
ret
|
||
|
|
||
|
get_char_skip_comment:
|
||
|
lodsb ; get char from file image
|
||
|
cmp al,EOF
|
||
|
je short get_char_EOF
|
||
|
cmp al,CR
|
||
|
jne short get_char_skip_comment
|
||
|
jmp short get_char_loop
|
||
|
|
||
|
Get_Char ENDP
|
||
|
|
||
|
Conv_Char_Lower PROC NEAR
|
||
|
|
||
|
cmp al, 'A' ; want char'r 'A'-'Z' to be
|
||
|
jb short lower_done ; converted to 'a'-'z'
|
||
|
cmp al, 'Z'
|
||
|
ja short lower_done
|
||
|
or al, 020h ; convert to lower case
|
||
|
lower_done:
|
||
|
ret
|
||
|
|
||
|
Conv_Char_Lower ENDP
|
||
|
|
||
|
; -------------------------------------------------------
|
||
|
|
||
|
DXCODE ends
|
||
|
|
||
|
;****************************************************************
|
||
|
end
|