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
|
PAGE 60,132
TITLE INDEGDT - 386 XMA Emulator - Build Global Descriptor Table
COMMENT #
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* MODULE NAME : INDEGDT *
* *
* *
* 5669-196 (C) COPYRIGHT 1988 Microsoft Corp. *
* *
* DESCRIPTIVE NAME: Build the Global Descriptor Table (GDT) *
* *
* STATUS (LEVEL) : Version (0) Level (1.0) *
* *
* FUNCTION : Build the Global Descriptor Table (GDT) for the 80386 *
* XMA emulator *
* *
* MODULE TYPE : ASM *
* *
* REGISTER USAGE : 80386 Standard *
* *
* RESTRICTIONS : None *
* *
* DEPENDENCIES : None *
* *
* ENTRY POINT : GDT_BLD *
* *
* LINKAGE : Called NEAR from INDEINI *
* *
* INPUT PARMS : None *
* *
* RETURN PARMS : None *
* *
* OTHER EFFECTS : None *
* *
* EXIT NORMAL : Return to INDEINI *
* *
* EXIT ERROR : None *
* *
* EXTERNAL *
* REFERENCES : None *
* *
* SUB-ROUTINES : SREG_2_24BITS - Convert the 16 bit value in AX to a 24 *
* bit value in DH and AX. *
* ADDOFF - Add the 16 bit offset in AX to the 24 bit value *
* in DH and BX. *
* *
* MACROS : DESCR_DEF - Declare a descriptor entry *
* DESCR_INIT - Initialize a descriptor *
* *
* CONTROL BLOCKS : INDEDAT - System data structures *
* *
* CHANGE ACTIVITY : *
* *
* $MOD(INDEGDT) COMP(LOAD) PROD(3270PC) : *
* *
* $D0=D0004700 410 870530 D : NEW FOR RELEASE 1.1 *
* $P1=P0000293 410 870731 D : LIMIT LINES TO 80 CHARACTERS *
* $P2=P0000312 410 870804 D : CHANGE COMPONENT FROM MISC TO LOAD *
* $P3=P0000410 410 870918 D : RELOCATE DATA AREAS TO MAKE ROOM FOR BIT MAP *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
#
.286P ; Enable recognition of 286 privileged instructs.
.XLIST ; Turn off the listing
INCLUDE INDEDAT.INC ; Include system data structures
INCLUDE INDEACC.INC ; Include access byte definitions
IF1 ; Only include macros on the first pass
INCLUDE INDEDES.MAC ; Descriptor macros
ENDIF
.LIST ; Turn on the listing
PROG SEGMENT PARA PUBLIC 'PROG'
ASSUME CS:PROG
ASSUME SS:NOTHING
ASSUME DS:PROG
ASSUME ES:NOTHING
INDEGDT LABEL NEAR
PUBLIC INDEGDT
PUBLIC GDT_BLD
PUBLIC GDT_DATA_START
PUBLIC SREG_2_24BITS
; The following data define a pre-initialized GDT. They represent
; all structures which will exist when the emulator comes up.
; THESE MUST BE INITIALIZED IN THE ORDER IN WHICH THEY APPEAR IN THE
; GDT_DEF STRUCTURE DEFINITION AS IT APPEARS IN INDEDAT.INC. This data
; area will be copied from the code segment to the final GDT resting
; place during initialization.
GDT_DATA_START LABEL WORD
; First entry is unusable
DESCR_DEF SEG, 0, 0, 0, 0
; The descriptor for GDT itself
DESCR_DEF SEG, GDT_LEN, GDT_LOC, 3, CPL0_DATA_ACCESS
PAGE
; The system IDT descriptor
DESCR_DEF SEG, SIDT_LEN, SIDT_LOC, 3, CPL0_DATA_ACCESS
; The real system data area descriptor (XMA pages)
DESCR_DEF SEG, 0FFFFH, 0000H, 11H, CPL0_DATA_ACCESS
; The virtual IDT descriptor (not needed so use for all memory)
DESCR_DEF SEG, MAX_SEG_LEN, NSEG@_LO, NSEG@_HI, CPL0_DATA_ACCESS
; The LOADALL descriptor
DESCR_DEF SEG, 0, 0, 0, 0
PAGE
; Compatible monochrome display
DESCR_DEF SEG, MCRT_SIZE, MCRT@_LO, MCRT@_HI, CPL0_DATA_ACCESS
; Compatible color display
DESCR_DEF SEG, CCRT_SIZE, CCRT@_LO, CCRT@_HI, CPL0_DATA_ACCESS
; Enhanced color display - one entry for each 64K P1C
DESCR_DEF SEG, ECCRT_SIZE, ECCRT@_LO_LO, ECCRT@_LO_HI, CPL0_DATA_ACCESS
; Second part of enhanced display P1C
DESCR_DEF SEG, ECCRT_SIZE, ECCRT@_HI_LO, ECCRT@_HI_HI, CPL0_DATA_ACCESS
PAGE
; Code segment for ROM code, system IDT
DESCR_DEF SEG, MAX_SEG_LEN, CSEG@_LO, CSEG@_HI, CPL0_CODE_ACCESS
; Data segment for ROM code, system IDT
DESCR_DEF SEG, MAX_SEG_LEN, CSEG@_LO, CSEG@_HI, CPL0_CODE_ACCESS
; Temporarily, the monitor is installed using the patch
; segment descriptors in the GDT
MSEG@_LO EQU 00000H
MSEG@_HI EQU 008H
; Code segment for patch code, system IDT
DESCR_DEF SEG, MAX_SEG_LEN, MSEG@_LO, MSEG@_HI, CPL0_CODE_ACCESS
; Data segment for patch code, system IDT
DESCR_DEF SEG, MAX_SEG_LEN, MSEG@_LO, MSEG@_HI, CPL0_DATA_ACCESS
PAGE
; Code segment for ROM code, virtual IDT
DESCR_DEF SEG, MAX_SEG_LEN, CSEG@_LO, CSEG@_HI, CPL0_CODE_ACCESS
; Data segment for ROM code, virtual IDT
DESCR_DEF SEG, MAX_SEG_LEN, CSEG@_LO, CSEG@_HI, CPL0_CODE_ACCESS
; Code segment for patch code, virtual IDT
DESCR_DEF SEG, NULL_SEG_LEN, NSEG@_LO, NSEG@_HI, NULL_ACCESS
; Data segment for patch code, virtual IDT
DESCR_DEF SEG, NULL_SEG_LEN, NSEG@_LO, NSEG@_HI, NULL_ACCESS
PAGE
; Temporary descriptors for ES, CS, SS, and DS
DESCR_DEF SEG, MAX_SEG_LEN, NSEG@_LO, NSEG@_HI, CPL0_DATA_ACCESS
DESCR_DEF SEG, MAX_SEG_LEN, NSEG@_LO, NSEG@_HI, CPL0_CODE_ACCESS
DESCR_DEF SEG, MAX_SEG_LEN, NSEG@_LO, NSEG@_HI, CPL0_DATA_ACCESS
DESCR_DEF SEG, MAX_SEG_LEN, NSEG@_LO, NSEG@_HI, CPL0_DATA_ACCESS
PAGE
; These DQ's pad out the space between the last MultiPC descriptor and the
; PMVM descriptors. They don't need initialization.
DQ 9 DUP (0) ; These 9 are for the Monitor descriptors
; This is for the keyboard owner (not used)
DQ 0
; These 16 are for the virtual timer support
DQ 16 DUP (0)
; The following 32 descriptors are for exception condition task gates.
REPT 32
DQ 0
ENDM
; The following 16 pairs are for the hardware interrupt handling tasks.
REPT 16
DQ 0
DQ 0
ENDM
; The following pair is for the DISPATCH task
DESCR_DEF SEG, TSS_LEN, DISPATCH_LOC, 3, <TSS_ACCESS OR FREE_TSS>
DESCR_DEF SEG, TSS_LEN, DISPATCH_LOC, 3, CPL0_DATA_ACCESS
DESCR_DEF SEG, 0, 0, 0,LDT_DESC
; BASIC's segment
DESCR_DEF SEG, 07FFFH, 06000H, 0FH, CPL0_DATA_ACCESS
; BIOS's segment
DESCR_DEF SEG, 01FFFH, 00000H, 0FH, CPL0_DATA_ACCESS
DQ 13 DUP (0) ; Reserved guys
; The following guys are junk ! Used before the first TSS allocated. These
; have to be in the PMVM location in the GDT.
DESCR_DEF SEG, TSS_LEN, 0C000H, 0, FREE_TSS ; For the TR
DESCR_DEF SEG, TSS_LEN, 0C000H, 0, CPL0_DATA_ACCESS ; TSS as data
DESCR_DEF SEG, GDT_LEN, 0D000H, 0, LDT_DESC ; For the LDTR
DESCR_DEF SEG, GDT_LEN, 0D000H, 0, CPL0_DATA_ACCESS ; LDT as data
GDT_DATA_END LABEL WORD
COPY_LEN EQU GDT_DATA_END-GDT_DATA_START
;
; End of pre-allocated GDT
;
PAGE
GDT_BLD PROC NEAR
; Copy the pre-initialized GDT into its proper location in memory
CLI ; All string operations go forward
MOV SI,OFFSET GDT_DATA_START ; DS:SI points to the pre-initialized
; GDT above
MOV CX,COPY_LEN/2 ; CX = number of words to copy
MOV DI,GDT_LOC ; ES:DI points to the GDT location
REP MOVSW ; Copy GDT into its final resting place
; Now let's initialize some of the GDT entries
; Set up the descriptors for our code segment and data segment
MOV AX,CS ; Get our CS
CALL SREG_2_24BITS ; And convert it to a 24 bit offset
MOV BX,AX ; Get the monitor offset
ALLSET:
DESCR_INIT SEG, SYS_PATCH_CS, 07FFFH, BX, DH, CPL0_CODE_ACCESS
DESCR_INIT SEG, SYS_PATCH_DS, 0FFFFH, BX, DH, CPL0_DATA_ACCESS
; Initialize the descriptor for the GDT
MOV AX,ES ; Get the segment of the GDT
CALL SREG_2_24BITS ; Convert to a 24 bit offset
MOV DL,DH ; Save a copy of the hi byte
MOV BX,GDT_LOC ; Add on the offset of the GDT
CALL ADDOFF
DESCR_INIT SEG, GDT_PTR, GDT_LEN, BX, DH, CPL0_DATA_ACCESS
; Initialize the descriptor for the IDT
MOV BX,SIDT_LOC ; DH,AX already contains the segment
; converted to 24 bits so all we
CALL ADDOFF ; have to do is add on the offset
DESCR_INIT SEG, MON_IDT_PTR, SIDT_LEN, BX, DH, CPL0_DATA_ACCESS
; Initialize the descriptor that accesses all of memory as data
DESCR_INIT BSEG, HUGE_PTR, 0FFFFH, 0, 0, CPL0_DATA_ACCESS
; Initialize the descriptors for the V86 task's LDT
MOV BX,DISPATCH_LOC ; @P3C
CALL ADDOFF
DESCR_INIT SEG,SCRUBBER.VM_LDTR,00FFFH,BX,DH,LDT_DESC
DESCR_INIT SEG,SCRUBBER.LDT_PTR,00FFFH,BX,DH,CPL0_DATA_ACCESS
; Initialize the descriptors for the V86 task's TR
MOV BX,DISPATCH_LOC ; @P3C
CALL ADDOFF
DESCR_INIT SEG,SCRUBBER.VM_TR,TSS_LEN,BX,DH,FREE_TSS_386 ; @P3C
DESCR_INIT SEG,SCRUBBER.TSS_PTR,TSS_LEN,BX,DH,CPL0_DATA_ACCESS; @P3C
RET
GDT_BLD ENDP
PAGE
; SREG_2_24BITS converts the segment register 16 bit value in the AX register
; into a 24 bit value in DH and AX
;
; Input : AX = segment register value
;
; Output: AX = 24 bit low word
; DH = 24 bit high byte
SREG_2_24BITS PROC NEAR
; Put the high four bits of AH into the low four bits of DH
MOV DH,AH ; Get the high byte of the segment value
; into DH
AND DH,0F0H ; Strip off the low nibble
SHR DH,4 ; Shift right four bits
; Now shift AX left four bits
AND AH,00FH ; Strip high nibble from AH
; This keeps the carry flag from being
; set which could effect later ADDs.
SHL AX,4 ; Shift AX
RET
SREG_2_24BITS ENDP
PAGE
; ADDOFF adds the 16 bit offset in BX to the 24 bit value in DL and AX. The
; result is left in DH and BX.
;
; Input : DL = 24 bit high byte
; AX = 24 bit low word
; BX = offset to be added
;
; Output: DH = 24 bit high byte
; BX = 24 bit low word
ADDOFF PROC NEAR
MOV DH,DL ; Restore the high byte that was saved
; in DL
ADD BX,AX ; Add on the offset
ADC DH,0 ; Add the carry, if any, to the high
; byte
RET
ADDOFF ENDP
PROG ENDS
END
|