summaryrefslogtreecommitdiff
path: root/v4.0/src/DEV/PRINTER/PRTINT2F.ASM
blob: 82654c52dbc3e366e88475d0f4b4d0ae1f4ceb71 (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
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
PAGE	,132
TITLE	PRINTER.SYS INT2FH Code

;****************** START OF SPECIFICATIONS **************************
;
;  MODULE NAME: PRTINT2F.ASM
;
;  DESCRIPTIVE NAME: PERFORM THE INT2FH FUNCTION OF PRINTER.SYS
;
;  FUNCTION: THE INT2FH FUNCTION OF PRINTER.SYS WILL LOCK THE PRINTER
;	     DEVICE AND LOAD THE CODE PAGE SPECIFIED.  WHEN AN UNLOCK
;	     IS ENCOUNTERED, THE SAVED CODE PAGE WILL BE ACTIVATED.
;	     ATTACHED.
;
;  ENTRY POINT: INT2F_COM
;
;  INPUT: AX = AD40H (CALL IDENTIFIER)
;	  BX = REQUESTED CODE PAGE (-1 FOR UNLOCK)
;	  DX = 0 - LPT1
;	       1 - LPT2
;	       2 - LPT3
;
;  AT EXIT:
;     NORMAL: CARRY CLEAR
;
;     ERROR: CARRY SET - CODE PAGE NOT AVAILABLE OR DEVICE IS NOT CPSW.
;
;  INTERNAL REFERENCES:
;
;     ROUTINES: CHECK_FOR_CP - CHECKS TO SEE IF CODE PAGE REQUESTED IS
;			       AVAILABLE ON DEVICE REQUESTED.
;		FIND_ACTIVE_CP - FINDS THE ACTIVE CODE PAGE ON SPECIFIED
;				 DEVICE; IF AVAILABLE.
;		LOCK_CP - VERIFIES, LOADS, AND LOCKS DEVICE CODE PAGE.
;		UNLOCK_CP - UNLOCKS DEVICE.
;
;     DATA AREAS: INVOKE_BLOCK - PARAMETER BLOCK PASSED TO INVOKE PROC.
;
;
;  EXTERNAL REFERENCES:
;
;     ROUTINES: INVOKE - ACTIVATES FONT REQUESTED.
;
;     DATA AREAS: BUF1 - BUFFER FOR LPT1
;		  BUF2 - BUFFER FOR LPT2
;		  BUF3 - BUFFER FOR LPT3
;
;  NOTES:
;
;  REVISION HISTORY:
;	 A000 - DOS Version 4.00
;
;      Label: "DOS PRINTER.SYS Device Driver"
;	      "Version 4.00 (C) Copyright 1988 Microsoft
;	      "Licensed Material - Program Property of Microsoft"
;
;****************** END OF SPECIFICATIONS ****************************

.XLIST
INCLUDE  STRUC.INC								    ;AN000;
.LIST


INCLUDE   CPSPEQU.INC								    ;AN000;
PRIV_LK_CP   EQU    0AD40H	       ; multiplex number and function		    ;AN000;
LPT1	     EQU    0		       ;					    ;AN000;
LPT2	     EQU    1		       ;					    ;AN000;
LPT3	     EQU    2		       ;					    ;AN000;
UNLOCK	     EQU    -1		       ; unlock the device			    ;AN000;
UNDEFINED    EQU    -1		       ; undefined code page			    ;AN000;
NOT_CY	     EQU    0FFFEH	       ; clear the carry in flag register	    ;AN000;
CY	     EQU    1		       ; set the carry in flag register 	    ;AN000;
FOUND	     EQU    1		       ; search flag				    ;AN000;
NOT_FOUND    EQU    0		       ;					    ;AN000;


PUBLIC	INT2F_COM								    ;AN000;
PUBLIC	ROM_INT2F								    ;AN000;
PUBLIC	ABORT									    ;AN000;


CSEG	SEGMENT PARA PUBLIC 'CODE'                                                  ;AN000;
	ASSUME CS:CSEG								    ;AN000;


EXTRN	INVOKE:NEAR								    ;AN000;
EXTRN	BUF0:BYTE								    ;AN000;
EXTRN	BUF1:BYTE								    ;AN000;
EXTRN	BUF2:BYTE								    ;AN000;
EXTRN	BUF3:BYTE								    ;AN000;

ROM_INT2F    DW     ?		       ; chaining point for INT2FH		    ;AN000;
	     DW     ?								    ;AN000;

COPY_BUF0    DW     0								    ;AN000;
PREV_LOCK    DB     OFF 							    ;AN000;

INVOKE_BLOCK LABEL  BYTE	       ; parameter block passed to INVOKE	    ;AN000;
	     DB     3 DUP(0)	       ;					    ;AN000;
RET_STAT     DW     0		       ; returned status from INVOKE		    ;AN000;
	     DQ     0		       ;					    ;AN000;
	     DB     6 DUP(0)	       ;					    ;AN000;
	     DW     OFFSET PARA_BLOCK  ;					    ;AN000;
CODE_SEGB    DW     SEG CSEG	       ;					    ;AN000;
				       ;
PARA_BLOCK   LABEL  WORD	       ;					    ;AN000;
	     DW     TWO 	       ;					    ;AN000;
REQ_CP	     DW     ?		       ; requested code page to load		    ;AN000;
				       ;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; PROCEDURE_NAME: INT2F_COM
;
; FUNCTION:
; THIS IS THE INTERRUPT 2FH HANDLER TO CAPTURE THE FOLLOWING FUNCTIONS:
;
;   AX=AD40H PRIVELEGED LOCK CP SWITCHING
;
; AT ENTRY: AX = AD40H
;	    BX = CODEPAGE REQUESTED DURING LOCK.
;		 -1 = UNLOCK
;	    DX = 0 - LPT1
;		 1 - LPT2
;		 2 - LPT3
;
;
; AT EXIT:
;    NORMAL: CARRY CLEAR - DEVICE LOADED AND LOCKED
;
;    ERROR: CARRY SET - CODE PAGE NOT AVAILABLE OR DEVICE NOT CPSW.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


INT2F_COM  PROC   NEAR								    ;AN000;
	   STI									    ;AN000;
	   .IF <AX NE PRIV_LK_CP>		; is this for PRINTER?		    ;AN000;
	     JMP    DWORD PTR CS:ROM_INT2F	; no....jump to old INT2F	    ;AN000;
	   .ENDIF				;				    ;AN000;
	   PUSH   AX				;				    ;AN000;
	   PUSH   BP				;				    ;AN000;
	   PUSH   BX				; s    r			    ;AN000;
	   PUSH   CX				;  a	e			    ;AN000;
	   PUSH   DX				;   v	 g			    ;AN000;
	   PUSH   DI				;    e	  s			    ;AN000;
	   PUSH   SI				;				    ;AN000;
	   PUSH   DS				;				    ;AN000;
	   PUSH   ES				;				    ;AN000;
	   MOV	  CS:COPY_BUF0,ZERO		;				    ;AN000;
	   MOV	  CS:CODE_SEGB,CS		;				    ;AN000;
	   MOV	  BP,BX 			; move req. cp to bp		    ;AN000;
	   .SELECT				; depending on the lptx..	    ;AN000;
	   .WHEN <DX EQ LPT1>			; point to the appropriate	    ;AN000;
	     LEA   BX,BUF1			; buffer..			    ;AN000;
	     LEA   SI,BUF0			;				    ;AN000;
	     MOV   CS:COPY_BUF0,SI		;				    ;AN000;
	   .WHEN <DX EQ LPT2>			;				    ;AN000;
	     LEA   BX,BUF2			;				    ;AN000;
	   .WHEN <DX EQ LPT3>			;				    ;AN000;
	     LEA   BX,BUF3			;				    ;AN000;
	   .OTHERWISE				;				    ;AN000;
	     STC				; not a valid lptx..set flag	    ;AN000;
	   .ENDSELECT				;				    ;AN000;
	   .IF NC				; process			    ;AN000;
	     .IF <BP EQ UNLOCK> 		; if unlock requested		    ;AN000;
	       CALL   UNLOCK_CP 		; unlock code page.		    ;AN000;
	     .ELSE				; must be a lock request..	    ;AN000;
	       CALL   LOCK_CP			;				    ;AN000;
	     .ENDIF				;				    ;AN000;
	   .ENDIF				;				    ;AN000;
	   MOV	  SI,CS:COPY_BUF0		;				    ;AN000;
	   PUSHF				;				    ;AN000;
	   .IF <SI NE ZERO>			; if this is lpt1...		    ;AN000;
	     MOV    AX,CS:[BX].STATE		; copy data into prn		    ;AN000;
	     MOV    CS:[SI].STATE,AX		; buffer as well.		    ;AN000;
	     MOV    AX,CS:[BX].SAVED_CP 	;				    ;AN000;
	     MOV    CS:[SI].SAVED_CP,AX 	;				    ;AN000;
	   .ENDIF				;				    ;AN000;
	   POPF 				;				    ;AN000;
	   POP	  ES				;				    ;AN000;
	   POP	  DS				; restore			    ;AN000;
	   POP	  SI				;				    ;AN000;
	   POP	  DI				;    registers			    ;AN000;
	   POP	  DX				;				    ;AN000;
	   POP	  CX				;				    ;AN000;
	   POP	  BX				;				    ;AN000;
	   MOV	  BP,SP 			;				    ;AN000;
	   MOV	  AX,[BP+8]			; load flag onto..		    ;AN000;
	   .IF NC				;				    ;AN000;
	     AND    AX,NOT_CY			;				    ;AN000;
	   .ELSE				;    stack flags		    ;AN000;
	     OR     AX,CY			;				    ;AN000;
	   .ENDIF				;				    ;AN000;
	   MOV	  [BP+8],AX			;				    ;AN000;
	   POP	  BP				;				    ;AN000;
	   POP	  AX				;				    ;AN000;
	   XCHG   AH,AL 			; exchange ah and al to show that.. ;AN000;
ABORT:	   IRET 				; printer.sys is present.	    ;AN000;
INT2F_COM  ENDP 								    ;AN000;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; PROCEDURE_NAME: UNLOCK_CP
;
; FUNCTION:
; THIS FUNCTION UNLOCKS THE DEVICE THAT IS LOCKED.
;
; AT ENTRY:
;	    BX - POINTS TO LPTx BUFFER
;
;
; AT EXIT:
;    NORMAL: CARRY CLEAR - DEVICE UNLOCKED.
;
;    ERROR: CARRY SET - ERROR DURING UNLOCK, ACTIVE CODE PAGE SET TO INACTIVE
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

UNLOCK_CP      PROC  NEAR							    ;AN000;
	       .IF <CS:[BX].STATE EQ LOCKED> NEAR ; is device locked?		    ;AN000;
		 MOV   CS:[BX].STATE,CPSW	  ; change status to unlocked..     ;AN000;
		 MOV   BP,CS:[BX].SAVED_CP	  ; get saved code page 	    ;AN000;
		 .IF <BP NE UNDEFINED>		  ; valid?..... 		    ;AN000;
		   XOR	  AX,AX 		  ;				    ;AN000;
		   CALL   FIND_ACTIVE_CP	  ; find the active code page.	    ;AN000;
		   .IF <BP NE DX>		  ; are they the same..?	    ;AN000;
		     MOV    CS:REQ_CP,BP	  ; no...invoke the saved code page ;AN000;
		     PUSH   CS			  ;				    ;AN000;
		     POP    ES			  ;				    ;AN000;
		     LEA    DI,INVOKE_BLOCK	  ;				    ;AN000;
		     MOV    CS:[BX].RH_PTRO,DI	  ;				    ;AN000;
		     MOV    CS:[BX].RH_PTRS,ES	  ;				    ;AN000;
		     CALL   INVOKE		  ;				    ;AN000;
		     .IF <AL NE ZERO>		  ; error on invoke?		    ;AN000;
		       MOV    AX,ONE		  ; yes...change the active..	    ;AN000;
		       CALL   FIND_ACTIVE_CP	  ; to inactive.		    ;AN000;
		       .IF <CS:COPY_BUF0 NE ZERO> ; do likewise to PRN if this	    ;AN000;
			 PUSH	 BX		  ; is lpt1.			    ;AN000;
			 MOV	 BX,CS:COPY_BUF0  ;				    ;AN000;
			 CALL	 FIND_ACTIVE_CP   ;				    ;AN000;
			 POP	 BX		  ;				    ;AN000;
		       .ENDIF			  ;				    ;AN000;
		       STC			  ; set error flag.		    ;AN000;
		     .ELSE			  ;				    ;AN000;
		       CLC			  ; invoke ok...clear error flag    ;AN000;
		     .ENDIF			  ;				    ;AN000;
		   .ELSE			  ;				    ;AN000;
		     CLC			  ; active = saved ..no invoke...   ;AN000;
		   .ENDIF			  ; clear error 		    ;AN000;
		 .ELSE				  ;				    ;AN000;
		   MOV	  AX,ONE		  ; saved cp was inactive...change..;AN000;
		   CALL   FIND_ACTIVE_CP	  ; active to inactive. 	    ;AN000;
		   .IF <CS:COPY_BUF0 NE ZERO>	  ; do likewise to PRN if this	    ;AN000;
		     PUSH    BX 		  ; is lpt1.			    ;AN000;
		     MOV     BX,CS:COPY_BUF0	  ;				    ;AN000;
		     CALL    FIND_ACTIVE_CP	  ;				    ;AN000;
		     POP     BX 		  ;				    ;AN000;
		   .ENDIF			  ;				    ;AN000;
		   CLC				  ;				    ;AN000;
		 .ENDIF 			  ;				    ;AN000;
		 MOV	CS:[BX].SAVED_CP,UNDEFINED; reset the saved cp		    ;AN000;
	       .ENDIF				  ;				    ;AN000;
	       RET								    ;AN000;
UNLOCK_CP      ENDP								    ;AN000;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; PROCEDURE_NAME: LOCK_CP
;
; FUNCTION:
; THIS FUNCTION LOCKS THE DEVICE WITH THE CODE PAGE REQUESTED.
;
; AT ENTRY: BP - REQUESTED CODE PAGE
;	    BX - POINTS TO LPTx BUFFER
;
;
; AT EXIT:
;    NORMAL: CARRY CLEAR - DEVICE LOCKED.
;
;    ERROR: CARRY SET - ERROR, CODE PAGE NOT LOCKED.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

LOCK_CP        PROC   NEAR							    ;AN000;
	       .IF <CS:[BX].STATE EQ LOCKED>	; if this was previously locked..   ;AN000;
		 MOV	CS:PREV_LOCK,ON 	; then...set flag and...	    ;AN000;
		 MOV	CS:[BX].STATE,CPSW	; change to unlock for this proc    ;AN000;
	       .ELSEIF <CS:[BX].STATE EQ CPSW>	; if this is unlocked...	    ;AN000;
		 MOV	CS:PREV_LOCK,OFF	; then set flag off.		    ;AN000;
	       .ELSE				;				    ;AN000;
		 STC				; neither...set error		    ;AN000;
	       .ENDIF				;				    ;AN000;
	       .IF NC				;				    ;AN000;
		 CALL	CHECK_FOR_CP		; yes..see if req cp is available.  ;AN000;
		 .IF NC 			; yes...			    ;AN000;
		   XOR	   AX,AX		;				    ;AN000;
		   CALL    FIND_ACTIVE_CP	; find the active code page	    ;AN000;
		   .IF <BP NE DX>		; is it the same as requested?..    ;AN000;
		     MOV    CS:REQ_CP,BP	; no..invoke the requested cp	    ;AN000;
		     PUSH   CS			;				    ;AN000;
		     POP    ES			;				    ;AN000;
		     LEA    DI,INVOKE_BLOCK	;				    ;AN000;
		     MOV    CS:[BX].RH_PTRO,DI	;				    ;AN000;
		     MOV    CS:[BX].RH_PTRS,ES	;				    ;AN000;
		     PUSH   DX			;				    ;AN000;
		     CALL   INVOKE		;				    ;AN000;
		     POP    DX			;				    ;AN000;
		     .IF <AL NE ZERO>		; error on invoke?		    ;AN000;
		       STC			; yes...set error flag. 	    ;AN000;
		     .ELSE			;				    ;AN000;
		       MOV    CS:[BX].STATE,LOCKED ; no, 'lock' the printer device  ;AN000;
		       .IF <CS:PREV_LOCK EQ OFF> ; if we were not locked..	    ;AN000;
			 MOV	CS:[BX].SAVED_CP,DX ; and..save the old code page.  ;AN000;
		       .ENDIF			;				    ;AN000;
		       CLC			; clear error flag.		    ;AN000;
		     .ENDIF			;				    ;AN000;
		   .ELSE			;				    ;AN000;
		     MOV    CS:[BX].STATE,LOCKED ; 'lock' the printer device        ;AN000;
		     .IF <CS:PREV_LOCK EQ OFF>	; if we were not locked..	    ;AN000;
		       MOV    CS:[BX].SAVED_CP,DX ; and..save the old code page.    ;AN000;
		     .ENDIF			;				    ;AN000;
		     CLC			; clear the error flag		    ;AN000;
		   .ENDIF			;				    ;AN000;
		 .ENDIF 			;				    ;AN000;
	       .ENDIF				;				    ;AN000;
	       RET								    ;AN000;
LOCK_CP        ENDP								    ;AN000;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; PROCEDURE_NAME: CHECK_FOR_CP
;
; FUNCTION:
; THIS FUNCTION SEARCHES FOR THE CODE PAGE REQUESTED TO SEE IF IT HAS
; BEEN PREPARED OR IS A HARDWARE CODE PAGE
;
;
; AT ENTRY: BP = CODE PAGE REQUESTED
;	    BX - POINTS TO LPTx BUFFER
;
;
; AT EXIT:
;    NORMAL: CARRY CLEAR - CODE PAGE IS VALID.
;
;    ERROR: CARRY SET - CODE PAGE NOT AVAILABLE.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


CHECK_FOR_CP  PROC   NEAR							    ;AN000;
	      PUSH   DX 							    ;AN000;
	      MOV    DX,NOT_FOUND		; initialize flag		    ;AN000;
	      MOV    CX,CS:[BX].RSLMX		; load number of RAM slots	    ;AN000;
	      MOV    DI,CS:[BX].RAMSO		; load DI with table offset	    ;AN000;
	      .WHILE <DX EQ NOT_FOUND> AND	; whil not found and....	    ;AN000;
	      .WHILE <CX NE ZERO>		; while  still slots to check..     ;AN000;
		.IF <CS:[DI].SLT_CP EQ BP>	; is it this one??		    ;AN000;
		  MOV	 DX,FOUND		; yes....set flag		    ;AN000;
		.ELSE				;				    ;AN000;
		  ADD	 DI,TYPE SLTS		; no..point to next entry	    ;AN000;
		  DEC	 CX			; decrement the count		    ;AN000;
		.ENDIF				;				    ;AN000;
	      .ENDWHILE 			;				    ;AN000;
	      .IF <DX EQ NOT_FOUND>		; if we didn't find it then..       ;AN000;
		MOV    CX,CS:[BX].HSLMX 	; check hardware		    ;AN000;
		MOV    DI,CS:[BX].HARDSO	; load regs as before.		    ;AN000;
		.WHILE <DX EQ NOT_FOUND> AND	; while not found and.. 	    ;AN000;
		.WHILE <CX NE ZERO>		; still have slots to check..	    ;AN000;
		  .IF <CS:[DI].SLT_CP EQ BP>	; is it this one?		    ;AN000;
		    MOV    DX,FOUND		; yes...set flag.		    ;AN000;
		  .ELSE 			;				    ;AN000;
		    ADD    DI,TYPE SLTS 	; no ..point to next entry	    ;AN000;
		    DEC    CX			; and decrement count.		    ;AN000;
		  .ENDIF			;				    ;AN000;
		.ENDWHILE			;				    ;AN000;
	      .ENDIF				;				    ;AN000;
	      .IF <DX EQ NOT_FOUND>		;				    ;AN000;
		STC				; set flag appropriately	    ;AN000;
	      .ELSE				;				    ;AN000;
		CLC				;				    ;AN000;
	      .ENDIF				;				    ;AN000;
	      POP    DX 			;				    ;AN000;
	      RET				;				    ;AN000;
CHECK_FOR_CP  ENDP								    ;AN000;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; PROCEDURE_NAME: FIND_ACTIVE_CP
;
; FUNCTION:
; THIS FUNCTION SEARCHES FOR THE ACTIVE CODE PAGE. IF REQUESTED, THE
; CODE PAGE IS MADE INACTIVE.
;
;
; AT ENTRY:
;	    BX - POINTS TO LPTx BUFFER
;	    AX = 0 - LEAVE AS ACTIVE
;	    AX = 1 - DE-ACTIVATE
;
;
; AT EXIT:
;    NORMAL: DX - ACTIVE CODE PAGE.  (NO ACTIVE = -1)
;
;    ERROR: N/A
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


FIND_ACTIVE_CP PROC   NEAR							    ;AN000;
	       MOV    DX,UNDEFINED		 ; initialize register		    ;AN000;
	       MOV    CX,CS:[BX].RSLMX		 ; load number of RAM slots	    ;AN000;
	       MOV    DI,CS:[BX].RAMSO		 ; load DI with table offset	    ;AN000;
	       .WHILE <DX EQ UNDEFINED> AND	 ; whil not found and....	    ;AN000;
	       .WHILE <CX NE ZERO>		 ; while still slots to check..     ;AN000;
		 .IF <BIT CS:[DI].SLT_AT AND AT_ACT> ; is it this one?? 	    ;AN000;
		   MOV	  DX,CS:[DI].SLT_CP	 ; yes....load value		    ;AN000;
		   .IF <AX EQ ONE>		 ; is deactivate requested?	    ;AN000;
		     MOV    CS:[DI].SLT_AT,AT_OCC; yes...change attrib. to occupied ;AN000;
		   .ENDIF			 ;				    ;AN000;
		 .ELSE				 ;				    ;AN000;
		   ADD	  DI,TYPE SLTS		 ; no..point to next entry	    ;AN000;
		   DEC	  CX			 ; decrement the count		    ;AN000;
		 .ENDIF 			 ;				    ;AN000;
	       .ENDWHILE			 ;				    ;AN000;
	       .IF <DX EQ UNDEFINED>		 ; if we didn't find it then..      ;AN000;
		 MOV	CX,CS:[BX].HSLMX	 ; check hardware		    ;AN000;
		 MOV	DI,CS:[BX].HARDSO	 ; load regs as before. 	    ;AN000;
		 .WHILE <DX EQ UNDEFINED> AND	 ; while not found and..	    ;AN000;
		 .WHILE <CX NE ZERO>		 ; still have slots to check..	    ;AN000;
		   .IF <BIT CS:[DI].SLT_AT AND AT_ACT> ; is it this one??	    ;AN000;
		     MOV    DX,CS:[DI].SLT_CP	 ; yes....load value		    ;AN000;
		     .IF <AX EQ ONE>		 ; is deactivate requested?	    ;AN000;
		       MOV    CS:[DI].SLT_AT,AT_OCC; yes...change attrib to occupied;AN000;
		     .ENDIF			 ;				    ;AN000;
		   .ELSE			 ;				    ;AN000;
		     ADD    DI,TYPE SLTS	 ; no ..point to next entry	    ;AN000;
		     DEC    CX			 ; and decrement count. 	    ;AN000;
		   .ENDIF			 ;				    ;AN000;
		 .ENDWHILE			 ;				    ;AN000;
	       .ENDIF				 ;				    ;AN000;
	       RET				 ;				    ;AN000;
FIND_ACTIVE_CP ENDP								    ;AN000;

CSEG	   ENDS
	   END