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