summaryrefslogtreecommitdiffstats
path: root/private/mvdm/dpmi/dxini.asm
blob: 029433e46de78ca5861dc9d6368841bf04ca2286 (plain) (blame)
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