Metropoli BBS
VIEWER: int86.asm MODE: TEXT (ASCII)
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


[ RETURN TO DIRECTORY ]