home *** CD-ROM | disk | FTP | other *** search
- ; pcoint86.asm
- ;
- ; 12/13/88 by Ted
- ;
- ; Dos/Bios interrupt function.
- ;
- ; Copyright (c) 1988, 1989 Oakland Group Inc.
- ; ALL RIGHTS RESERVED
- ;
- ;------------------------REVISION HISTORY--------------------------------------;
- ; 1/29/90 ted Changed from self-modifying code method to stack games method.
- ; 5/29/90 ted Added ds option in esdsin variable.
- ;------------------------------------------------------------------------------;
- include PCDECL.MAC
-
- regstruc struc
- rax dw 0
- rbx dw 0
- rcx dw 0
- rdx dw 0
- res dw 0
- rds dw 0
- rsi dw 0
- rdi dw 0
- regstruc ends
-
- PSEG
- ;------------------------------------------------------------------------------;
- ;
- ; unsigned _oakint86(unsigned intno, regstruc *regs, boolean esdsin);
- ; Puts the values from regstruc into the registers and executes the specified
- ; interrupt. Fills the structure up again with the outgoing register values.
- ; NOTE: es and ds are returned in the regs structure, but on input they are
- ; ignored if esdsin is 0. If esdsin is 1, es is used as input; if esdsin is 2,
- ; ds is used as input.
-
- pubproc DIGPRIV _oakint86 <intno, regs, dptr, esdsin>
- push bp
- mov bp,sp
- sub sp, 6 ; make room on stack for auto vars for bx and es and ds.
- pushm <ds, es, si, di>
-
- mov bx, [bp].regs ;get source registers
- IF FAR_DATA
- mov ds, [bp].regs+2 ;get regs segment
- ELSE
- mov [bp-6], ds ; save ds in auto var
- ENDIF
- mov si, [bx].rsi
- mov di, [bx].rdi
- mov dx, [bx].rdx
- mov cx, [bx].rcx
- test word ptr [bp].esdsin, 1
- jz noes
- mov es, [bx].res
- noes:
- test word ptr [bp].esdsin, 2
- jz nods
- mov ax, [bx].rds
- push ax
- mov ax, [bx].rax
- mov bx, [bx].rbx
- pop ds
- jmp ldend
- nods:
- mov ax, [bx].rax
- mov bx, [bx].rbx
- ldend:
-
- push bp ; save bp
-
- ; Prepare to do the interrupt
- mov [bp-2], es ; stash es in auto var
- mov [bp-4], bx ; stash bx in auto var
-
- pushf ; push flags for return
- push cs ; push return address segment
- mov bx, offset back_from_future
- push bx ; push return address offset
-
- mov bx, DOS_IVECSEG
- mov es, bx ; set es to 0 seg for reading int vector
- mov bx, [bp].intno ; get interrupt #
- shl bx, 1
- shl bx, 1 ; multiply intno by 4 to get address of vector
- IF (RATL)
- shl bx, 1 ; multiply intno by 8 to get address of vector
- ENDIF
-
- pushf ; push flags on stack
- push es:[bx+2] ; push interrupt address segment
- push es:[bx] ; push interrupt address offset
-
- mov es, ss:[bp-2] ; get es out from auto var where we stashed it
- mov bx, ss:[bp-4] ; get bx out from auto var where we stashed it
-
- iret ; DO THE INTERRUPT NOW.
- back_from_future:
- ; Interrupt accomplished
- pop bp ; restore bp
-
- pushf
- push ds
- push bx
- mov bx, [bp].regs ; get source registers
- IF FAR_DATA
- mov ds, [bp].regs+2 ; get regs segment
- ELSE
- mov ds, [bp-6]
- ENDIF
- pop [bx].rbx
- pop [bx].rds
- mov [bx].rax, ax
- mov [bx].res, es
- pop ax ; get flags into ax for return
-
- mov [bx].rcx, cx
- mov [bx].rdx, dx
- mov [bx].rdi, di
- mov [bx].rsi, si
-
- popm <di, si, es, ds>
- add sp, 6 ; get auto vars off stack
- pop bp
- ret
- endproc _oakint86
- ; ---------------------------------------------------------------- ;
- ENDPS
- end
- ; ---------------------------------------------------------------- ;
-
-