summaryrefslogtreecommitdiff
path: root/Source/Kernel/TaskManager/V86/v86.wtf.asm
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Kernel/TaskManager/V86/v86.wtf.asm')
-rw-r--r--Source/Kernel/TaskManager/V86/v86.wtf.asm48
1 files changed, 48 insertions, 0 deletions
diff --git a/Source/Kernel/TaskManager/V86/v86.wtf.asm b/Source/Kernel/TaskManager/V86/v86.wtf.asm
new file mode 100644
index 0000000..09b08a2
--- /dev/null
+++ b/Source/Kernel/TaskManager/V86/v86.wtf.asm
@@ -0,0 +1,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