summaryrefslogtreecommitdiff
path: root/v4.0/src/BIOS/STKINIT.INC
blob: 8298fb8c7bd4b847d4a3caf2f7de6f16fae874b1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
;
;	To follow the standard interrupt sharing scheme, MSSTACK.ASM	       ;3.30
;	has been modified.  This initialization routine also has to	       ;3.30
;	be modified because for the interrupt level 7 and 15, FirstFlag        ;3.30
;	should be set to signal that this interrupt handler is the	       ;3.30
;	first handler hooked to this interrupt vector.			       ;3.30
;	We determine this by looking at the instruction pointed by	       ;3.30
;	this vector.  If it is IRET, then this handler should be the	       ;3.30
;	first one.  In our case, only the interrupt vector 77h is the	       ;3.30
;	interrupt level 15. (We don't hook interrupt level 7.)                 ;3.30
; 9/10/1986 							       ;3.30
;	The followings are mainly due to M.R.T; PTM fix of P886 12/3/86;3.30
;	Some design changes are needed to the above interrupt sharing	       ;3.30
;	method.  The above sharing scheme assumes that 1). Interrupt	       ;3.30
;	sharing is NEVER done on levels that have BIOS support. 2). "Phantom"  ;3.30
;	interrupts would only be generated on levels 7 and 15.		       ;3.30
;	These assumptions are not true any more. We have to use the FirstFlag  ;3.30
;	for EVERY level of interrupt.  We will set the firstFlag on the following;3.30
;	conditions:							       ;3.30
;	 a.	 if the CS portion of the vector is 0000, then "first"         ;3.30
;	 b. else if CS:IP points to valid shared header, then NOT "first"      ;3.30
;	 c. else if CS:IP points to an IRET, then "first"                      ;3.30
;	 d. else if CS:IP points to DUMMY, then "first"                        ;3.30
;	where DUMMY is - the CS portion must be F000, and the IP portion must  ;3.30
;	be equal to the value at F000:FF01. This location is the initial value ;3.30
;	from VECTOR_TABLE for interrupt 7, one of the preserved addresses in all;3.30
;	the BIOSes for all of the machines.				       ;3.30
;									       ;3.30
;	System design group requests BIOS to handle the phantom interrupts.    ;3.30
;									       ;3.30
;	The "Phantom" interrupt is an illegal interrupt such as an interrupt   ;3.30
;	produced by the bogus adapter card even without interrupt request is   ;3.30
;	set.  More specifically, 1). The 8259 has a feature when running in    ;3.30
;	edge triggered mode to latch a pulse and present the interrupt when    ;3.30
;	the processor indicates interrupt acknowledge (INTA).  The interrupt   ;3.30
;	pulse was exist at the time of INTA to get a "phantom" interrupt.      ;3.30
;	2). or, this is caused by adapter cards placing a glitch on the        ;3.30
;	interrupt line. 						       ;3.30
;									       ;3.30
;	To handle those "phantom" interrupts, the main stack code will check   ;3.30
;	the own FirstFlag, and if it is not "first" (which means the forward   ;3.30
;	pointer points to the legal shared interrupt handler), then pass the   ;3.30
;	control.  If it is the first, then the following action should be      ;3.30
;	taken.	We don't have to implement skack logic in this case.           ;3.30
;									       ;3.30
;	To implement this logic, we rather choose a simple method.	       ;3.30
;	If ont of the above "FirstFlag" conditions is met, we are not          ;3.30
;	going to hook this interrupt vector.  The reason is if the original    ;3.30
;	vector points to "IRET" and do nothing, we don't need                  ;3.30
;	to implement the stack logic for it.  This will simplify implementation;3.30
;	while maintaining compatibility with the old version of DOS.	       ;3.30
;	This implies that in the main stack code, there might be a stack code  ;3.30
;	that will never be used, a dead code.				       ;3.30
;									       ;3.30
; 12/3/86								       ;3.30
									       ;3.30
;In - CS, DS -> sysinitseg, ES -> relocated stack code & data.		       ;3.30
									       ;3.30
	PAGE								       ;3.30
	assume  ds:sysinitseg			; sunilp SB340
StackInit	proc near						       ;3.30
									       ;3.30
	PUSH	AX				;SAVE ALL		       ;3.30
	PUSH	DS							       ;3.30
	PUSH	ES							       ;3.30
	PUSH	BX							       ;3.30
	PUSH	CX							       ;3.30
	PUSH	DX							       ;3.30
	PUSH	DI							       ;3.30
	PUSH	SI							       ;3.30
	PUSH	BP							       ;3.30
									       ;3.30
;Currently ES -> stack code area					       ;3.30
	MOV	AX, cs:[STACK_COUNT]		   ;defined in CS	       ;3.30
	MOV	es:[STACKCOUNT], AX		   ;defined in STACK CODE AREA ;3.30
	MOV	AX, [STACK_SIZE]		;in CS			       ;3.30
	MOV	es:[STACKSIZE], AX		   ;			       ;3.30
	MOV	AX, WORD PTR cs:[STACK_ADDR]	   ; OFFSET		       ;3.30
	MOV	WORD PTR es:[STACKS], AX				       ;3.30
	MOV	AX, WORD PTR cs:[STACK_ADDR+WORD]  ; SEGMENT		       ;3.30
	MOV	WORD PTR es:[STACKS+WORD], AX				       ;3.30
									       ;3.30
; INITIALIZE THE DATA FIELDS WITH THE PARAMETERS			       ;3.30
									       ;3.30
; "FIRSTENTRY" WILL ALWAYS BE AT STACKS                                        ;3.30
									       ;3.30
	MOV	BP, word ptr es:STACKS		   ; GET OFFSET OF STACK       ;3.30
	MOV	es:FIRSTENTRY,BP					       ;3.30
									       ;3.30
; THE STACKS WILL ALWAYS IMMEDIATELY FOLLOW THE TABLE ENTRIES		       ;3.30
									       ;3.30
	MOV	AX,ENTRYSIZE						       ;3.30
	MOV	CX,es:STACKCOUNT					       ;3.30
	MUL	CX							       ;3.30
	ADD	AX,BP							       ;3.30
	MOV	es:STACKAT,AX						       ;3.30
	MOV	BX,AX							       ;3.30
	SUB	BX,2							       ;3.30
									       ;3.30
; ZERO THE ENTIRE STACK AREA TO START WITH				       ;3.30
									       ;3.30
	MOV	DI,es:STACKAT						       ;3.30
	MOV	AX,es:STACKSIZE 					       ;3.30
	MUL	CX							       ;3.30
	MOV	CX,AX							       ;3.30
	xor	ax,ax							       ;3.30
	push	es							       ;3.30
	pop	ds				;ds = Relocated stack code seg.;3.30
	assume	ds:nothing						       ;3.30
;Now, DS -> stack code area						       ;3.30
	MOV	ES, word ptr ds:[STACKS+2]	   ; GET SEGMENT OF STACK AREA.;3.30
	CLD								       ;3.30
	REP	STOSB							       ;3.30
									       ;3.30
	MOV	CX, ds:STACKCOUNT					       ;3.30
									       ;3.30
; LOOP FOR "COUNT" TIMES, BUILDING A TABLE ENTRY                               ;3.30
;  cs = sysinitseg, ds = Relocated stack code seg , es = segment of stack space;3.30
;  CX = NUMBER OF ENTRIES						       ;3.30
;  ES:BP => BASE OF STACKS - 2						       ;3.30
;  ES:BX => FIRST TABLE ENTRY						       ;3.30
									       ;3.30
BUILDLOOP:								       ;3.30
	MOV	ALLOCBYTE,FREE						       ;3.30
	MOV	INTLEVEL,AL			;AX = 0 		       ;3.30
	MOV	SAVEDSP,AX						       ;3.30
	MOV	SAVEDSS,AX						       ;3.30
	ADD	BX,ds:STACKSIZE 					       ;3.30
	MOV	NEWSP,BX						       ;3.30
	MOV	ES:[BX],BP						       ;3.30
	ADD	BP,ENTRYSIZE						       ;3.30
									       ;3.30
	LOOP	BUILDLOOP						       ;3.30
									       ;3.30
	SUB	BP,ENTRYSIZE						       ;3.30
	MOV	ds:LASTENTRY,BP 					       ;3.30
	MOV	ds:NEXTENTRY,BP 					       ;3.30
									       ;3.30
	push	ds							       ;3.30
	mov	ax, 0f000h		;loook at the model byte	       ;3.30
	mov	ds, ax							       ;3.30
	cmp	ds:byte ptr [0fffeh], mdl_convert	;convertible?	       ;3.30
	pop	ds							       ;3.30
	jne	Skip_disableNMIS					       ;3.30
									       ;3.30
	MOV	AL,07H				; DISABLE Convertible NMIS	       ;3.30
	OUT	72H,AL							       ;3.30
									       ;3.30
Skip_disableNMIS:							       ;3.30
	XOR	AX,AX							       ;3.30
	MOV	es,AX				;es - SEGID OF VECTOR TABLE AT 0;3.30
	ASSUME	es:NOTHING			;ds - Relocated Stack code segment;3.30
									       ;3.30
	CLI								       ;3.30
									       ;3.30
	IRP	AA,<02,08,09,70>					       ;3.30
									       ;3.30
	MOV	SI,AA&H*4		;PASS WHERE VECTOR IS TO BE ADJUSTED   ;3.30
	mov	di, offset Int19OLD&AA	       ;we have to set OLD&AA for Int19 handler too.;3.30
	MOV	BX,OFFSET OLD&AA	;PASS WHERE TO SAVE ORIGINAL OWNER POINTER;3.30
	MOV	DX,OFFSET INT&AA	;PASS WHERE NEW HANDLER IS	       ;3.30
	CALL	NEW_INIT_LOOP		;ADJUST THE VECTOR TO NEW HANDLER,     ;3.30
					;  SAVING POINTER TO ORIGINAL OWNER    ;3.30
	ENDM								       ;3.30
									       ;3.30
	IRP	AA,<0A,0B,0C,0D,0E,72,73,74,76,77>	;shared interrupts     ;3.30
									       ;3.30
	MOV	SI,AA&H*4		;PASS WHERE VECTOR IS TO BE ADJUSTED   ;3.30
	push	ds			;save relocated stack code segment     ;3.30
	lds	bx, es:[si]		;ds:bx -> original interrupt handler   ;3.30
	push	ds							       ;3.30
	pop	dx			;dx = segment value		       ;3.30

	cmp	dx,0
	jz	int&AA&_first

	cmp	byte ptr ds:[bx],0cfh	;Does vector point to an IRET?
	jz	int&AA&_first

	cmp	word ptr ds:[bx.6],424Bh ;Magic offset (see INT&AA, msstack.inc)
	jz	int&AA&_Not_first

	cmp	dx,0f000h		;ROM BIOS segment
	jnz	int&AA&_Not_first

	push	es
	push	dx
	mov	dx,0f000h
	mov	es,dx
	cmp	bx,word ptr es:0ff01h
       	pop	dx
	pop	es
	jz	int&AA&_first

int&AA&_Not_first:			 ;Not the first. We are going to hook vector.;3.30
	pop	ds							       ;3.30
	mov	di, offset Int19OLD&AA	;we have to set OLD&AA for Int19 handler too.;3.30
	mov	BX, OFFSET OLD&AA	;PASS WHERE TO SAVE ORIGINAL OWNER POINTER;3.30
	MOV	DX, OFFSET INT&AA	;PASS WHERE NEW HANDLER IS	       ;3.30
	CALL	NEW_INIT_LOOP		;ADJUST THE VECTOR TO NEW HANDLER, SAVING;3.30
					;POINTER TO ORIGINAL OWNER.	       ;3.30
	jmp	short int&AA&_end					       ;3.30
int&AA&_first:				 ;the first. Don't have to hook stack code.;3.30
	pop	ds							       ;3.30
int&AA&_end:								       ;3.30
									       ;3.30
	ENDM								       ;3.30
									       ;3.30
	push	ds							       ;3.30
	mov	ax, 0f000h		;loook at the model byte	       ;3.30
	mov	ds, ax							       ;3.30
	cmp	ds:byte ptr [0fffeh], mdl_convert	;PC convertible?	       ;3.30
	pop	ds							       ;3.30
	jne	Skip_EnableNMIS 					       ;3.30
									       ;3.30
	MOV	AL,27H				; ENABLE Convertible NMIS	       ;3.30
	OUT	72H,AL							       ;3.30
									       ;3.30
Skip_EnableNMIS:							       ;3.30
	STI								       ;3.30
	MOV	AX,code 						       ;3.30
	MOV	DS,AX							       ;3.30
	ASSUME	DS:CODE 						       ;3.30
									       ;3.30
;	MOV	SI,OFFSET STKMSG1					       ;3.30
;	CALL	WRMSG							       ;3.30
									       ;3.30
	mov	[INT19SEM],1		; INDICATE THAT INT 19		       ;3.30
					; INITIALIZATION IS COMPLETE	       ;3.30
									       ;3.30
	POP	BP			; RESTORE ALL			       ;3.30
	POP	SI							       ;3.30
	POP	DI							       ;3.30
	POP	DX							       ;3.30
	POP	CX							       ;3.30
	POP	BX							       ;3.30
									       ;3.30
	POP	ES							       ;3.30
	POP	DS							       ;3.30
	assume	ds:sysinitseg						       ;3.30
	POP	AX							       ;3.30
	RET								       ;3.30
STACKINIT	ENDP							       ;3.30
;									       ;3.30
									       ;3.30
NEW_INIT_LOOP PROC NEAR 						       ;3.30
;INPUT: SI=OFSET INTO VECTOR TABLE OF THE PARTICULAR INT VECTOR BEING ADJUSTED ;3.30
;	BX=ds:OFFSET OF OLDxx, WHERE WILL BE SAVED THE POINTER TO ORIGINAL OWNER;3.30
;	DX=ds:OFFSET OF INTxx, THE NEW INTERRUPT HANDLER		       ;3.30
;	di=offset value of Int19OLD&AA variable in BIOS.		       ;3.30
;	es=ZERO, SEGID OF VECTOR TABLE					       ;3.30
;	ds=Relocated Stack code segment 				       ;3.30
									       ;3.30
	MOV	AX,es:[SI+0]	       ;REMEMBER OFFSET IN VECTOR	       ;3.30
	MOV	WORD PTR ds:[BX],AX	  ; TO ORIGINAL OWNER in DS	       ;3.30
	MOV	AX,es:[SI+2]	       ;REMEMBER SEGID IN VECTOR	       ;3.30
	MOV	WORD PTR ds:[BX]+2,AX	  ; TO ORIGINAL OWNER in DS	       ;3.30
	push	ds							       ;3.30
	mov	ax, code						       ;3.30
	mov	ds, ax			;Set Int19OLDxx value in BIOS for      ;3.30
	mov	ax,es:[si+0]		;Int 19 handler 		       ;3.30
	mov	word ptr ds:[di],ax					       ;3.30
	mov	ax,es:[si+2]						       ;3.30
	mov	word ptr ds:[di]+2,ax					       ;3.30
	pop	ds							       ;3.30
									       ;3.30
	MOV	WORD PTR es:[SI+0],DX  ;SET VECTOR TO POINT TO NEW INT HANDLER ;3.30
	MOV	es:[SI+2],ds						       ;3.30
	RET								       ;3.30
NEW_INIT_LOOP ENDP							       ;3.30
									       ;3.30