wok view linld/stuff/src/MEMCPY32.ASM @ rev 19515

linld: multi initrd support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Nov 22 21:19:01 2016 +0100 (2016-11-22)
parents
children 7f92b23984dc
line source
1 ;***************************************************************
2 ;****** This file is distributed under GPL
3 ;***************************************************************
4 ideal
5 %crefref
6 %noincl
7 %nomacs
8 p386
10 group DGROUP _TEXT,_DATA
11 assume cs:DGROUP,ds:DGROUP
13 segment _DATA byte public use16 'DATA'
14 msg_badcpu db "I need 386+ CPU in real mode or under VCPI manager",0
15 ends _DATA
17 segment _TEXT byte public use16 'CODE'
19 ;***************************************************************
20 ;int _is_vm86();
21 ;****** Return: AX=1 - it is a 386+ in virtual86 mode with vcpi
22 ;****** AX=0 - it is a 386+ in real mode
23 ;****** otherwise abort program
24 ;****** Uses: Flags
25 ;***************************************************************
26 global _is_vm86:near
27 proc _is_vm86 near
29 ; Check for oldies
30 mov ax, 0F000h
31 pushf
32 push ax ; < 286 : flags[12..15] are forced 1
33 popf ; = 286 : flags[12..15] are forced 0
34 pushf ; > 286 : only flags[15] is forced 0
35 pop dx
36 popf
37 add dh,ah ; NS=386+, NC=286
38 ifndef NO386
39 js @@no_vcpi ;it is a 86/186/286, not a 386+
40 else
41 js @@ret
42 endif
43 ; Check for vm
44 smsw ax ;SMSW cannot be trapped! :-)
45 and ax,1 ;MSW_PE
46 ; We're in vm
47 jnz check_vcpi
49 ; It's a 386 in real mode, chk for paging (crazy but possible)
50 mov edx,cr0
51 shl edx,1 ;CR0_PG to CF
52 jc @@no_vcpi
53 @@ret:
54 ret
56 ;***************************************************************
57 ;****** Helper: checks for vcpi
58 ;***************************************************************
59 label check_vcpi near
60 push ds
61 ; Check whether it is safe to call 67h (we trust only known EMM managers)
62 push 0
63 pop ds
64 mov ds,[word 67h*4+2]
65 cmp [dword 10+4],'0XXX'
66 jne @@skip
67 mov eax,[dword 10]
68 cmp eax,'XMME'
69 je @@skip
70 ; this also works (as told by <J.S.Peatfield@damtp.cambridge.ac.uk>)
71 cmp eax,'QMME'
72 @@skip:
73 pop ds
74 jne @@no_vcpi
75 ; Check emm manager status and version
76 mov ah,40h ; get status
77 int 67h
78 test ah,ah
79 jnz @@no_vcpi
80 mov ah,46h ; get version
81 int 67h
82 test ah,ah
83 jnz @@no_vcpi
84 cmp al,40h ; version must be >= 4.0
85 jb @@no_vcpi
86 ; Check vcpi manager status
87 ;;mov ax,5A01h ; ALLOCATE RAW PAGES
88 ;;mov bx,4
89 ;;int 67h
90 ;;test ah,ah
91 ;;jnz @@no_vcpi
92 ;;push dx ;$ save handle
93 mov ax,0DE00h ; check for vcpi present
94 int 67h
95 mov al,1
96 test ah,ah
97 jz @@386vcpi
98 ;;pop dx ;$ handle
99 ;;mov ax,4500h ; DEALLOCATE PAGES
100 ;;int 67h
101 @@no_vcpi:
102 mov bx,offset msg_badcpu
103 extrn die:near
104 jmp near die
105 @@386vcpi:
106 mov [_vcpi],al
107 extrn @init_vcpi$qv:near
108 jmp near @init_vcpi$qv
110 endp _is_vm86
113 ;***************************************************************
114 ;void dos_shutdown()
115 ;***************************************************************
116 global dos_shutdown:near
117 proc dos_shutdown near
119 ;TODO NO386
120 dos_shutdown:
121 pusha
122 xor bx,bx
123 mov ds,bx
124 push [dword bx+4] ; save step
125 mov ax,sp
126 push ss
127 push ax
128 pop [dword cs:sssp]
129 ;cmp [byte bx+7],0F0h
130 ;jnc notdos
131 mov [word bx+4],offset step19
132 mov [bx+6],cs
133 pushf
134 pop ax
135 inc ah ; set TF
136 push ax
137 popf
138 jmp small [dword bx+4*19h]
139 doiret:
140 iret
141 sssp:
142 dd 0
143 step19:
144 push bx
145 push ds
146 mov bx,sp
147 lds bx,[dword ss:bx+4] ; read cs:ip
148 cmp [word bx],19CDh ; int 19h ?
149 pop ds
150 pop bx
151 jne doiret
152 notdos:
153 lss sp,[dword cs:sssp]
154 xor bx,bx
155 mov ds,bx
156 pop [dword bx+4] ; restore step
157 popa
158 push cs
159 pop ds
160 ret
162 endp dos_shutdown
165 ;***************************************************************
166 ;void memcpy32(u16 dstseg,u32 dstofs,u16 srcseg,u32 srcofs,u32 size);
167 ;***************************************************************
168 ;****** Uses: Flags
169 ;***************************************************************
170 global _memcpy32:near
171 proc _memcpy32 near
173 ;TODO NO386
174 ; rm32,imm16 helper
175 macro addzx_e rm,i
176 db 66h
177 add rm,i
178 dw 0
179 endm
180 arg dstseg :word, \
181 dstofs :dword, \
182 srcseg :word, \
183 srcofs :dword, \
184 sz :dword = PARAM_SIZE
186 local GDTR :pword, \
187 oldGDTR :pword = TEMP_SIZE
189 ;****** Init ***************************************************
190 enter TEMP_SIZE,0
191 pushf
192 push es ds esi edi
193 movzx esi,[srcseg]
194 shl esi,4
195 add esi,[srcofs]
196 movzx edi,[dstseg]
197 shl edi,4
198 add edi,[dstofs]
199 ifndef pm_only
200 mov eax,00100000h
201 cmp esi,eax
202 jnb pmcopy
203 cmp edi,eax
204 jnb pmcopy
205 mov eax,esi
206 shr eax,4
207 mov ds,ax
208 mov edx,edi
209 shr edx,4
210 @@movlp:
211 mov ds,ax
212 mov es,dx
213 and si,0Fh
214 and di,0Fh
215 mov cx,08h
216 cld
217 rep movsw
218 inc ax
219 inc dx
220 sub [sz],10h
221 ja @@movlp
222 jmp done
223 endif
224 pmcopy:
225 mov ecx,[sz]
226 mov dx,-1
228 ifdef keep_int15
229 jecxz godone
230 test [_vcpi],dl
231 jne with_movsw
233 push ss
234 pop es
235 inc ecx
236 shr ecx,1
237 mov bx,9318h
238 clear:
239 push 0
240 dec bl
241 jnz clear
242 xchg eax,esi
243 mov si,sp
244 mov [si+12h],eax
245 mov [si+1Ah],edi
246 mov [si+10h],dx
247 mov [si+18h],dx
248 mov edi,ecx
249 mov dh,93h
250 xchg bx,[si+14h]
251 xchg dx,[si+1Ch]
252 mvlp:
253 mov [si+14h],bl
254 mov [si+17h],bh
255 mov [si+1Ch],dl
256 mov [si+1Fh],dh
257 xor ecx,ecx
258 mov ch,80h
259 sub edi,ecx
260 pushf
261 jnc domv
262 add ecx,edi
263 domv:
264 ;push bx dx si edi
265 mov ah,87h
266 int 15h
267 ;pop edi si dx bx
268 inc bx
269 inc dx
270 popf
271 jnc mvlp
272 add sp,30h
273 godone:
274 jmp done
275 else
276 jecxz done
277 endif
279 with_movsw:
280 cld
281 cmp esi,edi
282 jae @@do_copy
283 add esi,ecx ;src<dst: we must do
284 dec esi ; copy backwards to avoid
285 add edi,ecx ; overwrite bug
286 dec edi ;
287 std ;
288 @@do_copy:
289 cli
290 sgdt [oldGDTR]
292 ;****** Load gdtr **********************************************
293 mov eax,cs
294 shl eax,4
295 addzx_e ax,<offset GDT>
296 mov [word GDTR],dx ;GDT limit = 0FFFFh
297 mov [dword GDTR+2],eax ;GDT base
298 lgdt [GDTR]
300 ;****** Go into pm *********************************************
301 mov eax,cr0
302 or al,01h ;CR0_PE on
303 mov cr0,eax
304 jmp short $+2 ;*Required*!
305 ;3+ NOPs also work fine (chkd on 386)
306 ;****** Move data **********************************************
307 push 0008h
308 pop ds ;base=0, lim = 4gb
309 push ds ;
310 pop es ;
311 db 66h ;operand width override for ecx
312 db 67h ;address width override for esi/edi
313 rep movsb
314 cld
316 ;****** Return to rm *******************************************
317 dec ax ;CR0_PE off
318 mov cr0,eax ;ds/es limits are *not* reset to 64kb
319 ; but who cares :-)
320 jmp short $+2
322 ;****** Return *************************************************
323 lgdt [oldGDTR]
324 done:
325 cld
326 pop edi esi ds es
327 popf
328 leave
329 ret
331 ;****** Const data *********************************************
332 org $-8 ;save 8 bytes - they are unused anyway
333 ;0000: unused
334 GDT dd ?,?
335 ;0008: Data seg [0,FFFFFFFF]
336 ; lim_lo base_lo
337 dw 1111111111111111b, 0000000000000000b
338 db 00000000b,10010010b,10001111b,00000000b
339 ; base_med P S D A G ??l_hi base_hi
340 ; Pl E W D
342 global _vcpi:byte
343 _vcpi db 0
345 endp _memcpy32
347 ends _TEXT
349 end
351 ;###### END OF FILE ############################################