include qlib.inc
include dos.inc
.code
int86 proc,i:byte,rin:dword,rout:dword
.if i==3
int 3 ;0cch
ret
.endif
sub esp,sizeof SREGS
mov eax,esp
mov [eax].SREGS._ds,0
mov [eax].SREGS._es,0
mov [eax].SREGS._fs,0
mov [eax].SREGS._gs,0
callp int86x,i,rin,rout,eax
add esp,sizeof SREGS
ret
int86 endp
int86x proc,i:byte,rin:dword,rout:dword,sreg:dword
pushad
mov esi,rin
sub esp,sizeof callstruct
mov edi,esp
mov eax,[esi].REGS.d._eax
mov [edi].callstruct._eax,eax
mov eax,[esi].REGS.d._ebx
mov [edi].callstruct._ebx,eax
mov eax,[esi].REGS.d._ecx
mov [edi].callstruct._ecx,eax
mov eax,[esi].REGS.d._edx
mov [edi].callstruct._edx,eax
mov eax,[esi].REGS.d._esi
mov [edi].callstruct._esi,eax
mov eax,[esi].REGS.d._edi
mov [edi].callstruct._edi,eax
mov eax,[esi].REGS.d.cflag
and ax,1 ;only the carry flag is needed
mov [edi].callstruct._flg,ax
mov esi,sreg ;FIX : v2.03 Beta #2 : this was missing
mov ax,[esi].SREGS._ds
mov [edi].callstruct._ds,ax
mov ax,[esi].SREGS._es
mov [edi].callstruct._es,ax
mov ax,[esi].SREGS._fs
mov [edi].callstruct._fs,ax
mov ax,[esi].SREGS._gs
mov [edi].callstruct._gs,ax
mov [edi].callstruct._ss,0
mov [edi].callstruct._sp,0
mov ax,300h
mov bl,i
xor bh,bh
xor ecx,ecx
;es:edi=callstruct
int 31h
mov esi,rout
mov edi,esp
mov eax,[edi].callstruct._eax
mov [esi].REGS.d._eax,eax
mov eax,[edi].callstruct._ebx
mov [esi].REGS.d._ebx,eax
mov eax,[edi].callstruct._ecx
mov [esi].REGS.d._ecx,eax
mov eax,[edi].callstruct._edx
mov [esi].REGS.d._edx,eax
movzx eax,[edi].callstruct._flg
and eax,1 ;only the carry flag is needed
mov [esi].REGS.d.cflag,eax
mov eax,[edi].callstruct._esi
mov [esi].REGS.d._esi,eax
mov eax,[edi].callstruct._edi
mov [esi].REGS.d._edi,eax
mov esi,sreg ;FIX : v2.03 Beta #2 : this was missing
mov ax,[edi].callstruct._ds
mov [esi].SREGS._ds,ax
mov ax,[edi].callstruct._es
mov [esi].SREGS._es,ax
mov ax,[edi].callstruct._fs
mov [esi].SREGS._fs,ax
mov ax,[edi].callstruct._gs
mov [esi].SREGS._gs,ax
add esp,sizeof callstruct
popad
ret
int86x endp
int386 proc,i:byte,rin:dword,rout:dword
; it would not be good to make this call int386x() with current sel
; cause loading sel is slow
pushad
mov al,i
mov intnum1,al
mov eax,rin
mov ebx,[eax].REGS.d._ebx
mov ecx,[eax].REGS.d._ecx
mov edx,[eax].REGS.d._edx
mov esi,[eax].REGS.d._esi
mov edi,[eax].REGS.d._edi
.if [eax].REGS.d.cflag
stc
.else
clc
.endif
mov eax,[eax].REGS.d._eax
jmp far1
far1:
db 0cdh
intnum1 db 3
pushf
push eax
mov eax,rout
pop [eax].REGS.d._eax
mov [eax].REGS.d._ebx,ebx
mov [eax].REGS.d._ecx,ecx
mov [eax].REGS.d._edx,edx
mov [eax].REGS.d._esi,esi
mov [eax].REGS.d._edi,edi
pop ax
.if ax&1
mov [eax].REGS.d.cflag,1
.else
mov [eax].REGS.d.cflag,0
.endif
popad
xor eax,eax
ret
int386 endp
int386x proc,i:byte,rin:dword,rout:dword,sreg:dword
pushad
mov al,i
mov intnum2,al
mov eax,rin
mov ebx,[eax].REGS.d._ebx
mov ecx,[eax].REGS.d._ecx
mov edx,[eax].REGS.d._edx
mov esi,[eax].REGS.d._esi
mov edi,[eax].REGS.d._edi
.if [eax].REGS.d.cflag
stc
.else
clc
.endif
push [eax].REGS.d._eax
;load DS,ES,FS,GS
mov eax,sreg
mov gs,[eax].SREGS._gs
mov fs,[eax].SREGS._fs
mov es,[eax].SREGS._es
mov ds,[eax].SREGS._ds
pop eax
jmp far1
far1:
db 0cdh
intnum2 db 3
push ds
mov ds,cs:seldata
pushf
push eax
mov eax,rout
pop [eax].REGS.d._eax
mov [eax].REGS.d._ebx,ebx
mov [eax].REGS.d._ecx,ecx
mov [eax].REGS.d._edx,edx
mov [eax].REGS.d._esi,esi
mov [eax].REGS.d._edi,edi
pop ax
.if ax&1
mov [eax].REGS.d.cflag,1
.else
mov [eax].REGS.d.cflag,0
.endif
mov eax,sreg
pop [eax].SREGS._ds
mov [eax].SREGS._es,es
mov [eax].SREGS._fs,fs
mov [eax].SREGS._gs,gs
mov ax,seldata
mov es,ax
mov fs,ax
mov gs,ax
popad
xor eax,eax
ret
int386x endp
intdos proc,rin:dword,rout:dword
callp int386,21h,rin,rout
ret
intdos endp
intdosx proc,i:byte,rin:dword,rout:dword,sreg:dword
callp int386x,21h,rin,rout,sreg
ret
intdosx endp
end