1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
|
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
|