]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/MEMM/MEMM/RETREAL.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / MEMM / MEMM / RETREAL.ASM
1
2
3 page 58,132
4 ;******************************************************************************
5 title RetReal - Return-To-Real routine(s) for the 386
6 ;******************************************************************************
7 ;
8 ; (C) Copyright MICROSOFT Corp. 1986
9 ;
10 ; Title: MEMM.EXE - MICROSOFT Expanded Memory Manager 386 Driver
11 ;
12 ; Module: RetReal - Return-To-Real routine(s) for the 386
13 ;
14 ; Version: 0.04
15 ;
16 ; Date: February 20, 1986
17 ;
18 ; Author:
19 ;
20 ;******************************************************************************
21 ;
22 ; Change log:
23 ;
24 ; DATE REVISION DESCRIPTION
25 ; -------- -------- -------------------------------------------------------
26 ; 02/20/86 Original
27 ; 05/12/86 A Cleanup and segment reorganization
28 ; 06/01/86 Removed Real386a (loadall version) and left only
29 ; RetReal via PE bit
30 ; 06/21/86 0.02 Saved Eax
31 ; 06/28/86 0.02 Name changed from MEMM386 to MEMM
32 ; 07/02/86 0.03 Reset TSS busy bit
33 ; 07/05/86 0.04 Added Real_Seg label for _TEXT fixup
34 ; 07/06/86 0.04 changed assume to DGROUP
35 ;
36 ;******************************************************************************
37 ;
38 ; Functional Description:
39 ;
40 ; This module contains the routine RetReal which goes from Ring 0 protected
41 ; mode to Real Mode by resetting the PE bit (and the PG bit).
42 ;
43 ; NOTE: this module only works on the B0 and later parts. The A2 part
44 ; will leave the CS non writeable.
45 ;
46 ;******************************************************************************
47 .lfcond ; list false conditionals
48 .386p
49 page
50 ;******************************************************************************
51 ; P U B L I C D E C L A R A T I O N S
52 ;******************************************************************************
53 ;
54 public RetReal
55 public Real_Seg
56
57 page
58 ;******************************************************************************
59 ; I N C L U D E F I L E S
60 ;******************************************************************************
61
62 include VDMSEG.INC
63 include VDMSEL.INC
64 include INSTR386.INC
65 include OEMDEP.INC
66
67 ;
68 ;******************************************************************************
69 ; E X T E R N A L R E F E R E N C E S
70 ;******************************************************************************
71 ;
72 _DATA segment
73 extrn Active_Status:byte
74 _DATA ends
75
76 _TEXT segment
77
78 extrn SelToSeg:near ; selector to segment (I286)
79 extrn DisableA20:near ; disable A20 line (MODESW)
80
81 _TEXT ends
82 ;******************************************************************************
83 ; L O C A L C O N S T A N T S
84 ;******************************************************************************
85 ;
86 FALSE equ 0
87 TRUE equ not FALSE
88
89 page
90 ;******************************************************************************
91 ; S E G M E N T D E F I N I T I O N
92 ;******************************************************************************
93
94 _TEXT segment
95 assume cs:_TEXT, ds:DGROUP
96
97 ;*** RetReal - cause a 386 mode switch to real mode
98 ;
99 ; ENTRY Ring 0 protected mode
100 ; CLI - interrupts disabled
101 ; NMI should also be disabled here.
102 ifndef NOHIMEM
103 ; FS = Diag segment selector
104 endif
105 ;
106 ; EXIT Real Mode
107 ; DGROUP:[Active_Status] = 0
108 ; CS = _TEXT
109 ; DS = ES = FS = GS = DGROUP
110 ; SS = stack segment
111 ; general registers preserved
112 ; flags modified
113 ; interrupts disabled
114 ; A20 disabled
115 ifndef NOHIMEM
116 ; high system memory LOCKED
117 endif
118 ;
119 ; USES see exit conditions above
120 ;
121 ; DESCRIPTION
122 ;
123 real_gdt label qword
124 real_idt dw 0FFFFh ; limit
125 dw 0000 ; base
126 dw 0000
127 dw 0000 ; just in case
128
129 public RetReal
130 RetReal proc near
131 PUSH_EAX ; save two scratch registers
132 push bx
133 cli ; disable ints
134
135 smsw ax ;check to see if we are in real mode
136 test ax,1
137 jnz rl386_a ;jump if in protected mode
138 sti
139 pop bx
140 POP_EAX
141 ret ;otherwise return
142
143 rl386_a:
144
145 ;
146 ; reset TSS busy bit before returning to Real Mode
147 ;
148 mov ax, GDTD_GSEL
149 mov es, ax ; ES:0 = ptr to gdt
150
151 and byte ptr ES:[TSS_GSEL + 5], 11111101B
152
153 ;
154 ; lock high system ROM before returning to real
155 ;
156 HwTabLock
157
158 ;
159 ; First save return ss:sp. We have to translate
160 ; the current ss (a selector) into a segment number.
161 ; Calculate a real mode segment corresponding to the
162 ; current protected mode stack selector base address.
163 ;
164 ; We get the base address from the descriptor table,
165 ; and convert it to a paragraph number.
166 ;
167 mov bx,ss ; bx = selector for stack
168 call SelToSeg ; AX = segment number for SS
169 mov bx,ax ; BX = setup stack segment
170 ;
171 ;
172 ; Intel shows DS,ES,FS,GS,and SS set up to make sure 'Real Mode' type
173 ; access rights, and limit are installed. In this program, that happens
174 ; to already be the case, but for general purposeness, VDMD_GSEL fits
175 ; the bill.
176 ;
177 mov ax,VDMD_GSEL ; selector with real mode attributes
178 mov ds,ax
179 mov es,ax
180 mov ss,ax
181 MOV_FS_AX
182 MOV_GS_AX
183 ;
184 ; Intel recommends the following code for resetting the PE bit. Mine
185 ; works OK, but maybe it's not general purpose enough (I was counting
186 ; on knowing that paging wasn't enabled).
187 ;
188 MOV_EAX_CR0 ; get CR0
189
190 OP32
191 and ax,0FFFEh ; force real mode and shut down paging
192 dw 07FFFh ; (mov eax,07FFFFFFEh)
193
194 MOV_CR0_EAX ; set CR0
195
196 ; flush prefetched instructions with:
197 db 0EAh ; Far Jump opcode
198 dw offset _TEXT:rl386_b ; destination offset
199 Real_Seg label word
200 dw _TEXT ; destination segment
201 rl386_b:
202 OP32 ; load up full IDT address
203 lidt qword ptr cs:[real_idt]
204
205 sti
206
207 MOV_EAX_CR3 ; get CR3
208 MOV_CR3_EAX ; set CR3 => clear TLB
209
210 mov ss,bx ; ss = real mode stack segment
211 mov ax,DGROUP
212 mov ds,ax
213 mov es,ax
214 MOV_FS_AX
215 MOV_GS_AX
216
217 mov [Active_Status],0 ; rest VDM status
218
219 call DisableA20 ; disable A20 line
220
221 pop bx
222 POP_EAX
223 ret ; *** RETURN ***
224 RetReal endp
225
226 _TEXT ends
227 end
228 \1a