Category : C++ Source Code
Archive   : VCCRT2.ZIP
Filename : INT86X.ASM
Output of file : INT86X.ASM contained in archive : VCCRT2.ZIP
title int86x - interrupt with given registers
;***
;int86x.asm - interrupt with given regs and seg regs
;
; Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
;
;Purpose:
; defines int86x() - interrupt with given regs and seg regs
;
;*******************************************************************************
include version.inc
.xlist
include cmacros.inc
.list
OFFAX = 0
OFFBX = 2
OFFCX = 4
OFFDX = 6
OFFSI = 8
OFFDI = 10
OFFC = 12
OFFES = 0
OFFDS = 6
externP _maperror
ifdef _WINDOWS
extrn ALLOCDSTOCSALIAS:far
extrn FREESELECTOR:far
endif
sBegin code
assumes cs,code
assumes ds,data
page
;***
;int _int86x(intno, inregs, outregs, segregs) - do 8086 interrupt
;
;Purpose:
; calls the sepcified DOS interrupt with the registers as specified
; in inregs and ES and DS from segregs; copies the registers, ES,
; and DS into outregs and segregs on return.
;
;Entry:
; int intno - interrupt to execute
; union REGS *inregs - registers on entry to interrupt
; union REGS *outregs - registers on exit from interrupt
; struct SREGS *segregs - seg register: input and output
; (only ES and DS are used)
;
;Exit:
; returns value in AX after interrupt
;
;Uses:
;
;Exceptions:
;
;*******************************************************************************
cProc _int86x,
parmw intno
parmdp inregs
parmdp outregs
parmdp segregs
ifdef _WINDOWS
ife sizeD
; Small data model windows libs
localW saveds
endif
endif
cBegin
ifdef _WINDOWS
ife sizeD
mov [saveds],ds ; save ds for later
endif
endif
;
; the stack is made to look like this:
;
; -------------------
; | outregs | (arg3)
; -------------------
; | inregs | (arg2)
; -------------------
; | intno | (arg1)
; -------------------
; | ret addr |
; -------------------
; bp-> | old bp |
; -------------------
; | old di |
; -------------------
; | old si |
; -------------------
; | old ds |
; -------------------
; |
; -------------------
; | 'retf'| |
; -------------------
; | 'inc sp inc sp' | <- only in if int 25 or int 26
; -------------------
; | 'int' | intno | <- we do a long call to 'int' opcode
; -------------------
; | ss |
; -------------------
; (bp)->| offset of 'int' |
; -------------------
;
;
; Define BP-relative offset values to this frame
; (In small data model windows, account for the extra word on the stack)
;
ifdef _WINDOWS
ife sizeD
BASE EQU
else
BASE EQU
endif
else
BASE EQU
endif
BP_INT EQU
BP_INTNUM EQU
BP_RETF EQU
BP_RETFX EQU
BP_INCSP1 EQU
BP_INCSP2 EQU
BP_SEGADDR EQU
BP_OFFADDR EQU
;
; Set up this stack
;
sub sp,10 ; room for 5 words
mov byte ptr [BP_INT],0cdh ; an 'int' opcode
mov ax,intno
mov [BP_INTNUM],al ; the interrupt number
cmp al,25h
je abnorm
cmp al,26h
je abnorm
mov byte ptr [BP_RETF],0cbh ; a 'retf' opcode
jmp short continue
abnorm:
mov byte ptr [BP_RETFX],0cbh ; a 'retf' opcode
mov byte ptr [BP_INCSP1],044h ; a 'inc sp' opcode for flags on stack
mov byte ptr [BP_INCSP2],044h ; a 'inc sp' opcode for flags on stack
continue:
ifdef _WINDOWS
push ss
call ALLOCDSTOCSALIAS; can't exec code on stack
mov [BP_SEGADDR],ax ; seg part of far call addr, using CS alias
else
mov [BP_SEGADDR],ss ; seg part of far call addr
endif
lea ax,[BP_INT] ; offset part of far call addr
mov [BP_OFFADDR],ax ; we're going to jump onto the stack
if sizeD
lds di,inregs ; get union REGS addr
else
mov di,inregs ; get union REGS addr
endif
mov ax,[di+OFFAX]
mov bx,[di+OFFBX]
mov cx,[di+OFFCX]
mov dx,[di+OFFDX]
mov si,[di+OFFSI]
push [di+OFFDI] ; save di, need it for indexing
if sizeD
lds di,segregs ; get struct SREGS addr
else
mov di,segregs ; get struct SREGS addr
endif
mov es,[di+OFFES]
mov ds,[di+OFFDS]
pop di ; restore di
push bp
clc ; clear carry before int
call dword ptr [BP_OFFADDR] ; execute interrupt
pop bp ; bp points to old bp
cld ; ensure that direction is "up"
push di ; save di
push ds
if sizeD
lds di,segregs ; get struct SREGS addr
else
ifdef _WINDOWS
mov ds,[saveds] ; restore ds from stack
else
push ss
pop ds ; in case interrupt smashed ds
endif ;_WINDOWS
mov di,segregs ; get struct SREGS addr
endif ;sizeD
mov [di+OFFES],es
pop [di+OFFDS]
if sizeD
lds di,outregs ; get union REGS addr
else
mov di,outregs ; get union REGS addr
endif
mov [di+OFFAX],ax
mov [di+OFFBX],bx
mov [di+OFFCX],cx
mov [di+OFFDX],dx
mov [di+OFFSI],si
pop [di+OFFDI] ; restore di
ifdef _WINDOWS
push ax ; save return value
lahf
push ax ; save carry flag
push [BP_SEGADDR]
call FREESELECTOR ; free DS-to-CS alias selector
pop ax ; restore carry flag
sahf
pop ax ; restore return value
endif
jc carry ; test carry flag
xor si,si
jmp short toend
carry:
if sizeD
push ds ; save segment of REGS parameter
;
mov cx,DGROUP
mov ds,cx ; restore DS to DGROUP
endif
callcrt __maperror
if sizeD
pop ds ; restore segment of REGS parameter
endif
mov si,1
mov ax,[di+OFFAX] ; restore ax after mapping error
toend:
mov [di+OFFC],si ; set carry/no carry flag
add sp,10 ; to get back to old sp
cEnd
sEnd
end
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/