1 ;
2 ;	_inta	 -	Generalized interrupt service routine
3 ;
4 ;	Copyright (C) 1984-2003 David L. Clark.
5 ;	This program is free software; you can redistribute it and/or modify it under
6 ;	the terms of the GNU General Public License as published by the Free Software
7 ;	Foundation; either version 2 of the License, or (at your option) any later
8 ;	version. This program is distributed in the hope that it will be useful,
9 ;	but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 ;	or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 ;	more details. You should have received a copy of the GNU General Public
12 ;	License along with this program; if not, write to the Free Software Foundation,
13 ;	Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14 ;
15 ;
16 ;			Author: Dave Clark
17 ;
18 ;	Modification History:
19 ;			84-02-22	Development
20 ;			87-03-10	Microsoft compiler
21 ;			94-12-18	C6 Compiler
22 ;			2003-01-27	GNU General Public License
23 ;	Usage:
24 ;		---------------------------------------------------
25 ;
26 ;		_int1vec()
27 ;
28 ;		Provides a list of override interrupt entry points.
29 ;		Performs an iret to the override routine in order
30 ;		to preserve any returned registers.
31 ;
32 ;		IMPORTANT:
33 ;			The old (overridden) interrupt service
34 ;			routines IP:CS is pushed on the stack,
35 ;			as well as the new interrupt routines
36 ;			data segment.
37 ;			To terminate the new routine, do:
38 ;				add	SP,8
39 ;				iret
40 ;			To transfer to the old routine, do:
41 ;				add	sp,2
42 ;				iret
43 ;		---------------------------------------------------
44 ;
45 ;		get_ivec( inum )
46 ;		int	inum;
47 ;
48 ;		returns the long address for the interrupt number
49 ;		---------------------------------------------------
50 ;
51 ;		set_ivec( inum, server )
52 ;		int	inum;
53 ;		long	server;
54 ;
55 ;		returns the long address for the interrupt number
56 ;
57 
58 
59 %	.MODEL	model,lang
60 	INCLUDE mixed.inc
61 
62 	.CODE
63 
64 
65 INTTABSZ	equ	10
66 
67 	include segments.h
68 
69 	public	_int1vec
70 	public	_int2vec
71 	public	set_ivec
72 	public	get_ivec
73 
74 ;
75 ;	vector of interrupt entry points
76 ;
77 
78 _int1vec:
79 	push	CS:i0
80 	jmp	common
81 _int2vec:
82 	push	CS:i1
83 	jmp	common
84 	push	CS:i2
85 	jmp	common
86 	push	CS:i3
87 	jmp	common
88 	push	CS:i4
89 	jmp	common
90 	push	CS:i5
91 	jmp	common
92 	push	CS:i6
93 	jmp	common
94 	push	CS:i7
95 	jmp	common
96 	push	CS:i8
97 	jmp	common
98 	push	CS:i9
99 	jmp	common
100 
101 ;
102 ;	common interrupt handler
103 ;
104 
105 common:
106 	sub	SP,20			; save BX,DS on stack
107 	push	BX
108 	push	DS
109 	add	SP,24
110 
111 	mov	BX,DGROUP		; get DS from save area
112 	mov	DS,BX			;
113 	pop	BX			; get interrupt table offset from stack
114 
115 	pushf				; old routine flags
116 	push	_inttab[BX+6]		;	      CS
117 	push	_inttab[BX+4]		;	      IP
118 	push	DS			; new routine DS
119 	pushf				;	      flags
120 	push	CS			;	      CS
121 	push	_inttab[BX+0]		;	      IP
122 
123 
124 	sub	SP,12			; restore BX,DS
125 	pop	DS
126 	pop	BX
127 	add	SP,8
128 
129 	iret				; iret to interrupt service routine
130 
131 ;
132 ;	if here, the service routine did not iret
133 ;
134 
135 	xor	AH,AH			; terminate program DOS call
136 	int	21H
137 
138 
139 ;	data for push of interrupt number
140 
141 i0	dw	0*INTTABSZ
142 i1	dw	1*INTTABSZ
143 i2	dw	2*INTTABSZ
144 i3	dw	3*INTTABSZ
145 i4	dw	4*INTTABSZ
146 i5	dw	5*INTTABSZ
147 i6	dw	6*INTTABSZ
148 i7	dw	7*INTTABSZ
149 i8	dw	8*INTTABSZ
150 i9	dw	9*INTTABSZ
151 
152 
153 
154 get_ivec:
155 	push	BP			; save frame pointer
156 	mov	BP,SP			; new frame pointer
157 	push	ES			; save registers
158 
159 	mov	AH,35H			; get interrupt function
160 	mov	AL,@AB[BP]		; interrupt number
161 	int	21H			; get server in ES:BX
162 	mov	DX,ES			; return in DX:AX
163 	mov	AX,BX			;
164 
165 	pop	ES			; restore registers
166 	pop	BP			;
167 	ret				; return
168 
169 
170 set_ivec:
171 	push	BP			; save frame pointer
172 	mov	BP,SP			; new frame pointer
173 	push	DS			; save registers
174 
175 	mov	AH,25H			; set interrupt function
176 	mov	AL,@AB[BP]		; interrupt number
177 	lds	DX,dword ptr @AB+2[BP]	; get server in DS:DX
178 	int	21H			; set new server
179 
180 	pop	DS			; restore registers
181 	pop	BP			;
182 	ret				; return
183 
184 
185 
186 	.DATA
187 
188 	extrn	_inttab:word
189 
190 	end
191 