rev |
line source |
pascal@23996
|
1 ;***************************************************************
|
pascal@23996
|
2 ;****** This file is distributed under GPL
|
pascal@23996
|
3 ;***************************************************************
|
pascal@23996
|
4 ;VDPI init:
|
pascal@23996
|
5 ;Call char* prepare_vcpi(void *pagebuf) first to
|
pascal@23996
|
6 ;initialize paging tables needed for vm86.
|
pascal@23996
|
7 ;pagebuf needs to be 8k+4 bytes. Returns ptr to 1st unused byte.
|
pascal@23996
|
8 ;Then call int get_vcpi_interface(). Returns 1 if ok, 0 if bad.
|
pascal@23996
|
9 ;
|
pascal@23996
|
10 ;VCPI use:
|
pascal@23996
|
11 ;u32* malloc_vcpi(u32 size) - source in HIMEM.CPP
|
pascal@23996
|
12 ; Returns ptr to mallocated zero-terminated list of 4k page addrs
|
pascal@23996
|
13 ; Addresses are sorted in ascending order
|
pascal@23996
|
14 ; Never fails (will die if not enough mem)
|
pascal@23996
|
15 ;void read2vcpi(int fd, u32* vp, u32 size,
|
pascal@23996
|
16 ;void* xfer_buf, u16 xfer_size) - source in HIMEM.CPP
|
pascal@23996
|
17 ; Reads opened fd data into malloc_vcpi'ed memory
|
pascal@23996
|
18 ; Dies if file isn't exactly 'size' bytes long
|
pascal@23996
|
19 ; Needs intermediate buffer of exactly Nx4k bytes
|
pascal@23996
|
20 ;void memcpy_vcpi(u32 dstofs,u16 srcseg,u32 srcofs)
|
pascal@23996
|
21 ; copies 4k from conventional memory to VCPI
|
pascal@23996
|
22 ;void _vm2rm()
|
pascal@23996
|
23 ; switches you from vm86 to plain real mode
|
pascal@23996
|
24
|
pascal@23996
|
25
|
pascal@23996
|
26 ideal
|
pascal@23996
|
27 %PAGESIZE 1000
|
pascal@23996
|
28 %crefref
|
pascal@23996
|
29 %noincl
|
pascal@23996
|
30 %nomacs
|
pascal@24019
|
31
|
pascal@24019
|
32 include "common.inc"
|
pascal@24019
|
33
|
pascal@24019
|
34 ifdef VCPI
|
pascal@23996
|
35 p386
|
pascal@23996
|
36
|
pascal@23996
|
37 ;****** Stuff for declaring descriptors
|
pascal@23996
|
38 struc descr
|
pascal@23996
|
39 limit dw ?
|
pascal@23996
|
40 base0 dw ?
|
pascal@23996
|
41 base16 db ?
|
pascal@23996
|
42 type db ?
|
pascal@23996
|
43 limit16 db ?
|
pascal@23996
|
44 base24 db ?
|
pascal@23996
|
45 ends descr
|
pascal@23996
|
46 macro descriptor name,typ,plevel,present,limit,gran,base
|
pascal@23996
|
47 ;;name descr <limit and 0ffffh,base and 0ffffh,low (base shr 16),typ or plevel or present,(limit shr 16) or gran,high (base shr 16)>
|
pascal@23996
|
48 name descr <limit and 0ffffh,base ,0 ,typ or plevel or present,(limit shr 16) or gran,0 >
|
pascal@23996
|
49 endm
|
pascal@23996
|
50 ; decriptor types (bit0..4 of descr.type )
|
pascal@23996
|
51 tss386_avail = 09h
|
pascal@23996
|
52 data_seg = 00010000b ; data segment
|
pascal@23996
|
53 expand_down = 00000100b ; =1 limit counts down from base
|
pascal@23996
|
54 writable = 00000010b ; =1 if write access allowed to data segment
|
pascal@23996
|
55 code_seg = 00011000b ; code segment
|
pascal@23996
|
56 conforming = 00000100b ; =1 code can be accesses and executed at any PL
|
pascal@23996
|
57 readable = 00000010b ; =1 if code also can be read (cannot be ovwritten)
|
pascal@23996
|
58 ; privilege levels (bit5..6 of descr.type )
|
pascal@23996
|
59 priv0 = 00000000b
|
pascal@23996
|
60 priv1 = 00100000b
|
pascal@23996
|
61 priv2 = 01000000b
|
pascal@23996
|
62 priv3 = 01100000b
|
pascal@23996
|
63 ; segment present bit (bit7 of descr.type )
|
pascal@23996
|
64 is_present = 10000000b
|
pascal@23996
|
65 not_present = 00000000b
|
pascal@23996
|
66 ;definition of granularity ( bits6..7 in descr.limit16 )
|
pascal@23996
|
67 gran_byte = 00000000b
|
pascal@23996
|
68 gran_page = 10000000b ; 4k granularity
|
pascal@23996
|
69 use_16 = 00000000b
|
pascal@23996
|
70 use_32 = 01000000b
|
pascal@23996
|
71
|
pascal@23996
|
72 ;****** rm32,imm16 helper
|
pascal@23999
|
73 macro movzx_e rm,i
|
pascal@23999
|
74 db 66h
|
pascal@23999
|
75 mov rm,i
|
pascal@23999
|
76 dw 0
|
pascal@23996
|
77 endm
|
pascal@23996
|
78
|
pascal@23999
|
79 macro pushd sreg
|
pascal@23999
|
80 db 66h
|
pascal@23999
|
81 push sreg
|
pascal@23996
|
82 endm
|
pascal@23996
|
83
|
pascal@23996
|
84 group DGROUP _TEXT
|
pascal@23996
|
85 assume cs:DGROUP,ds:DGROUP
|
pascal@23996
|
86
|
pascal@23996
|
87 segment _TEXT byte public use16 'CODE'
|
pascal@23996
|
88
|
pascal@23996
|
89 ;***************************************************************
|
pascal@23996
|
90 ;int get_vcpi_interface();
|
pascal@23996
|
91 ;****** Return: Z - page mapping for low 640k is 1:1
|
pascal@23996
|
92 ;****** NZ - otherwise (it's bad)
|
pascal@23996
|
93 ;****** Uses: Flags
|
pascal@23996
|
94 ;***************************************************************
|
pascal@23996
|
95 ;global _get_vcpi_interface:near
|
pascal@23996
|
96 proc _get_vcpi_interface near
|
pascal@23996
|
97
|
pascal@23996
|
98 ;push si di
|
pascal@23996
|
99
|
pascal@23996
|
100 ; Get and save VCPI pm interface
|
pascal@23996
|
101 ;mov si,offset gdt_vcpi ;DS:DI => 3 GDT entries for VCPI
|
pascal@23996
|
102 ;mov di,[si+page0_ofs-gdt_vcpi] ;ES:DI => page0
|
pascal@23996
|
103 ;push ds
|
pascal@23996
|
104 ;pop es
|
pascal@23996
|
105 ;push di
|
pascal@23996
|
106 ;mov ax,0DE01h ;get vcpi pm interface
|
pascal@23996
|
107 int 67h
|
pascal@23996
|
108 xchg [si+vcpi_pm_entry-gdt_vcpi],ebx ; bx=((640*1024) shr 12)
|
pascal@23996
|
109
|
pascal@23996
|
110 ; Check that mapping for low 640k is 1:1
|
pascal@23996
|
111 pop si ; [page0_ofs]
|
pascal@23996
|
112 ;cld
|
pascal@24013
|
113 mov cx,bx
|
pascal@23996
|
114 @@map_chk:
|
pascal@24013
|
115 lodsd
|
pascal@24013
|
116 shr eax,12
|
pascal@24013
|
117 add ax,cx
|
pascal@24013
|
118 ;cmp eax,ebx ; ((640*1024) shr 12)
|
pascal@24013
|
119 cmp ax,bx ; ((640*1024) shr 12)
|
pascal@24013
|
120 loope @@map_chk
|
pascal@24013
|
121 ;pop di si
|
pascal@23996
|
122 ret
|
pascal@24013
|
123
|
pascal@23996
|
124 endp _get_vcpi_interface
|
pascal@23996
|
125
|
pascal@23996
|
126
|
pascal@23996
|
127 ;***************************************************************
|
pascal@23996
|
128 ;char* prepare_vcpi(void *pagebuf);
|
pascal@23996
|
129 ;****** Return: AX=>first unused byte in pagebuf
|
pascal@23996
|
130 ;****** Uses: Flags
|
pascal@23996
|
131 ;***************************************************************
|
pascal@23996
|
132 global prepare_vcpi:near
|
pascal@23996
|
133 proc prepare_vcpi near
|
pascal@23996
|
134
|
pascal@23996
|
135 ;Calculate pagedir/page0 addrs, initialize cr3 and pagedir[0]
|
pascal@23996
|
136 ; heap_top = prepare_vcpi(malloc_or_die(8*1024+4));
|
pascal@23996
|
137
|
pascal@23996
|
138 ;mov edx,cs
|
pascal@23996
|
139 ;shl edx,4 ;edx = linear addr of CS
|
pascal@23996
|
140 mov si,offset gdt_vcpi
|
pascal@23996
|
141 ; Fix up base of some gdt descriptors
|
pascal@23996
|
142 ; Note: 'add [dword xx.base0],edx' actually updates 24 bit quantity!
|
pascal@23996
|
143 ; Do NOT replace with mov!
|
pascal@24013
|
144 mov bx,10000h-28h
|
pascal@23996
|
145 add [dword si+sw2pm_addr-gdt_vcpi],edx
|
pascal@23996
|
146 add [dword si+sw2pm_idtr_ptr-gdt_vcpi],edx
|
pascal@23996
|
147 @@fixup:
|
pascal@23996
|
148 add [dword bx+si+(gdt_code.base0)-gdt_vcpi+28h],edx
|
pascal@23996
|
149 add bx,8
|
pascal@23996
|
150 js @@fixup
|
pascal@23996
|
151 mov bh,10h
|
pascal@23996
|
152 extrn _heap_top:word
|
pascal@24013
|
153 ;movzx eax,[_heap_top]
|
pascal@24013
|
154 mov ax,[_heap_top]
|
pascal@24013
|
155 add ax,bx ; assume _heap_top < 0f000h
|
pascal@23996
|
156 add eax,edx
|
pascal@23996
|
157 and ax,0f000h ;eax = 4k aligned linear addr of pagebuf
|
pascal@24013
|
158 add [si+sw2pm_cr3-gdt_vcpi],eax ;eax=page0 linear addr
|
pascal@23996
|
159 mov edi,eax
|
pascal@23996
|
160 sub edi,edx
|
pascal@23996
|
161 mov al,3 ;add present+writable bits
|
pascal@23996
|
162 mov [bx+di],eax ;stuff it into pagedir[0]
|
pascal@24022
|
163 ;push ds
|
pascal@24022
|
164 ;pop es ;es:di->page0,es:di+1000h->pagedir
|
pascal@23996
|
165 ;page directory will use only one entry (4 bytes):
|
pascal@23996
|
166 ;cr3 => pagedir => page0 => ########
|
pascal@23996
|
167 ; (1 entry) (1024 => # 4M #
|
pascal@23996
|
168 ; entries)=> # page #
|
pascal@23996
|
169 ; => ########
|
pascal@23996
|
170 ; Return
|
pascal@23996
|
171 lea ax,[bx+di+4]
|
pascal@23996
|
172 mov [_heap_top],ax
|
pascal@23996
|
173 ;ret
|
pascal@23996
|
174 push di
|
pascal@23996
|
175 mov ax,0DE01h ;get vcpi pm interface
|
pascal@23996
|
176 jmp _get_vcpi_interface
|
pascal@23996
|
177
|
pascal@23996
|
178 endp prepare_vcpi
|
pascal@23996
|
179
|
pascal@23996
|
180 org $-40
|
pascal@23996
|
181 tss dd ?,? ;enough, we'll never use it anyway
|
pascal@23996
|
182 label gdt byte
|
pascal@23996
|
183 gdt_null descr <?> ;0000
|
pascal@23996
|
184 gdt_vcpi descr <?> ;0008
|
pascal@23996
|
185 gdt_vcpi2 descr <?> ;0010
|
pascal@23996
|
186 gdt_vcpi3 descr <?> ;0018
|
pascal@23996
|
187 org $-8
|
pascal@23996
|
188 global gdt_memcpy:descr
|
pascal@24013
|
189 gdt_memcpy descr <?> ;null + gdt_abs
|
pascal@23996
|
190 descriptor gdt_abs ,(data_seg+writable),priv0,is_present,0fffffh,(gran_page+use_32),0
|
pascal@23996
|
191 ;Note: code/data segs must be flagged use16 (i.e. use ip/sp, not eip/esp)
|
pascal@23996
|
192 ;Note: base addrs will be fixed up in prepare_vcpi()
|
pascal@23996
|
193 descriptor gdt_code,(code_seg+readable),priv0,is_present,0fffffh,(gran_page+use_16),0
|
pascal@20751
|
194 global gdt_data:descr
|
pascal@23996
|
195 descriptor gdt_data,(data_seg+writable),priv0,is_present,0fffffh,(gran_page+use_16),0
|
pascal@23996
|
196 descriptor gdt_tss ,tss386_avail ,priv0,is_present,0ffh ,gran_byte ,<offset tss>
|
pascal@23996
|
197 SEL_VCPI = (gdt_vcpi - gdt_null)
|
pascal@23996
|
198 SEL_TSS = (gdt_tss - gdt_null)
|
pascal@23996
|
199 SEL_ABS = (gdt_abs - gdt_null)
|
pascal@23996
|
200 SEL_CODE = (gdt_code - gdt_null)
|
pascal@23996
|
201 SEL_DATA = (gdt_data - gdt_null)
|
pascal@23996
|
202
|
pascal@23996
|
203 label gdtr pword
|
pascal@23996
|
204 gdt_lim dw 0ffffh
|
pascal@23996
|
205 gdt_base dw offset gdt,0
|
pascal@23996
|
206
|
pascal@23996
|
207 ;Note: layout dictated by vcpi api, don't rearrange!
|
pascal@23996
|
208 label sw2pm_params byte
|
pascal@23996
|
209 ;Note: base addrs will be fixed up in prepare_vcpi()
|
pascal@23996
|
210 label pagedir_laddr dword
|
pascal@23996
|
211 sw2pm_cr3 dd 1000h
|
pascal@23996
|
212 sw2pm_gdtr_ptr dw offset gdtr,0
|
pascal@23996
|
213 sw2pm_idtr_ptr dw offset idtr,0
|
pascal@23996
|
214 sw2pm_ldtr dw 0 ;we don't need it
|
pascal@23996
|
215 sw2pm_tr dw SEL_TSS ;vcpi thinks we need it... can't set to 0
|
pascal@24013
|
216 sw2pm_jumpaddr dw offset pmode,0
|
pascal@23996
|
217 dw SEL_CODE
|
pascal@23996
|
218
|
pascal@23996
|
219 vcpi_pm_entry dd ((640*1024) shr 12)
|
pascal@23996
|
220 dw SEL_VCPI
|
pascal@23996
|
221
|
pascal@23996
|
222 label idtr pword
|
pascal@23996
|
223 idt_lim dw 03ffh ;we won't enable ints,
|
pascal@23996
|
224 idt_base dd 0 ; so let's leave it the same as for rm
|
pascal@23996
|
225
|
pascal@23996
|
226
|
pascal@23996
|
227 ;***************************************************************
|
pascal@23996
|
228 ;void memcpy_vcpi(u32 dstofs,u16 srcseg,u32 srcofs);
|
pascal@23996
|
229 ;***************************************************************
|
pascal@23996
|
230 ;****** Copies PAGE_SIZE bytes
|
pascal@23996
|
231 ;****** Uses: Flags
|
pascal@23996
|
232 ;***************************************************************
|
pascal@23996
|
233 global vcpi_pm_copy_routine:near
|
pascal@23996
|
234 proc vcpi_pm_copy_routine near
|
pascal@23996
|
235
|
pascal@23996
|
236 struc pm_regs
|
pascal@23996
|
237 $$retaddr dw ?
|
pascal@23996
|
238 $$edi dd ?
|
pascal@23996
|
239 $$esi dd ?
|
pascal@23996
|
240 $$ebp dd ?
|
pascal@23996
|
241 $$esp dd ?
|
pascal@23996
|
242 $$ebx dd ?
|
pascal@23996
|
243 $$edx dd ?
|
pascal@23996
|
244 $$ecx dd ?
|
pascal@23996
|
245 $$eax dd ?
|
pascal@23996
|
246 ends
|
pascal@23996
|
247
|
pascal@23996
|
248 ;***************************************************************
|
pascal@23996
|
249 ;****** Helper: goes into 16bit pm and calls routine (addr on stk)
|
pascal@23996
|
250 ;***************************************************************
|
pascal@23996
|
251 mov bp,sp ; ss:bp => struct pm_regs
|
pascal@23996
|
252
|
pascal@23999
|
253 mov bx,5 ; IRET stack for return to vm
|
pascal@23999
|
254 @@push_sreg:
|
pascal@23999
|
255 pushd ss ; fake pushd gs fs ds es ss
|
pascal@23999
|
256 dec bx
|
pascal@23999
|
257 jnz @@push_sreg ; (9 dwords)
|
pascal@23996
|
258 push ebp ; esp
|
pascal@23996
|
259 pushfd ; eflags: IF saved here
|
pascal@23996
|
260 pushd cs ;
|
pascal@23999
|
261 push bx ;\eip
|
pascal@23999
|
262 push offset vcpi_ret ;/
|
pascal@23996
|
263
|
pascal@24013
|
264 mov edx,esi
|
pascal@24013
|
265 switch_to_pm:
|
pascal@24013
|
266 movzx_e si,<offset sw2pm_params>
|
pascal@24013
|
267 org $-4
|
pascal@24013
|
268 sw2pm_addr dd ?
|
pascal@24013
|
269 mov ax,0DE0Ch ; vcpi: switch to pm
|
pascal@24013
|
270 cli ; load GDTR LDTR TR need 16 bytes in SS:ESP
|
pascal@24013
|
271 int 67h ; EAX, ESI, DS, ES, FS, GS destroyed
|
pascal@24013
|
272 pmode:
|
pascal@23996
|
273 assume nothing
|
pascal@23996
|
274 assume cs:DGROUP
|
pascal@23996
|
275
|
pascal@23996
|
276 ; Now we are in 16-bit protected mode
|
pascal@24013
|
277 push SEL_DATA
|
pascal@24013
|
278 pop ss
|
pascal@24013
|
279 test bx,bx
|
pascal@24013
|
280 jnz vm2rm_end
|
pascal@24013
|
281
|
pascal@24013
|
282 ;lea sp,[bp-8-9*4]
|
pascal@24013
|
283 lea sp,[bp-9*4]
|
pascal@23996
|
284
|
pascal@23996
|
285 ; Call the routine (bp points to params on stack if any)
|
pascal@23999
|
286 call do_memcpy_vcpi ; set ds=all_addrspace
|
pascal@23996
|
287
|
pascal@23996
|
288 ; Ok, let's return to vm
|
pascal@23996
|
289 mov ax,0DE0Ch ; maybe we need whole eax?
|
pascal@23996
|
290 cli ; to be safe
|
pascal@23996
|
291 clts ;
|
pascal@23999
|
292 ; Go to vm86 mode. Sregs, esp, eflags (IF) restored from IRET stack
|
pascal@24013
|
293 call [pword cs:vcpi_pm_entry]
|
pascal@24013
|
294 ret
|
pascal@24013
|
295 ;jmp [pword cs:vcpi_pm_entry]
|
pascal@23996
|
296
|
pascal@23996
|
297 ;***************************************************************
|
pascal@23996
|
298
|
pascal@23996
|
299 ;***************************************************************
|
pascal@23996
|
300 ;****** Helper: This is where real copy is done
|
pascal@23996
|
301 ;***************************************************************
|
pascal@23996
|
302 label do_memcpy_vcpi near
|
pascal@23996
|
303
|
pascal@23996
|
304 push SEL_ABS
|
pascal@23996
|
305 pop ds
|
pascal@23996
|
306 push ds
|
pascal@23996
|
307 pop es
|
pascal@23996
|
308 assume nothing
|
pascal@23996
|
309 assume cs:DGROUP
|
pascal@23996
|
310
|
pascal@23996
|
311 ; Set up target addr:
|
pascal@23996
|
312 ; replace page mapping for page at 0 so
|
pascal@23996
|
313 ; that it points to dstofs
|
pascal@23996
|
314 xchg eax,edi
|
pascal@23996
|
315 mov al,03h ; writeable, present
|
pascal@23996
|
316 call @@set_mapping
|
pascal@23996
|
317 xor edi,edi ;es:edi => remapped page
|
pascal@23996
|
318
|
pascal@23996
|
319 ; Set up source addr
|
pascal@23996
|
320 mov esi,edx
|
pascal@23996
|
321
|
pascal@23996
|
322 ; Do copying
|
pascal@23996
|
323 db 67h ;address width override for esi/edi
|
pascal@23996
|
324 rep movsb
|
pascal@23996
|
325
|
pascal@23996
|
326 @@set_mapping:
|
pascal@23996
|
327 mov esi,[cs:sw2pm_cr3]
|
pascal@23996
|
328 xchg [esi-1000h],eax ; restore page0[0]
|
pascal@23996
|
329 mov esi,cr3 ; reload TLB cache
|
pascal@23996
|
330 mov cr3,esi ;
|
pascal@23996
|
331 ; Return
|
pascal@19907
|
332 vcpi_ret:
|
pascal@23996
|
333 ret
|
pascal@23996
|
334
|
pascal@23996
|
335 endp vcpi_pm_copy_routine
|
pascal@23996
|
336
|
pascal@23996
|
337
|
pascal@23996
|
338 ;***************************************************************
|
pascal@23996
|
339 ;void _vm2rm();
|
pascal@23996
|
340 ;***************************************************************
|
pascal@23996
|
341 ;****** Uses: Flags
|
pascal@23996
|
342 ;***************************************************************
|
pascal@24013
|
343 global _vm2rm:far
|
pascal@24013
|
344 proc _vm2rm far
|
pascal@23996
|
345
|
pascal@23996
|
346 assume cs:DGROUP,ds:DGROUP
|
pascal@24013
|
347 push ds
|
pascal@24014
|
348 extrn sssp:dword
|
pascal@24014
|
349 mov bx,offset sssp
|
pascal@24014
|
350 mov [bx],sp
|
pascal@24014
|
351 ;mov [bx+2],ss
|
pascal@24013
|
352 ifdef QUICK_BOOT
|
pascal@24013
|
353 extrn _cmdnum:dword
|
pascal@24013
|
354 v86boot = (byte _cmdnum+24)
|
pascal@24014
|
355 test [v86boot],bh
|
pascal@24013
|
356 jnz @vm2rm_ret
|
pascal@24013
|
357 endif
|
pascal@23996
|
358 ifdef NO386
|
pascal@23996
|
359 extrn _vcpi:byte
|
pascal@23996
|
360 test [_vcpi],bh
|
pascal@23996
|
361 else
|
pascal@23996
|
362 smsw ax ;SMSW cannot be trapped! :-)
|
pascal@23996
|
363 and al,1 ;MSW_PE
|
pascal@23996
|
364 endif
|
pascal@24013
|
365 jz @vm2rm_ret
|
pascal@24013
|
366 jmp switch_to_pm ; EAX, ESI, DS, ES, FS, GS destroyed
|
pascal@24013
|
367 vm2rm_end:
|
pascal@23996
|
368 assume nothing
|
pascal@23996
|
369 assume cs:DGROUP
|
pascal@23996
|
370
|
pascal@24013
|
371 ;push ss
|
pascal@24013
|
372 ;pop ds
|
pascal@24013
|
373
|
pascal@23996
|
374 ; Now we are in 16-bit protected mode
|
pascal@23996
|
375 ; Black magic here
|
pascal@23996
|
376 mov eax,cr0
|
pascal@23996
|
377 and eax,7ffffffeh ; clear PG,P bits
|
pascal@23996
|
378 mov cr0,eax ; look mommy, we're in rm now!
|
pascal@23996
|
379 mov cr3,eax ; flush TLB cache
|
pascal@23996
|
380
|
pascal@23996
|
381 ; Now we are in rm, but not yet: have to restore sregs:
|
pascal@23996
|
382 lss sp,[cs:bx] ; SS
|
pascal@24013
|
383 @vm2rm_ret:
|
pascal@23996
|
384 pop ds ; DS
|
pascal@23996
|
385 retf ; CS
|
pascal@23996
|
386
|
pascal@23996
|
387 endp _vm2rm
|
pascal@23996
|
388
|
pascal@23996
|
389 ends _TEXT
|
pascal@24019
|
390 else
|
pascal@24019
|
391
|
pascal@24019
|
392 group DGROUP _TEXT
|
pascal@24019
|
393 assume cs:DGROUP,ds:DGROUP
|
pascal@24019
|
394
|
pascal@24019
|
395 segment _TEXT byte public use16 'CODE'
|
pascal@24019
|
396 global gdt_data:near
|
pascal@24019
|
397 gdt_data:
|
pascal@24019
|
398 ends _TEXT
|
pascal@24019
|
399
|
pascal@24019
|
400 endif
|
pascal@23996
|
401
|
pascal@23996
|
402 end
|
pascal@23996
|
403
|
pascal@23996
|
404 ;###### END OF FILE ############################################
|