summaryrefslogtreecommitdiff
path: root/Source/Kernel/TaskManager/V86/v86.wtf.asm
blob: 09b08a2a1fa072848aed204d08604e7d87cb3e63 (plain) (blame)
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
; This is the procedure that is first run when starting a V86 thread
; Parameters : esp+4 = page directory to switch to, esp+8 = v86_regs_t pointer
; Algorithm :
; - Switch page directory
; - Create a false IRET structure, with : (first pushed first)
;   GS, FS, DS, ES, SS, SP, EFLAGS (with eflags.if and eflags.vm), CS, IP
; - Set general purpose regisers : ax bx cx dx di si
; - Call iret, switch to V86 mode.

[BITS 32]

[GLOBAL v86_run]
v86_run:
	mov eax, [esp + 4]
	mov cr3, eax
	mov eax, [esp + 8]

	xor ebx, ebx
	mov bx, [eax + 20]		; get GS
	push ebx
	mov bx, [eax + 18]		; get FS
	push ebx
	mov bx, [eax + 14]		; get DS
	push ebx
	mov bx, [eax + 16]		; get ES
	push ebx
	mov bx, [eax + 22]		; get SS
	push ebx
	mov bx, [eax + 26]		; get SP
	push ebx
	pushf
	pop ebx
	or ebx, 20200h
	push ebx
	xor ebx, ebx
	mov bx, [eax + 12]		; get CS
	push ebx
	mov bx, [eax + 24]		; get IP
	push ebx

	mov bx, [eax + 2]
	mov cx, [eax + 4]
	mov dx, [eax + 6]
	mov di, [eax + 8]
	mov si, [eax + 10]
	mov ax, [eax]

	iret