-
Notifications
You must be signed in to change notification settings - Fork 0
/
DPMI.INC
215 lines (194 loc) · 5.99 KB
/
DPMI.INC
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
SELECTORS equ 7 ; no queremos los 4 del VCPI ni el del PSP
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
dpmi_error:
; DS = D16_SEL
; ponemos la real mode call structure
push ds
pop es
mov edi,offset dpmi_rm_call
mov byte ptr [edi+1Ch],9
mov word ptr [edi+24h],txdata
mov word ptr [edi+14h],offset dpmi_init_error
; mov word ptr [di+30h],txpila
; mov word ptr [di+2Eh],size txpila
mov bx,21h
xor cx,cx
mov ax,300h
int 31h
jmp no_vcpi_end
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
save_dpmi_data proc
mov dx,offset dpmi_32b_error
test bl,1
jz error_handle
ASSUME DS:txdata
mov ax,txdata
mov ds,ax
; guardamos el DPMI mode-switch entry point
mov word ptr cs:dpmi_mode_switch,di
mov word ptr cs:dpmi_mode_switch+2,es
push si
; alojamos la memoria que necesite el DPMI
pop bx
call get_dos_mem
mov dpmi_private_buffer,ax
ret
save_dpmi_data endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
dpmi_init:
; cargamos en DS el segmento para corregirlo todo
mov ax,txdata
mov ds,ax
; PM switch
mov ax,1
mov es,dpmi_private_buffer
db 9Ah ; CALL FAR PTR
dpmi_mode_switch dd 0
cli ; por si acaso...
mov dx,offset dpmi_init_error
jc error_handle ; estaremos todav¡a en real
; guardamos el selector del PSP
mov psp_selector,es
; guardamos el selector del entorno
; estamos en protegido
; alojamos descriptores
xor ax,ax
mov cx,SELECTORS
int 31h
jc dpmi_error
push ax
; miramos el incremento de selector
mov ax,3
int 31h
mov bp,ax
pop bx
; corregimos los selectores
mov ecx,SELECTORS
ASSUME DS:txdata
mov edi,offset dpmi_sels
mov dx,bx
suma_sels:
mov [edi],dx
add dx,ax
add edi,4
loop suma_sels
; averiguamos el PL actual y lo ponemos en los descriptores
push ds
pop es
mov ax,cs
lar dx,ax ; coge access rights
and dh,60h ; a¡sla PL
mov ecx,SELECTORS
mov edi,offset gdt+8
pon_dpl:
or es:[edi+5],dh
mov ax,0Ch
int 31h
jc dpmi_error
add edi,8
add bx,bp
loop pon_dpl
; fix-up de selectores
mov es,word ptr dpmi_sels+4
mov edi,txcode32
shl edi,4
add edi,offset C32_SEL
mov esi,offset dpmi_sels
mov ecx,SELECTORS
; si los copiamos con MOVSD no los copia bien (???)
copia_sels:
mov eax,[esi]
mov es:[edi],eax
add edi,4
add esi,4
loop copia_sels
mov ax,word ptr dpmi_sels
; SS:ESP = D32_SEL:STACK_PTR
; mov ss,dpmi_sels+4
; mov esp,stack_ptr
; hacemos el fix-up del salto a protegido antes de cargarnos DS
mov word ptr prot_code_address+4,ax
push ax
; ; pedimos las direcciones de los procs. de save/restore
; mov ax,305h
; int 31h
; mov word ptr dpmi_save_restore_real,cx
; mov word ptr dpmi_save_restore_real+2,bx
; mov dword ptr dpmi_save_restore_pm,edi
; mov word ptr dpmi_save_restore_pm+4,si
; ; pedimos las direcciones de switch en raw mode
; mov ax,306h
; int 31h
; mov word ptr dpmi_real_to_pm,cx
; mov word ptr dpmi_real_to_pm+2,bx
; mov dword ptr dpmi_pm_to_real,edi
; mov word ptr dpmi_pm_to_real+4,si
; nos guardamos las excepciones
xor bl,bl
mov edi,offset dpmi_exc_handlers
guarda_excs:
mov ax,202h
int 31h
mov [edi],edx
mov [edi+4],cx
add edi,6
inc bl
cmp bl,15
jnz guarda_excs
; ajustamos las excepciones 0,1,3-0Eh
pop cx
push cx
xor bl,bl
mov edx,offset interrup_redir
dpmi_set_excs:
mov ax,203h
int 31h
jc dpmi_error
inc bl
add edx,8
cmp bl,15
jnz dpmi_set_excs
mov edx,dword ptr dpmi_exc_handlers+2*6
mov cx,word ptr dpmi_exc_handlers+2*6+4
mov ax,203h
mov bl,2 ; la 2 no es excepci¢n...
int 31h
jc dpmi_error
; guardamos las interrupciones
xor bl,bl
mov edi,txcode32
shl edi,4
guarda_ints:
mov ax,204h
int 31h
ASSUME ES:txcode32
mov dword ptr es:[edi+idt],edx
mov word ptr es:[edi+idt+4],cx
add edi,6
inc bl
jnz guarda_ints
; ponemos las nuevas int's 21h y 31h
pop cx
push cx
mov bl,21h
mov edx,offset tx_int21h
mov ax,205h
int 31h
jc dpmi_error
pop cx
mov bl,31h
mov edx,offset tx_int31h
mov ax,205h
int 31h
jc dpmi_error
; rellenamos info varia para la funci¢n OEM 3201h
mov ax,cs:D32_SEL
mov zero_sel,ax
mov ax,cs:DATA_SEL
mov prog_sel,ax
mov ax,cs:ENVRN_SEL
mov env_selector,ax
ASSUME ES:txdata
; y nos vamos al programa
jmp fword ptr prot_code_address
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ