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

linld: add 'linld <kernel> <cmdline>' syntax
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Dec 02 12:37:59 2016 +0100 (2016-12-02)
parents bb42796dcd3b
children 31c5cbbd9380
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 msg_badmapping db "VCPI: low 640k: need 1:1 mapping",0
16 ends _DATA
18 segment _TEXT byte public use16 'CODE'
20 ;***************************************************************
21 ;int _is_vm86();
22 ;****** Return: AX=1 - it is a 386+ in virtual86 mode with vcpi
23 ;****** AX=0 - it is a 386+ in real mode
24 ;****** otherwise abort program
25 ;****** Uses: Flags
26 ;***************************************************************
27 global _is_vm86:near
28 proc _is_vm86 near
30 ; Check for oldies
31 mov ah, 0F0h
32 pushf
33 push ax ; < 286 : flags[12..15] are forced 1
34 popf ; = 286 : flags[12..15] are forced 0
35 pushf ; > 286 : only flags[15] is forced 0
36 pop dx
37 popf
38 add dh,ah ; NS=386+, NC=286
39 ifndef NO386
40 js @@no_vcpi ;it is a 86/186/286, not a 386+
41 else
42 js @@ret
43 endif
44 ; Check for vm
45 smsw ax ;SMSW cannot be trapped! :-)
46 and ax,1 ;MSW_PE
47 ; We're in vm
48 jnz check_vcpi
50 ; It's a 386 in real mode, chk for paging (crazy but possible)
51 mov edx,cr0
52 shl edx,1 ;CR0_PG to CF
53 jc @@no_vcpi
54 @@ret:
55 ret
57 ;***************************************************************
58 ;****** Helper: checks for vcpi
59 ;***************************************************************
60 label check_vcpi near
61 push ds
62 ; Check whether it is safe to call 67h (we trust only known EMM managers)
63 push 0
64 pop ds
65 mov ds,[word 67h*4+2]
66 cmp [dword 10+4],'0XXX'
67 jne @@skip
68 mov eax,'XMME'
69 xor eax,[dword 10]
70 ; QMME also works (as told by <J.S.Peatfield@damtp.cambridge.ac.uk>)
71 shl eax,8
72 @@skip:
73 pop ds
74 jne @@no_vcpi
76 ; Check emm manager status and version
77 mov ah,40h ; get status
78 int 67h
79 test ah,ah
80 jnz @@no_vcpi
81 mov ah,46h ; get version
82 int 67h
83 test ah,ah
84 jnz @@no_vcpi
85 cmp al,40h ; version must be >= 4.0
86 jb @@no_vcpi
87 ; Check vcpi manager status
88 ;;mov ax,5A01h ; ALLOCATE RAW PAGES
89 ;;mov bx,4
90 ;;int 67h
91 ;;test ah,ah
92 ;;jnz @@no_vcpi
93 ;;push dx ;$ save handle
94 mov ax,0DE00h ; check for vcpi present
95 int 67h
96 mov al,1
97 test ah,ah
98 jz @@386vcpi
99 ;;pop dx ;$ handle
100 ;;mov ax,4500h ; DEALLOCATE PAGES
101 ;;int 67h
102 @@no_vcpi:
103 mov bx,offset msg_badcpu
104 extrn die:near
105 godie:
106 jmp near die
107 @@386vcpi:
108 mov [_vcpi],al
109 extrn prepare_vcpi:near
110 call prepare_vcpi
111 ; get_vcpi_interface() || die("VCPI: low 640k: need 1:1 mapping");
112 ;extrn _get_vcpi_interface:near
113 ;call _get_vcpi_interface
114 mov bx,offset msg_badmapping
115 jz godie
116 ret
118 endp _is_vm86
121 ;***************************************************************
122 ;void dos_shutdown()
123 ;***************************************************************
124 global dos_shutdown:near
125 proc dos_shutdown near
127 dos_shutdown:
128 ifndef NO386
129 ;pusha
130 else
131 ;push bp si di
132 endif
133 xor bx,bx
134 mov ds,bx
135 ifndef NO386
136 push [dword bx+4] ; save step
137 mov ax,sp
138 push ss
139 push ax
140 pop [dword cs:sssp]
141 else
142 push [word bx+6]
143 push [word bx+4] ; save step
144 mov [word cs:sssp],sp
145 mov [word cs:sssp+2],ss
146 endif
147 ;cmp [byte bx+7],0F0h
148 ;jnc notdos
149 mov [word bx+4],offset step19
150 mov [bx+6],cs
151 pushf
152 pop ax
153 inc ah ; set TF
154 push ax
155 popf
156 jmp small [dword bx+4*19h]
157 doiret:
158 iret
159 sssp:
160 dd 0
161 step19:
162 push bx
163 push ds
164 mov bx,sp
165 lds bx,[dword ss:bx+4] ; read cs:ip
166 cmp [word bx],19CDh ; int 19h ?
167 pop ds
168 pop bx
169 jne doiret
170 notdos:
171 ifndef NO386
172 lss sp,[dword cs:sssp]
173 else
174 lds bx,[dword cs:sssp]
175 push ds
176 pop ss
177 mov sp,bx
178 endif
179 xor bx,bx
180 mov ds,bx
181 ifndef NO386
182 pop [dword bx+4] ; restore step
183 ;popa
184 else
185 pop [word bx+4] ; restore step
186 pop [word bx+6]
187 ;pop di si bp
188 endif
189 push cs
190 pop ds
191 ret
193 endp dos_shutdown
196 ;***************************************************************
197 ;void memcpy32(u32 dstofs,u16 srcseg,u32 srcofs,u32 size);
198 ;***************************************************************
199 ;****** Uses: Flags
200 ;***************************************************************
201 global _memcpy32:near
202 proc _memcpy32 near
204 ; rm32,imm16 helper
205 macro addzx_e rm,i
206 db 66h
207 add rm,i
208 dw 0
209 endm
210 arg dstofs :dword, \
211 srcseg :word, \
212 srcofs :dword, \
213 sz :dword = PARAM_SIZE
215 local GDTR :pword, \
216 oldGDTR :pword = TEMP_SIZE
218 ;****** Init ***************************************************
219 push bp
220 mov bp,sp
221 sub sp,TEMP_SIZE
222 pushf
223 cld
224 push ds es
226 ifndef NO386
228 pushad
229 movzx esi,[srcseg]
230 shl esi,4
231 add [srcofs],esi
232 mov esi,[srcofs]
233 mov edi,[dstofs]
235 ifndef pm_only
236 mov eax,esi
237 or eax,edi
238 shr eax,20 ; >1mb ?
239 jnz pmcopy
240 mov eax,esi
241 shr eax,4
242 mov edx,edi
243 shr edx,4
244 @@movlp:
245 mov ds,ax
246 mov es,dx
247 inc ax
248 inc dx
249 xor ecx,ecx
250 mov cl,0Fh
251 and si,cx
252 and di,cx
253 inc cx
254 sub [sz],ecx
255 rep movsb
256 ja @@movlp
257 jmp done
258 endif
259 pmcopy:
260 else
262 push si
263 xor bx,bx
264 xor dx,dx
265 xor si,si
266 mov ax,[bp+si+8] ; srcseg
267 call near N_LXLSH@4
268 add [bp+si+10],ax ; srcofs lo
269 adc [bp+si+10+2],dx ; srcofs hi
270 @@2flat:
271 mov ax,[bp+si+10] ; srcofs, dstofs lo
272 mov dx,[bp+si+10+2] ; srcofs, dstofs hi
273 call near N_LXURSH@4
274 or bx,dx ; >=1mb flag
275 push ax ; srcseg, dstseg
276 xor si,-6
277 jnz @@2flat
278 pop dx ; dstseg
279 pop ax ; srcseg
280 or bx,bx ; <1mb ?
281 jnz pmcopy
282 push di
283 @@movlp:
284 mov ds,ax
285 mov es,dx
286 inc ax
287 inc dx
288 mov cl,0Fh
289 mov si,cx
290 mov di,cx
291 and si,[word srcofs]
292 and di,[word dstofs]
293 inc cx
294 sub [word sz],cx
295 rep movsb
296 jae @@movlp
297 dec [word sz+2]
298 jns @@movlp ; mov 1-16 more bytes...
299 pop di si
300 jmp done16
301 pmcopy:
302 pop si
303 pushad
304 mov esi,[srcofs]
305 mov edi,[dstofs]
307 endif
309 mov ecx,[sz]
310 jecxz done
312 smsw ax
313 test al,1
314 jz @@real_mode
315 ; Note: bp points to std stack frame now. bp will be passed to
316 ; pm routine. This allows params to be passed on stack
317 extrn do_memcpy_vcpi:near
318 push offset do_memcpy_vcpi
319 extrn call_pm_routine:near
320 call near call_pm_routine ; Call pm copy routine via vcpi pm
321 pop ax
322 jmp done
323 @@real_mode:
324 mov dx,-1
326 with_movsw:
327 cmp esi,edi
328 jae @@do_copy
329 add esi,ecx ;src<dst: we must do
330 dec esi ; copy backwards to avoid
331 add edi,ecx ; overwrite bug
332 dec edi ;
333 std ;
334 @@do_copy:
335 cli
336 sgdt [oldGDTR]
338 ;****** Load gdtr **********************************************
339 mov eax,cs
340 shl eax,4
341 addzx_e ax,<offset GDT>
342 mov [word GDTR],dx ;GDT limit = 0FFFFh
343 mov [dword GDTR+2],eax ;GDT base
344 lgdt [GDTR]
346 ;****** Go into pm *********************************************
347 mov eax,cr0
348 or al,01h ;CR0_PE on
349 mov cr0,eax
350 jmp short $+2 ;*Required*!
351 ;3+ NOPs also work fine (chkd on 386)
352 ;****** Move data **********************************************
353 push 0008h
354 pop ds ;base=0, lim = 4gb
355 push ds ;
356 pop es ;
357 db 66h ;operand width override for ecx
358 db 67h ;address width override for esi/edi
359 rep movsb
361 ;****** Return to rm *******************************************
362 dec ax ;CR0_PE off
363 mov cr0,eax ;ds/es limits are *not* reset to 64kb
364 ; but who cares :-)
365 jmp short $+2
367 ;****** Return *************************************************
368 lgdt [oldGDTR]
369 done:
370 popad
371 done16:
372 pop es ds
373 popf
374 mov sp,bp
375 pop bp
376 ret
378 ;****** Const data *********************************************
379 org $-8 ;save 8 bytes - they are unused anyway
380 ;0000: unused
381 GDT dd ?,?
382 ;0008: Data seg [0,FFFFFFFF]
383 ; lim_lo base_lo
384 dw 1111111111111111b, 0000000000000000b
385 db 00000000b,10010010b,10001111b,00000000b
386 ; base_med P S D A G ??l_hi base_hi
387 ; Pl E W D
389 global _vcpi:byte
390 _vcpi db 0
392 endp _memcpy32
394 ifdef NO386
395 global N_LXURSH@:near
396 global N_LXURSH@4:near
397 proc N_LXURSH@4 near
399 mov cl,4
400 N_LXURSH@:
401 mov ch,0
402 @@loop:
403 shr dx,1
404 rcr ax,1
405 loop @@loop
406 ret
408 endp N_LXURSH@4
410 global N_LXLSH@:near
411 global N_LXLSH@4:near
412 proc N_LXLSH@4 near
414 mov cl,4
415 N_LXLSH@:
416 mov ch,0
417 @@loop:
418 shl ax,1
419 rcl dx,1
420 loop @@loop
421 ret
423 endp N_LXLSH@4
425 endif
427 ends _TEXT
429 end
431 ;###### END OF FILE ############################################