+ ; try to return to real mode
+ mov si, str_gemmis
+ call printstr
+
+ xor ax, ax
+ mov bx, ax
+ mov si, ax
+ mov es, ax
+ mov ds, ax
+ mov cx, ax
+ mov dx, ax
+ mov ax, 1605h
+ mov di, 30ah ; pretend to be windows 3.1
+ int 2fh
+ test cx, cx
+ jnz .vm86abort
+ ; we got a function in ds:si
+ push cs
+ push ds
+ pop es ; es <- func seg
+ pop ds ; ds <- cs
+ mov word [vmswitch_seg], es
+ mov word [vmswitch_off], si
+ xor ax, ax ; return to real mode
+ cli ; just make sure nothing enabled intr behind out back
+ call far [vmswitch]
+ jc .vm86abort
+
+ ; success
+ mov ax, cs
+ mov ds, ax
+ mov es, ax
+ mov si, msg_okstr
+ call printstr
+ jmp .notvm86
+
+.vm86abort:
+ push cs
+ pop ds
+ mov si, msg_failstr
+ call printstr