summaryrefslogtreecommitdiff
path: root/v4.0/src/DEV/XMA2EMS
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/DEV/XMA2EMS')
-rw-r--r--v4.0/src/DEV/XMA2EMS/DIAGS.ASM1909
-rw-r--r--v4.0/src/DEV/XMA2EMS/EMSINIT.INC886
-rw-r--r--v4.0/src/DEV/XMA2EMS/EMS_US.MSG110
-rw-r--r--v4.0/src/DEV/XMA2EMS/GENIOCTL.INC167
-rw-r--r--v4.0/src/DEV/XMA2EMS/I13HOOK.INC449
-rw-r--r--v4.0/src/DEV/XMA2EMS/LIM40.INC1792
-rw-r--r--v4.0/src/DEV/XMA2EMS/LIM40B.INC3468
-rw-r--r--v4.0/src/DEV/XMA2EMS/MAKEFILE24
-rw-r--r--v4.0/src/DEV/XMA2EMS/PARMPARS.INC530
-rw-r--r--v4.0/src/DEV/XMA2EMS/PS2_5060.INC735
-rw-r--r--v4.0/src/DEV/XMA2EMS/ROMSCAN.INC420
-rw-r--r--v4.0/src/DEV/XMA2EMS/XMA1DIAG.INC1870
-rw-r--r--v4.0/src/DEV/XMA2EMS/XMA2EMS.ASM2591
-rw-r--r--v4.0/src/DEV/XMA2EMS/XMA2EMS.LC11
-rw-r--r--v4.0/src/DEV/XMA2EMS/XMA2EMS.SKL39
-rw-r--r--v4.0/src/DEV/XMA2EMS/XMA2EMSP.INC243
16 files changed, 15244 insertions, 0 deletions
diff --git a/v4.0/src/DEV/XMA2EMS/DIAGS.ASM b/v4.0/src/DEV/XMA2EMS/DIAGS.ASM
new file mode 100644
index 0000000..6c52a1c
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/DIAGS.ASM
@@ -0,0 +1,1909 @@
1;-----------------------------------------------------------------------;
2; DATA THAT IS UNIQUE TO THE DIAGNOSTICS PORTION OF ;
3; THE DEVICE DRIVER. THIS AREA WILL NOT REMAIN PRESENT ;
4; AFTER INITIALIZATION. ;
5;-----------------------------------------------------------------------;
6INCLUDE EMS_US.MSG
7
8MEM_INST DB '1'
9ADDR_MODEL_BYTE DD 0F000FFFEH ;ADDRESS IN BIOS OF MODEL BYTE
10MODEL DB ? ;SAVE AREA FOR MODEL
11TEST_ID DB ? ;SAVE AREA FOR CURRENT TEST ID
12CTRLPARM DW ? ;SAVE AREA FOR CONTROL PARM
13PAGE_UNDER_TEST DW 0 ;SAVE AREA FOR PAGE UNDER TEST
14CUR_SAVE DW ? ;SAVE AREA FOR NEXT AVAILABLE LINE
15 ;FOR MESSAGES
16ACTIVE_PAGE DB ? ;ACTIVE DISPLAY PAGE
17TESTABLE_SEGMENTS DW ?
18
19
20PAGE
21;-----------------------------------------------------------------------;
22; EQUATES THAT ARE UNIQUE TO THE DIAGNOSTICS PORTION OF ;
23; THE DEVICE DRIVER. ;
24;-----------------------------------------------------------------------;
25BASE_REG EQU 31A0H
26DMACAPT EQU 31A8H ;I/O ADDRESS OF DMA CAPTURE REG
27BLK_ON EQU 11110111B ;MASK FOR ENABLING A BLOCK
28BLK_OFF EQU 00001000B ;MASK FOR INHIBITING A BLOCK
29VIRT_MODE EQU 00000010B ;MASK FOR VIRTUAL MODE
30REAL_MODE EQU 11111101B ;MASK FOR REAL MODE
31MAX_TASK_ID EQU 15 ;MAXIMIM TASK ID
32ENABLE EQU 01H ;INDICATES THAT BLOCK SHOULD BE ENABLED
33TABLEN EQU 1000H ;NUMBER OF ENTRIES IN XLAT TABLE
34DMAREQ1 EQU 0009H ;I/O ADDRESS OF DMA CTRL 1 REQ REG
35DMAREQ2 EQU 00D2H ;I/O ADDRESS OF DMA CTRL 2 REQ REG
36DMAMODE1 EQU 000BH ;I/O ADDRESS OF DMA CTRL 1 MODE REG
37DMAMODE2 EQU 00D6H ;I/O ADDRESS OF DMA CTRL 2 MODE REG
38PC1 EQU 0FFH ;RESERVED BYTE FOR PC1
39PC_XT EQU 0FEH ;RESERVED BYTE FOR XT
40XT_AQUARIUS EQU 0FBH ;RESERVED BYTE FOR XT-AQUARIUS
41AT_NMI_REG EQU 70H ;AT NMI REG
42AT_NMI_OFF EQU 80H ;AT NMI OFF MASK
43AT_NMI_ON EQU 00H ;AT NMI ON MASK
44AT_CHCHK_EN_REG EQU 61H ;AT CH CHK ENABLE REG
45AT_CHCHK_REG EQU 61H ;AT CH CHK REG
46AT_CHCHK_EN EQU 0F7H ;AT CH CHK ENABLE MASK
47AT_CHCHK_DIS EQU 08H ;AT CH CHK DISABLE MASK
48AT_CHCHK EQU 40H ;AT CH CHK MASK
49XT_NMI_REG EQU 0A0H ;XT NMI REG
50XT_NMI_OFF EQU 00H ;XT NMI OFF MASK
51XT_NMI_ON EQU 80H ;XT NMI ON MASK
52XT_CHCHK_EN_REG EQU 61H ;XT CH CHK ENABLE REG
53XT_CHCHK_REG EQU 62H ;XT CH CHK REG
54XT_CHCHK_EN EQU 0DFH ;XT CH CHK ENABLE MASK
55XT_CHCHK_DIS EQU 20H ;XT CH CHK DISABLE MASK
56XT_CHCHK EQU 40H ;XT CH CHK MASK
57ONE_MEG EQU 16 ;CONSTANT FOR ONE MEG MEMORY CARD
58TWO_MEG EQU 32 ;CONSTANT FOR TWO MEG MEMORY CARD
59CR EQU 0DH ;CARRIAGE RETURN
60LF EQU 0AH ;LINE FEED
61PRES_TEST EQU 01 ;PRESENCE TEST ID
62REG_TEST EQU 02 ;REG TEST ID
63AUTO_INC EQU 03 ;AUTO INC TEST ID
64XLAT_TABLE_TEST EQU 04 ;TT TEST ID
65LOMEM_TEST EQU 05 ;ABOVE 640K TEST ID
66DMA_CAPTURE EQU 06 ;DMA CAPTURE TEST ID
67PAGE_TEST EQU 07 ;PAGE TEST ID
68MEM_TEST EQU 10 ;MEMORY TEST ID
69
70
71;------------------------------------------------------------------------;
72; Diagnostics...on exit if ZF=0 then error ;
73;------------------------------------------------------------------------;
74DIAGS PROC
75
76 MOV CS:TEST_ID,00H ;CLEAR TEST ID BYTE
77 MOV CS:CTRLPARM,0100H ;SAVE CONTROL PARM
78 CALL GETMOD ;FIND OUT WHICH PC THIS IS
79 CALL CUR_POS ;GET CURSOR READY FOR MESSAGES
80 CALL REGTST ;TEST XMA REGISTERS
81 JNE FOUND_ERROR ;JUMP IF ERROR
82 CALL INCTST
83 JNE FOUND_ERROR
84 CALL XLATST
85 JNE FOUND_ERROR
86 CALL LOMEMTST ;TEST FOR BELOW 640K
87 JNE FOUND_ERROR ;JUMP IF ERROR
88 CALL MEMARRAY ;TEST MEMORY ABOVE 640K
89 JNE FOUND_ERROR ;JUMP IF ERROR
90 CALL PAGETST
91 JNE FOUND_ERROR
92 CALL CAPTST ;TEST DMA CAPTURE
93 JNE FOUND_ERROR ;JUMP IF ERROR
94FOUND_ERROR:
95 RET
96DIAGS ENDP
97
98
99
100
101PAGE
102;-------------------------------------------------------------------------
103;-------------------------------------------------------------------------
104;
105; PRESENCE TEST
106;
107; DESCRIPTION : This routine will determine if the XMA is in the system.
108; It will also determine the amount of memory installed
109; on the card in 1Meg increments (up to 4Meg).
110;
111; FUNCTION/ : See description
112; PURPOSE
113;
114; ENTRY POINT : PRESTST
115;
116; ENTRY : The assumption is that at least 1MB of memory is installed.
117; CONDITIONS If the 2nd, 3rd or 4th MB of memory is installed then the
118; TOTAL_XMA_PAGES, TOTAL_PAGES, FREE_PAGES and
119; MEM_INST words are Revised accordingly.
120;
121;
122;
123; EXIT : (zero flag) = 0 indicates that the XMA is not installed.
124; if (zero flag) <> 0 then
125; TOTAL_XMA_PAGES, TOTAL_PAGES, FREE_PAGES and
126; MEM_INST words are Revised accordingly.
127;
128; AX,BX,CX,DX ARE DESTROYED
129;-------------------------------------------------------------------------
130;
131PRESTST PROC
132;
133 MOV AL,PRES_TEST
134 MOV CS:TEST_ID,AL
135
136;SAVE CONTENTS OF MODE REG
137 MOV DX,MODE_REG
138 IN AL,DX
139 PUSH AX
140
141; TRANSLATE TABLE ADDRESS AND DATA REGISTERS
142;
143 MOV AX,0AA55H ;DATA PATTERN (IN REAL MODE)
144 ;BE CERTAIN MODE REG GETS
145 ;REAL MODE
146 MOV DX,MODE_REG ;I/O TO MODE REG
147 OUT DX,AL ;WRITE PATTERN
148 MOV DX,TTPOINTER + 1 ;I/O TO TT POINTER (ODD ADDR)
149 XCHG AL,AH ;CHRG BUS WITH INVERSE PATTERN
150 OUT DX,AL ;WRITE IT
151 MOV DX,MODE_REG
152 IN AL,DX ;READ BACK MODE REG
153 XOR AL,AH
154 AND AL,0FH ;MASK OFF UNUSED BITS
155 ;ZERO FLAG = 0 IF ERROR
156END_PRES:
157 POP AX
158 PUSHF ;SAVE FLAGS
159 MOV DX,MODE_REG
160 OUT DX,AL ;RESTORE MODE REG TO INITIAL STATE
161 POPF ;RESTORE FLAGS
162 RET ;BACK TO CALLER
163;
164PRESTST ENDP
165
166
167
168
169PAGE
170;-------------------------------------------------------------------------
171;-------------------------------------------------------------------------
172;
173; SAVES CURSOR POSITION
174;
175; DESCRIPTION : This routine simply saves the cursor location
176; in CS:CUR_SAVE. This cursor position
177; should be used by the KB_OK routine to insure proper
178; format of the screen.
179;
180; FUNCTION/ : See description
181; PURPOSE
182;
183;
184; ENTRY POINT : CUR_POS
185;
186; ENTRY :
187; CONDITIONS
188;
189;
190; EXIT : new cursor position is saved in CS:CUR_SAVE
191;
192; All registers are preserved
193;
194;-------------------------------------------------------------------------
195;
196CUR_POS PROC
197;
198 PUSH AX
199 PUSH BX
200 PUSH CX
201 PUSH DX
202 PUSH SI
203 PUSH DI
204 PUSH DS ;SAVE REGISTERS
205;
206 PUSH CS
207 POP DS ;GET DS TO THIS CODE SEGMENT
208 ;MOVE CURSOR TO NEXT AVAILABLE LINE
209;IF DOS
210; MOV AH,9 ;DOS PRINT STRING
211; MOV DX,OFFSET NEXT_LINE + 1 ;OFFSET OF NEXT LINE MSG
212; INT 21H ;DISPLAY MESSAGE
213;ELSE
214; MOV BX,OFFSET NEXT_LINE ;GET OFFSET OF NEXT LINE MSG
215; MOV AH,0 ;TELL DCP TO DISPLAY
216; INT 82H ;DISPLAY MESSAGE
217;ENDIF
218 ; rsh001 fix scroll problem
219 ; and remove IF DOS crap
220 ;READ CURRENT VIDEO PAGE ; rsh001
221 MOV AH,15 ;READ CURRENT Video Page
222 INT 10H ;VIDEO CALL
223 MOV ACTIVE_PAGE,BH ;SAVE ACTIVE PAGE
224
225 ;READ CURRENT CURSOR POSITION
226 MOV AH,3 ;READ CURRENT CURSOR POS
227 INT 10H ;VIDEO CALL
228 MOV CUR_SAVE,DX ;SAVE CURSOR POSITION
229
230 ;RESTORE ALL REGISTERS
231 POP DS
232 POP DI
233 POP SI
234 POP DX
235 POP CX
236 POP BX
237 POP AX ;RESTORE ALL REGISTERS
238
239 RET ;RETURN TO CALLER
240
241CUR_POS ENDP
242
243
244
245
246
247PAGE
248;-------------------------------------------------------------------------
249;-------------------------------------------------------------------------
250;
251; TEST FOR PRESENCE OF MORE THAN 1 MEGABYTE OF MEMORY
252;
253; DESCRIPTION : This routine will determine if the 2nd, 3rd or 4th MB is
254; installed. Since there are no switches or other indicators
255; to be tested, this test will make a "best guess" as to
256; the presence of this memory. This test will roll a 0
257; and a 1 through the 1st word of the next Meg and if
258; at least 1 bit is consistently good then it is assumed
259; that the optional memory is installed. If successful
260; then try next Meg.
261;
262; FUNCTION/ : See description
263; PURPOSE
264;
265; ENTRY POINT : TRY4MEG
266;
267; ENTRY : none
268; CONDITIONS
269;
270; EXIT :
271;
272; AX,BX,CX,DX ARE DESTROYED
273;-------------------------------------------------------------------------
274;
275TRY4MEG PROC
276
277;MEMORY TEST MUST RUN IN PAGE MODE
278;BEFORE CARD IS PUT INTO PAGE MODE...MUST SET UP XLAT TABLE TO PASSOVER
279;RESERVED MEMORY SPACES (IE.,BIOS, DISPLAY, DISTRIBUTED ROS, ETC)
280;
281 CALL VIRT2REAL
282
283 MOV DX,IDREG ;I/O TO ID REGISTER
284 MOV AL,0 ;ID = 0
285 OUT DX,AL ;SWITCH TO ID = 0
286;
287 ;DISABLE NMI AND ENABLE I/O CHANNEL CHECK
288 MOV AL,CS:MODEL ;GET SAVED MODEL BYTE
289 CMP AL,PC1 ;IS IT A PC1?
290 JE TR2M1 ;IF NO THEN TRY FOR PC_XT
291 CMP AL,PC_XT ;IS IT AN XT?
292 JE TR2M1 ;IF NO THEN TRY FOR AQUARIUS
293 CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS?
294 JE TR2M1 ;IF NO THEN USE AT NMI REGS
295 ;USE PC-AT NMI REGISTER
296 MOV DX,AT_NMI_REG ;AT's NMI REGISTER
297 MOV AL,AT_NMI_OFF ;MASK OFF NMI
298 OUT DX,AL ;OUTPUT IT
299 MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG
300 IN AL,DX ;READ IT
301 OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
302 OUT DX,AL ;WRITE IT
303 AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
304 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
305 ;ENABLED
306 ;USE PC1, XT, AQUARIUS REGISTERS
307TR2M1:
308 MOV DX,XT_NMI_REG ;XT's NMI REGISTER
309 MOV AL,XT_NMI_OFF ;MASK OFF NMI
310 OUT DX,AL ;OUTPUT IT
311 MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG
312 IN AL,DX ;READ IT
313 OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
314 OUT DX,AL ;WRITE IT
315 AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
316 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
317 ;ENABLED
318;
319 ;MAP FIRST 64K OF 2ND MEG INTO PC SPACE BEGINNING AT 512K
320;***jnw MOV CX,3 ;LOOK FOR PRESENCE OF NEXT 3 MB IN 1MB STEPS
321 MOV CX,99*1024/16 ;***jnw ;LOOK FOR PRESENCE OF NEXT n MB IN 1MB STEPS
322 MOV AX,CS:PAGE_FRAME_STA ;SEGMENT AT PAGE FRAME
323;***jnw MOV DX,256 ;BEGINNING AT 2ND MEG OF XMA
324 MOV DX,256+3 ;***jnw ;AT end of 16k
325 MOV BH,0 ;ASSIGNED TO TASK ID 0
326 MOV BL,01H ;ENABLE THIS MEMORY
327TR2M1A:
328 PUSH AX
329 PUSH BX
330 PUSH CX
331 PUSH DX
332;***jnw MOV CX,16 ;16 * 4K = 64K BLOCK
333 MOV CX,1 ;***jnw ;1 * 4K = 4K BLOCK
334 CALL SETXLAT ;SET TRANSLATE TABLE
335;
336 MOV AX,CS:PAGE_FRAME_STA
337 MOV DS,AX ;SET SEGMENT AND
338 MOV SI,0 ;OFFSET TO TEST
339 MOV BX,0000000000000001B ;ROLL 1 THROUGH WORD
340 MOV DX,1111111111111110B ;ROLL 0 THROUGH WORD
341 MOV CX,16 ;16 BITS TO TEST
342TR2M2:
343 MOV [SI],BX ;WRITE ROLLING 1 PATTERN
344 LOCK MOV [SI+2],DX ;CHARGE BUS INVERSE PATTERN
345 LOCK MOV AX,[SI] ;READ BACK INITIAL PATTERN
346 AND AX,BX ;ISOLATE BIT UNDER TEST
347;***jnw JZ TR2M3 ;IF ZERO TRY ANOTHER BIT
348 JZ quit ;IF ZERO quit ***jnw
349 MOV [SI],DX ;WRITE ROLLING 0 PATTERN
350 LOCK MOV [SI+2],BX ;CHARGE BUS INVERSE PATTERN
351 LOCK MOV AX,[SI] ;READ BACK INITIAL PATTERN
352 AND AX,BX ;ISOLATE BIT UNDER TEST
353 AND AX,BX ;ISOLATE BIT UNDER TEST
354;***jnw JZ TR2M4 ;IF ZERO THEN FOUND GOOD BIT
355 Jnz quit ;IF nonzero then quit ***jnw
356TR2M3:
357 ROL BX,1 ;ROLL 1 TO NEXT POSITION
358 ROL DX,1 ;ROLL 0 TO NEXT POSITION
359 LOOP TR2M2 ;REPEAT FOR 16 BITS
360 jmp tr2m4 ;all 16 bits passed test ***jnw
361quit: ;***jnw
362;AT THIS POINT THERE ARE NO GOOD BITS SO END SEARCH FOR NEXT MB
363 POP DX ;RECOVER THESES REGISTERS
364 POP CX
365 POP BX
366 POP AX
367 JMP TR2M5 ;EXIT
368;AT THIS POINT WE KNOW THERE IS MEMORY IN THIS MEG THAT WAS JUST TESTED
369TR2M4:
370;***jnw ADD CS:MEM_INST,1 ;ADD 1 MB TO THIS FLAG
371;***jnw ADD CS:TOTAL_XMA_PAGES,1024/16 ;ADD 1 MB TO THIS FLAG
372;***jnw ADD CS:TOTAL_PAGES,1024/16 ;ADD 1 MB TO THIS FLAG
373;***jnw ADD CS:FREE_PAGES,1024/16 ;ADD 1 MB TO THIS FLAG
374 ADD CS:TOTAL_XMA_PAGES,1 ;Add 16k ***jnw
375 ADD CS:TOTAL_PAGES,1 ;Add 16k ***jnw
376 ADD CS:FREE_PAGES,1 ;Add 16k ***jnw
377 POP DX ;RECOVER THESE REGISTERS
378 POP CX
379 POP BX
380 POP AX
381;***jnw ADD DX,256 ;TRY NEXT MB
382 ADD DX,4 ;TRY NEXT 16k ***jnw
383 LOOP TR2M1A ;REPEAT LOOP
384TR2M5:
385;BEFORE NMI IS ENABLED, CLEAR PARITY CHECK LATCH ON XMA
386 MOV SI,0
387 MOV AX,[SI] ;READ 1ST WORD OF THIS SEG
388 MOV [SI],AX ;WRITE BACK SAME WORD
389 ;THE WRITE WILL CLEAR PCHK LTCH
390;PUT THE XMA CARD BACK INTO REAL MODE
391 MOV DX,MODE_REG ;READY FOR I/O TO MODE REG
392 IN AL,DX ;READ IT
393 AND AL,REAL_MODE ;TURN OFF VIRTUAL BIT
394 OUT DX,AL ;WRITE IT TO MODE REG
395;CLEAR I/O CHANNEL CHECK LATCHES AND ENABLE NMI
396 MOV AL,CS:MODEL ;GET SAVED MODEL BYTE
397 CMP AL,PC1 ;IS IT A PC1?
398 JE TR2M6 ;USE XT REGISTERS
399 CMP AL,PC_XT ;IS IT AN XT?
400 JE TR2M6 ;USE XT REGISTERS
401 CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS?
402 JE TR2M6 ;USE XT REGISTERS
403;IF NONE OF THE ABOVE THEN...
404;USE AT NMI REGISTER
405 MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG
406 IN AL,DX ;READ IT
407 OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
408 OUT DX,AL ;WRITE IT
409 AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
410 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
411 ;ENABLED
412 MOV DX,AT_NMI_REG ;AT's NMI REGISTER
413 MOV AL,AT_NMI_ON ;MASK ON NMI
414 OUT DX,AL ;OUTPUT IT
415;USE XT/AQUARIUS NMI REGISTER
416TR2M6:
417 MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG
418 IN AL,DX ;READ IT
419 OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
420 OUT DX,AL ;WRITE IT
421 AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
422 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
423 ;ENABLED
424 MOV DX,XT_NMI_REG ;XT's NMI REGISTER
425 MOV AL,XT_NMI_ON ;MASK ON NMI
426 OUT DX,AL ;OUTPUT IT
427;
428 RET ;RETURN TO CALLER
429
430TRY4MEG ENDP
431
432
433PAGE
434;-------------------------------------------------------------------------
435;-------------------------------------------------------------------------
436;
437; REGISTER TESTS
438;
439; DESCRIPTION : This routine will test the following subset
440; of XMA registers:
441; 31A0...8 bits
442; 31A1...4 bits
443; 31A6...4 bits
444; 31A7...4 bits (BIT 1 IS HELD LOW TO DISABLE
445; THE VIRTUAL MODE)
446;
447; The test is performed by writing and reading
448; AA, 55, FF, 00 from each of the above locations.
449;
450; NOTE: Regs 31A6 and 31A7 should always return 0 in
451; the high nibble.
452;
453; The remainding registers will be tested in
454; subsequent routines.
455;
456;
457; FUNCTION/ : To ensure integrity of XMA registers that will be used
458; PURPOSE in subsequent routines.
459;
460; ENTRY POINT : REGTST
461;
462; ENTRY : none
463; CONDITIONS
464;
465; EXIT : XMA registers are set to zero
466;
467; (zero flag) = 0 indicates an error
468; (DX) failing register
469; (AL) expected data XOR'ed with actual data
470;
471;-------------------------------------------------------------------------
472;
473REGTST PROC
474;
475 MOV AL,REG_TEST
476 MOV CS:TEST_ID,AL
477
478;SAVE CONTENTS OF MODE REG
479 MOV DX,MODE_REG
480 IN AL,DX
481 PUSH AX
482
483; TRANSLATE TABLE ADDRESS AND DATA REGISTERS
484;
485 MOV BX,0AA55H ;SET UP INITIAL DATA PATTERN
486 MOV AX,BX
487 MOV CX,BX
488
489R1:
490 MOV DX,BASE_REG ;FIRST REGISTER PAIR TO WRITE
491
492 OUT DX,AX ;WRITE PATTERN TO REGS
493 ADD DX,6 ;POINT TO NEXT REG PAIR
494 XCHG AL,AH ;SETUP INVERSE PATTERN
495 AND AH,11111101B ;MASK OFF BIT 1
496 OUT DX,AX ;BECAUSE AH -> 21B7
497R2:
498 SUB DX,6 ;POINT TO FIRST REGISTER PAIR
499 IN AX,DX ;READ REGISTER (21B1 -> AH)
500 XOR AX,BX ;DATA READ AS EXPECTED ?
501 AND AX,0FFFH ;MASK OFF UPPER NIBBLE OF 21B1
502 JNE R_ERROR ;MISMATCH - GO TO ERROR ROUTINE
503 XCHG BH,BL ;NEXT PATTERN TO TEST
504 AND BX,0F0FH ;REGS RETURN 0 IN HI NIBBLE
505 ADD DX,6 ;POINT TO NEXT REGISTER PAIR
506 IN AX,DX ;READ IT (21B7 -> AH)
507 XOR AX,BX ;DATA READ AS EXPECTED ?
508 AND AX,0DFFH ;MASK OFF BIT 1 IN REG 21B7
509 JNE R_ERROR ;MISMATCH - GO TO ERROR ROUTINE
510;
511 CMP CH,CL ;LAST PASS ?
512 JE R_EXIT ;YES - THEN EXIT REG TEST
513;
514 CMP CX,055AAH ;END OF AA55,55AA PATTERNS?
515 JNE R3 ;
516 MOV CX,000FFH ;SET UP NEXT VALUE TO WRITE
517 JMP R4
518R3:
519 CMP CX,00FFH ;END OF FF00,00FF PATTERNS?
520 JNE R4 ;
521 MOV CX,0 ;YES, THEN SET UP FOR LAST PASS
522R4:
523 XCHG CL,CH ;SET UP INVERSE PATTERN
524 MOV AX,CX ;SAVE IT
525 MOV BX,CX ;SAVE IT
526R5:
527 JMP R1 ;CONTINUE TILL ZERO PATTERN
528
529R_ERROR:
530R_EXIT:
531 POP AX
532 MOV DX,MODE_REG
533 OUT DX,AL ;restore mode reg
534 RET
535;
536REGTST ENDP
537
538
539
540
541PAGE
542;-------------------------------------------------------------------------
543;-------------------------------------------------------------------------
544;
545; MEMORY ARRAY TEST
546;
547; DESCRIPTION : This routine test all 1Meg (or 2Meg) of XMA memory
548; through a 64K window in PC space beginning at PF:0
549; (where PF is the Page Frame Segment)
550; This module looks at TOTAL_XMA_PAGES
551; to determine the memory size to be tested.
552;
553; (i) write the Translate Table for the 1st 64K block
554; of XMA memory to be mapped into PF:0 in PC space
555; (ii) test PF:0 to PF:FFFF
556; (iii) if good...write Translate Table to map next 64K block
557; into PF:0
558; (iv) repeat 'till all XMA memory is tested
559;
560; FUNCTION/ : See description
561; PURPOSE
562;
563;
564; ENTRY POINT : MEMARRAY
565;
566; ENTRY :
567; CONDITIONS
568;
569; EXIT : All SMAS memory is set to zero.
570;
571; (zero flag) = 0 if storage error
572; (AX) expected data XOR'ed with actual data
573; if AX = 0 and ZF = 0 then parity error
574; DS:SI point to failing location
575; CS:PAGE_UNDER_TEST point failing 64k block
576;
577; AX,BX,CX,DX,DS,ES,SI,DI ARE DESTROYED
578;
579;-------------------------------------------------------------------------
580
581MEMARRAY PROC
582
583 MOV AL,MEM_TEST
584 MOV CS:TEST_ID,AL
585
586;MEMORY TEST MUST RUN IN PAGE MODE
587
588 CALL VIRT2REAL
589
590;INDICATE 0 KB OK
591 MOV DX,(640-64)/4 ;CODE FOR 640 KB OK
592 CALL KB_OK
593;SETUP FOR TEST OF SMAS MEMORY ARRAY
594 MOV AX,CS:PAGE_FRAME_STA ;PAGE MEMORY FROM THIS SEGMENT
595 MOV ES,AX ;SET UP DEST SEG
596 MOV DS,AX ;SET UP SOURCE SEG
597 MOV BL,01H ;ENABLE THIS BLOCK OF MEMORY
598 MOV BH,0 ;USING ID 0
599 MOV DX,(640)/4 ;STARTING BLK IN SMAS ARRAY
600 ;DETERMINE HOW MUCH MEMORY TO TEST
601 MOV CX,CS:TOTAL_XMA_PAGES ;GET NUMBER OF 16K PAGES
602 SHR CX,1 ;CONVERT TO NUMBER
603 SHR CX,1 ; OF 64K SEGMENTS
604 SUB CX,640/64 ;SUBTRACT OFF 1ST 640K MEMORY
605;BEGIN TEST
606MA1:
607 MOV CS:PAGE_UNDER_TEST,DX ;INDICATE WHICH 64K BLOCK
608 PUSH AX ;IS UNDER TEST
609 PUSH BX
610 PUSH CX
611 PUSH DX ;SAVE ALL REGISTERS
612;
613 MOV CX,16 ;TEST 64K AT ONE TIME
614 ;16 x 4K = 64K
615 CALL SETXLAT ;SET UP XLAT TABLE
616 CALL STGTST ;TEST 64K OF STORAGE
617 JNZ MA2 ;WAS THERE AN ERROR
618 POP DX
619 POP CX
620 POP BX
621 POP AX ;RESTORE REGISTERS
622;
623 PUSHF ;SAVE FLAGS FOR ADDITION
624
625 CALL KB_OK ;INDICATE HOW MUCH
626 ;MEMORY HAS BEEN TESTED
627
628
629 ADD DX,16 ;POINT TO NEXT 64K BLOCK
630 POPF ;RESTORE FLAGS
631 LOOP MA1 ;LOOP FOR NEXT 64K
632 JMP MA3 ;EXIT WHEN COMPLETE
633MA2:
634 POP DX
635 POP CX
636 POP BX ;BX IS POPPED TWICE
637 POP BX ;TO RESTORE STACK WHILE
638 ;MAINTAINING AX
639MA3:
640 PUSH AX
641 PUSH DX
642 PUSHF ;SAVE THESE REGS...THEY CONTAIN
643 ;USEFULL ERROR INFO
644;PUT THE SMAS CARD INTO REAL MODE
645 MOV DX,MODE_REG ;READY FOR I/O TO MODE REG
646 IN AL,DX ;READ IT
647 AND AL,REAL_MODE ;TURN OFF VIRTUAL BIT
648 OUT DX,AL ;WRITE IT TO MODE REG
649 POPF
650 POP DX
651 POP AX ;RESTORE THESE REGS
652 RET
653;
654MEMARRAY ENDP
655
656
657
658
659PAGE
660;---------------------------------------------------------------------
661;---------------------------------------------------------------------
662; LO MEMORY TEST
663;
664; DESCRIPTION : This routine tests the first 256K or 512K
665; of XMA memory depending on the starting
666; position of the starting address jumper on
667; the card. The memory that is used to
668; fill conventional memory space is not tested
669; it is tested during POST and may now contain
670; parts of COMMAND.COM.
671;
672; FUNCTION/ : See description
673; PURPOSE
674;
675; ENTRY POINT : LOMEMTST
676;
677; ENTRY :
678; CONDITIONS
679;
680; EXIT : All tested memory is set to zero
681;
682; (zero flag) = 0 if storage error
683; (AX) = expected data XOR'ed with actual data
684; if (AX)=0 and ZF=0 then parity error
685; DS:SI point to failing location
686; CS:PAGE_UNDER_TEST point to failing 64K block
687;
688; AX,BX,CX,DX,DI,SI,ES,DS ARE DESTROYED
689;
690;-----------------------------------------------------------------------
691LOMEMTST PROC
692
693 MOV AL,LOMEM_TEST
694 MOV CS:TEST_ID,AL
695
696;MEMORY TEST MUST RUN IN PAGE MODE
697 CALL VIRT2REAL
698
699;INDICATE 0 KB OK AT START OF TEST
700 MOV DX,0FFF0H ;code for initial 0 kb
701 CALL KB_OK
702
703;DETERMINE HOW MUCH MEMORY TO TEST
704 MOV AX,CS:START_FILL ;get starting fill segment
705 XCHG AH,AL
706 MOV CL,4
707 SHR AX,CL ;convert to 64k block number
708 MOV CS:TESTABLE_SEGMENTS,AX ;save...this is number of 64k blocks
709 ;that can be tested without
710 ;destroying DOS
711;SET UP FOR TEST OF XMA MEMORY
712 MOV AX,CS:PAGE_FRAME_STA ;test through page frame
713 MOV DS,AX ;set up ds
714 MOV ES,AX ;and es
715 MOV BL,01H ;enable this block of memory
716 MOV BH,0 ;using id=0
717 XOR DX,DX ;start at block 0 in xma
718 MOV CX,640/64 ;loop counter is # 64k blocks in
719 ;conventional memory
720LM1:
721 MOV CS:PAGE_UNDER_TEST,DX ;save page under test
722 PUSH AX
723 PUSH BX
724 PUSH CX
725 PUSH DX ;save these registers
726
727 MOV CX,16 ;test 64k at one time
728 ;16 * 4k = 64k
729 CALL SETXLAT ;set translate table
730 CMP CS:TESTABLE_SEGMENTS,0 ;if this segment under test is used for
731 ;fill then read only
732 JG LM2 ;else do storage test
733 CALL READ_ONLY
734 JMP LM3
735LM2:
736 CALL STGTST
737LM3:
738 JNZ LM4 ;jump if there was an error
739 POP DX
740 POP CX
741 POP BX
742 POP AX ;recover registers
743
744 PUSHF ;save flags for addition
745 CALL KB_OK
746 ;indicate kb ok
747 ADD DX,16 ;next 64k block
748 DEC CS:TESTABLE_SEGMENTS ;dec testable pages
749 POPF ;recover flags
750 LOOP LM1 ;repeat for next 64k block
751 JMP LM5 ;exit when complete
752LM4:
753 POP DX ;recover these registers
754 POP CX
755 POP BX ;bx is popped twice to restore
756 POP BX ;satck while maintaining ax
757LM5:
758 PUSH AX ;save these ... they contain
759 PUSH DX ;useful error information
760 PUSHF
761;PUT CARD BACK TO REAL MODE
762 MOV DX,MODE_REG ;read mode reg
763 IN AL,DX
764 AND AL,REAL_MODE ;turn off virtual bit
765 OUT DX,AL ;write it to mode reg
766 POPF
767 POP DX
768 POP AX ;restore these registers
769 RET
770
771
772READ_ONLY PROC ;INTERNAL PROC TO READ MEMORY WITHOUT DESTROYING CONTENTS
773 XOR SI,SI ;start of segment
774 XOR CX,CX ;test 64k
775
776 LODSW ;just read each byte
777 XOR AX,AX ;and set zf=1 for return
778 RET ;back to caller
779READ_ONLY ENDP
780
781LOMEMTST ENDP
782
783
784
785PAGE
786;-------------------------------------------------------------------------
787;-------------------------------------------------------------------------
788;
789; PAGE TEST
790;
791; DESCRIPTION : This routine tests that the TASK ID register is
792; actually paging in unique segments of memory.
793; The test is performed through the page frame segment.
794; The test assumes that the memory test has already
795; completed successfully. The page test procedes as
796; follows:
797; (i) 6-64K blocks of XMA memory are mapped into a
798; 64K segment of PC space (the page frame)
799; These XMA blocks are from 640k to 1024k of XMA memory.
800; (ii) Each of these blocks is assigned to a unique
801; task ID ranging from 0 to 5.
802; (iii) For each task ID, the page frame is filled with
803; a pattern that is the same as the task ID.
804; (iv) The page frame is then read for each task ID
805; and compared with the expected data.
806;
807; FUNCTION/ :
808; PURPOSE
809;
810; ENTRY POINT : PAGETST
811;
812; ENTRY : NONE
813; CONDITIONS
814;
815; EXIT : (zero flag) = 0 indicates an error
816; (AL) expected data XOR'ed with actual data
817;
818; AX,BX,CX,DX,ES,DS,SI,DI ARE DESTROYED
819;-------------------------------------------------------------------------
820;
821PAGETST PROC
822;
823 MOV AL,PAGE_TEST
824 MOV CS:TEST_ID,AL
825;MEMORY TEST MUST RUN IN PAGE MODE
826 CALL VIRT2REAL
827;INITIALIZE TRANSLATE TABLE FOR THIS TEST
828 MOV AX,CS:PAGE_FRAME_STA ;SEMENT OF PAGE FRAME
829 MOV BL,01H ;ENABLE CODE
830 MOV BH,0 ;START WITH TASK ID = 0
831 MOV DX,640/4 ;START WITH XMA BLOCK 160
832 MOV CX,6 ;LOOP COUNT...6 TASK ID's
833 ;EACH TASK ID IS ASSIGNED 64K
834 ;FROM 640K TO 1024K
835PT1:
836 PUSH AX
837 PUSH BX
838 PUSH CX
839 PUSH DX ;SAVE ALL REGISTERS
840;
841 MOV CX,16 ;16-4K BLOCKS IN 64K
842 CALL SETXLAT ;SET TRANSLATE TABLE
843 POP DX
844 POP CX
845 POP BX
846 POP AX ;RECOVER ALL
847 INC BH ;POINT TO NEXT TASK ID
848 ADD DX,16 ;NEXT 64K IN XMA MEMORY
849 LOOP PT1 ;REPEAT FOR ALL TASK ID's
850;FILL MEMORY WITH A UNIQUE PATTERN FOR EACH TASK ID
851 MOV CX,6 ;6 TASK ID's
852 MOV DX,IDREG ;READY FOR I/O TO TASK ID REG
853 MOV AL,0 ;START WITH ID = 0
854PT2:
855 PUSH AX ;SAVE ID NUMBER
856 PUSH CX ;SAVE ID COUNT
857 OUT DX,AL ;SWITCH TASK ID
858 MOV BX,CS:PAGE_FRAME_STA
859 MOV ES,BX ;SEGMENT TO 1ST 64K 0F ID
860 SUB DI,DI ;POINT TO 1ST LOCATION
861 XOR CX,CX ;WRITE ALL 64K LOCATIONS
862PT2X:
863 STOSB
864 LOOP PT2X
865 POP CX ;RECOVER ID COUNT
866 POP AX ;RECOVER CURRENT ID
867 INC AL
868 LOOP PT2 ;REPEAT FOR ALL TASK ID's
869;NOW CHECK THAT THERE ARE 16 UNIQUE PATTERNS IN MEMORY
870 MOV CX,6 ;USE 6 TASK ID's
871 MOV AH,0 ;START WITH ID = 0
872PT3:
873 MOV AL,AH ;GET TASK ID IN AL
874 PUSH AX
875 PUSH CX ;SAVE ID COUNT
876 OUT DX,AL ;SWITCH TASK ID
877 MOV BX,CS:PAGE_FRAME_STA
878 MOV DS,BX
879 MOV ES,BX ;SEGMENT AT 1ST 64K
880 SUB DI,DI ;POINT TO 1ST LOCATION
881 SUB SI,SI ;POINT TO 1ST LOCATION
882 XOR CX,CX ;READ ALL 64K LOCATIONS
883PT3X:
884 LODSB
885 XOR AL,AH ;DATA AS EXPECTED ?
886 JNE PT4X ;NO - THEN EXIT
887 STOSB ;AL SHOULD CONTAIN 0...WRITE IT
888 LOOP PT3X
889
890 POP CX ;RECOVER ID COUNT
891 POP AX
892 INC AH ;NEXT TASK ID
893 LOOP PT3 ;REPEAT FOR ALL TASK ID's
894 XOR AL,AL ;IF WE GOT THIS FAR THEN
895 ;NO ERRORS...SET ZF TO
896 ;INDICATE SUCCESS
897PT4:
898 PUSH AX
899 PUSH DX
900 PUSHF ;SAVE THESE REGS...THEY CONTAIN
901 ;USEFULL ERROR INFO
902;PUT THE SMAS CARD INTO REAL MODE
903 MOV DX,MODE_REG ;READY FOR I/O TO MODE REG
904 IN AL,DX ;READ IT
905 AND AL,REAL_MODE ;TURN OFF VIRTUAL BIT
906 OUT DX,AL ;WRITE IT TO MODE REG
907;MAKE SURE WE EXIT WHILE IN TASK ID=0
908 MOV DX,IDREG
909 XOR AL,AL
910 OUT DX,AL
911
912 POPF
913 POP DX
914 POP AX ;RESTORE THESE REGS
915 RET ;RETURN TO CALLER
916PT4X:
917 POP CX ;ALTERNATE RETURN PATH
918 POP AX
919 JMP PT4 ;TO ADJUST STACK
920;
921PAGETST ENDP
922
923
924PAGE
925;-------------------------------------------------------------------------
926;-------------------------------------------------------------------------
927;
928; DMA CAPTURE TEST
929;
930; DESCRIPTION : This routine is a test of the DMA capture logic.
931; The test is as follows:
932; (i) A bit is rolled through the second entry in the
933; DMA cature register file. (The first entry is used
934; for refresh on a PC-XT).
935; (ii) A bit and address test is performed on the
936; remainder of the register file(s).
937; (iii) A test is made for the capture of both REQUEST and
938; MODE registers of the DMA controller.
939; (iv) DMA channel 0 is tested only on the PC-AT
940;
941;
942; FUNCTION/ : To verify the functionality of the DMA capture logic.
943; PURPOSE
944;
945; ENTRY POINT : CAPTST
946;
947; ENTRY : NONE
948; CONDITIONS
949;
950; EXIT : Each entry in the DMA capture register file is set to 0.
951;
952; (zero flag) = 0 indicates an error
953; '31A8'X points to failing DMA capture reg
954; (AL) expected data XOR'ed with actual data
955;
956; AX,BX,CX,DX,SI,DI ARE DESTROYED
957;-------------------------------------------------------------------------
958;
959;
960CAPTST PROC
961;
962 MOV AL,DMA_CAPTURE
963 MOV CS:TEST_ID,AL
964;
965;ROLL A BIT THROUGH THE SECOND ENTRY IN THE DMA CAPTURE REGISTER FILE
966;
967 MOV BL,01H ;SET UP INITIAL PATTERN
968 MOV BH,01H ;SET UP DMA CHANNEL 1
969 MOV DI,DMACAPT ;SAVE FOR I/O TO DMA CAPTURE REG
970 MOV SI,DMAREQ1 ;SAVE FOR I/O TO DMA CTRL 1 REQ REG
971 MOV CX,4 ;ROLL 4 BIT POSITIONS
972C1:
973 MOV DX,IDREG ;I/O TO ID REG
974 MOV AL,BL ;PATTERN TO WRITE
975 OUT DX,AX ;SETUP ID REG WITH DATA PATTERN
976 MOV DX,SI ;DMA CTRL 1
977 MOV AL,BH ;CHANNEL 1
978 OUT DX,AL ;SETUP DMA CH 1...CAPT ID IN 2nd ENTRY
979 MOV DX,DI ;DMA CAPTURE REG
980 OUT DX,AL ;POINT TO 2nd ENTRY
981 IN AL,DX ;READ IT
982 XOR AL,BL ;DATA READ AS EXPECTED ?
983 JNE CAPT_ERROR ;NO - THEN ERROR
984 SHL BL,1 ;SHIFT BIT TO NEXT POSITION
985 LOOP C1 ;REPEAT
986;
987 MOV DI,DMAREQ2 ;SETUP FOR I/O TO DMA CTRL 2 REQ REG
988 MOV AL,05H ;DATA PATTERN TO CAPTURE
989 CALL CAPT_FILL ;FILL CAPTURE REGS WITH VALUE
990;
991 MOV AH,05H ;SETUP INITIAL PATTERN
992 MOV BX,0F0AH ;OTHER PATTERNS TO USE
993C2:
994 CALL CAPT_RMW
995 JNZ CAPT_ERROR ;ERROR - THEN EXIT
996 CMP AH,BL ;ZERO PATTERN ?
997 JE CAPT_EXIT ;EXIT IF YES
998 MOV AH,BL ;SET UP
999 MOV BL,BH ; NEXT
1000 MOV BH,0 ; PATTERN
1001 JMP C2 ;REPEAT
1002
1003;NOW REPEAT TEST FOR CATPURE OF DMA MODE REGISTERS
1004 MOV SI,DMAMODE1 ;SETUP FOR I/O TO DMA CTRL 1 MODE REG
1005 MOV DI,DMAMODE2 ;SETUP FOR I/O TO DMA CTRL 2 MODE REG
1006 MOV AL,05H ;DATA PATTERN TO CAPTURE
1007 CALL CAPT_FILL ;FILL CAPTURE REGS WITH VALUE
1008;
1009 MOV AH,05H ;SETUP INITIAL PATTERN
1010 MOV BX,0F0AH ;OTHER PATTERNS TO USE
1011C3:
1012 CALL CAPT_RMW
1013 JNZ CAPT_ERROR ;ERROR - THEN EXIT
1014 CMP AH,BL ;ZERO PATTERN ?
1015 JE CAPT_EXIT ;EXIT IF YES
1016 MOV AH,BL ;SET UP
1017 MOV BL,BH ; NEXT
1018 MOV BH,0 ; PATTERN
1019 JMP C3 ;REPEAT
1020CAPT_ERROR:
1021CAPT_EXIT:
1022 RET
1023
1024CAPTST ENDP
1025
1026
1027
1028PAGE
1029
1030;-------------------------------------------------------------------------
1031;-------------------------------------------------------------------------
1032;
1033; FILL DMA CAPTURE REG
1034;
1035; DESCRIPTION : This routine will fill the entire DMA capture register
1036; file with the pattern that is passed in AL
1037;
1038; FUNCTION/ : See Description.
1039; PURPOSE
1040;
1041; ENTRY POINT : CAPT_FILL
1042;
1043; ENTRY : AL contains the value to be captured into
1044; CONDITIONS the register file.
1045; SI contains the address of DMA controller 1
1046; DI contains the address of DMA controller 2
1047;
1048; EXIT : Each entry in the DMA capture register file is set to
1049; the value specified in AL.
1050;-------------------------------------------------------------------------
1051;
1052CAPT_FILL PROC NEAR
1053;
1054 MOV DX,IDREG
1055 OUT DX,AL ;LOAD ID REG WITH PAT TO BE CAPTURED
1056 MOV DX,DI ;GET ADDRESS OF CTRL 2
1057 MOV CX,3 ;REP FOR CHANNELS 7,6,5
1058CF1:
1059 MOV AL,CL ;CL CONTAINS WHICH DMA CHANNEL
1060 OUT DX,AL ;SETUP & CAPTURE DMA CHANNEL
1061 LOOP CF1 ;REPEAT
1062;
1063 MOV DX,SI ;GET ADDRESS OF CTRL 1
1064 MOV CX,3 ;REP FOR CHANNELS 3,2,1
1065CF2:
1066 MOV AL,CL ;CL CONTAINS WHICH DMA CHANNEL
1067 OUT DX,AL ;SETUP & CAPTURE DMA CHANNEL
1068 LOOP CF2 ;REPEAT
1069 ;DO CHANNEL 0 IF NOT MODEL PC1, XT, AQUARIUS
1070 CMP CS:MODEL,PC1 ;IS THIS A PC1 ?
1071 JE CF3 ;YES - THEN EXIT ELSE TRY PC_XT
1072 CMP CS:MODEL,PC_XT ;IS THIS AN XT ?
1073 JE CF3 ;YES - THEN EXIT ELSE TRY AQUARIUS
1074 CMP CS:MODEL,XT_AQUARIUS ;IS THIS AN AQUARIUS?
1075 JE CF3 ;YES - THEN EXIT ELSE FILL CH 0 CAPT
1076 MOV AL,0 ;INDICATE CHANNEL 0
1077 OUT DX,AL ;SETUP & CAPTURE DMA CHANNEL
1078CF3:
1079 RET ;RETURN TO CALLER
1080;
1081CAPT_FILL ENDP
1082
1083
1084
1085
1086PAGE
1087;-------------------------------------------------------------------------
1088;-------------------------------------------------------------------------
1089;
1090; READ-MODIFY-WRITE DMA CAPTURE REG
1091;
1092; DESCRIPTION : This routine will read the a DMA capture register
1093; and if the correct value is found will cause a capture
1094; of a new value. The next DMA capture reg is read and
1095; the process repeated.
1096;
1097; FUNCTION/ : See Description.
1098; PURPOSE
1099;
1100; ENTRY POINT : CAPT_RMW
1101;
1102; ENTRY : AH contains the value to be compared
1103; CONDITIONS BL contains the new value to be written
1104; SI contains the address of DMA controller 1
1105; DI contains the address of DMA controller 2
1106;
1107; EXIT : Each entry in the DMA capture register file is set to
1108; the value specified in BL.
1109;
1110; AL,CX,DX,ARE DESTROYED
1111;-------------------------------------------------------------------------
1112;
1113CAPT_RMW PROC NEAR
1114;
1115 MOV CX,3 ;REP FOR CHANNELS 7,6,5
1116RMW1:
1117 MOV DX,DMACAPT ;I/O ADDRESS OF DMA CAPTURE REG
1118 MOV AL,CL ;GET LOW BYTE OF COUNT
1119 ADD AL,4 ;ADD 4 TO POINT TO DMA CAPTURE
1120 CALL RMW
1121 JNZ RMW4 ;EXIT IF ERROR
1122 LOOP RMW1 ;REPEAT FOR CHANNEL 6,5
1123;
1124 MOV CX,3 ;REP FOR CHANNELS 3,2,1
1125 PUSH DI ;SAVE DMA CTRL 2
1126 MOV DI,SI ;GET DMA CTRL 1 INTO DI FOR PROC RMW
1127RMW2:
1128 MOV DX,DMACAPT ;I/O ADDRESS OF DMA CAPTURE REG
1129 MOV AL,CL ;GET LOW BYTE OF COUNT
1130 CALL RMW
1131 JNZ RMW3 ;EXIT IF ERROR
1132 LOOP RMW2 ;REPEAT FOR DMA CHANNELS 2,1
1133 ;DO CHANNEL 0 IF NOT MODEL PC1, XT, AQUARIUS
1134 CMP CS:MODEL,PC1 ;IS THIS A PC1 ?
1135 JE RMW3 ;YES - THEN EXIT ELSE TEST FOR PC_XT
1136 CMP CS:MODEL,PC_XT ;IS THIS AN XT ?
1137 JE RMW3 ;YES - THEN EXIT ELSE TEST FOR AQUARIUS
1138 CMP CS:MODEL,XT_AQUARIUS ;IS THIS AN AQUARIUS?
1139 JE RMW3 ;YES - THEN EXIT ELSE TEST CH 0
1140 MOV DX,DMACAPT ;I/O ADDRESS OF DMA CAPTURE REG
1141 MOV CL,0 ;INDICATE CHANNEL 0
1142 MOV AL,CL ;ALSO INTO AL
1143 CALL RMW
1144RMW3:
1145 POP DI ;RESTORE DI (ADDR OF DMA CTRL 2)
1146RMW4:
1147 RET ;RETURN TO CALLER
1148;
1149CAPT_RMW ENDP
1150;
1151RMW PROC
1152;
1153 OUT DX,AL ;SETUP TO READ FROM DMA CAPTURE REG
1154 IN AL,DX ;READ IT
1155 XOR AL,AH ;DATA AS EXPECTED ?
1156 JNE RMW5 ;NO THEN EXIT
1157 ;DATA WAS GOOD---NOW GET NEXT PATTERN INTO THIS CAPTURE REG
1158 MOV DX,IDREG ;ADDRESS OF ID REG
1159 MOV AL,BL ;NEW PATTERN TO WRITE
1160 OUT DX,AL ;WRITE IT TO ID REG
1161 MOV DX,DI ;ADDRESS OF DMA CTRL 2
1162 MOV AL,CL ;DMA CHANNEL TO SET UP
1163 OUT DX,AL ;SET UP DMA---THIS CAUSES CAPTURE OF ID
1164RMW5:
1165 RET ;RETURN TO CALLER
1166;
1167RMW ENDP
1168
1169
1170
1171
1172PAGE
1173;-------------------------------------------------------------------------
1174;-------------------------------------------------------------------------
1175;
1176; INHIBIT A BLOCK OF MEMORY
1177;
1178; DESCRIPTION : This routine will set a block of SMAS memory with
1179; the code to enable or inhibit it. The user simply
1180; specifies the starting segment and length of the block in
1181; PC 'real' address space that is to be enabled/inhibited.
1182; The appropriate entries in the Translate Table are
1183; written so that this specified block in 'real' address
1184; is enabled or protected in all 16 possible TASK ID's.
1185;
1186;
1187; FUNCTION/ : To enable or inhibit SMAS memory in specified areas of
1188; PURPOSE PC 'real'address space (ie.,diplay buffer, BIOS,
1189; distributed ROS...)
1190;
1191; ENTRY POINT : INHIBLK
1192;
1193; ENTRY : (AX) starting segment in PC address space to be
1194; CONDITIONS protected/enabled. Must be on 4K boundary else
1195; this routine will round UP to next 4K block.
1196;
1197; (CX) number of 4K blocks to be protected
1198;
1199; (BL) 01 = ENABLE
1200; 00 = INHIBIT
1201;
1202; EXIT : specified entries in Translate Table are enabled or
1203; inhibited for all posible task ID's.
1204;
1205; AX,BH,CX,DX ARE DESTROYED
1206;-------------------------------------------------------------------------
1207;
1208INHIBLK PROC
1209;
1210 ;ADJUST SI FOR TRANSLATE TABLE ENTRY
1211 XCHG AL,AH ;ROTATE RIGHT BY 8
1212 XOR AH,AH ;CLEAR AH
1213 ;AX IS NOW ADJUSTED FOR ENTRY INTO
1214 ;XLAT TABLE FOR TASK ID=0
1215 PUSH AX ;SAVE IT
1216 PUSH CX ;SAVE COUNT OF 4K BLOCKS
1217;
1218 MOV SI,TTDATA ;ADDRESS OF TT DATA REG
1219 MOV DI,AIDATA ;ADDRESS OF TT DATA WITH AUTO INC
1220 XOR BH,BH ;BH IS TASK ID
1221INH1:
1222 MOV DX,TTPOINTER ;ADDRESS OF TT POINTER
1223 POP CX ;RESTORE COUNT
1224 POP AX ;RESTORE TT ENTRY
1225 PUSH AX ;SAVE BOTH
1226 PUSH CX ; OF THEM
1227 MOV AH,BH ;APPEND TASK ID TO TT POINTER
1228 OUT DX,AX ;SET TT POINTER TO STARTING ENTRY
1229INH2:
1230 MOV DX,SI ;TT DATA REG
1231 IN AX,DX ;READ CURRENT ENTRY
1232 MOV DX,DI ;ADDRESS OF TT DATA WITH AUTO INC
1233 ;DETERMINE IF ENABLE OR INHIBIT BLOCK
1234 CMP BL,ENABLE ;WANT TO ENABLE THIS BLOCK ?
1235 JNE INH3 ;NO - THEN DISABLE IT
1236 AND AH,BLK_ON ;MASK OFF INHIBIT BIT
1237 JMP INH4
1238INH3:
1239 OR AH,BLK_OFF ;MASK ON INHIBIT BIT
1240INH4:
1241 OUT DX,AX ;WRITE IT THEN INC TO NEXT TT ENTRY
1242 LOOP INH2 ;REPEAT FOR EACH BLOCK OF 4K
1243 INC BH ;NEXT TASK ID
1244 CMP BH,MAX_TASK_ID ;COMPLETED FOR ALL TASK ID's ?
1245 JBE INH1 ;NO - THEN LOOP TILL DONE
1246INHIBLK_EXIT:
1247 POP CX
1248 POP AX
1249 RET
1250;
1251INHIBLK ENDP
1252
1253
1254
1255
1256PAGE
1257;-------------------------------------------------------------------------
1258;-------------------------------------------------------------------------
1259;
1260; STORAGE TEST
1261;
1262; DESCRIPTION : This routine performs a bit and address test on a
1263; 64K block of storage.
1264;
1265; (i) 55AA is written to each location.
1266; (ii) 55AA is read back
1267; (iii) if good, write AA55 and point to next location
1268; (iv) repeat step (iii) for all 64K locations
1269; (v) repeat steps (ii) to (iv) for AA55, FF00, 0101, 0000
1270; (vi) check parity bits
1271;
1272;
1273; FUNCTION/ : See description
1274; PURPOSE
1275;
1276; ENTRY POINT : STGTST
1277;
1278; ENTRY : (ES) storage segment to be tested
1279; CONDITIONS (DS) storage segment to be tested
1280;
1281; EXIT : (zero flag) = 0 if storage error
1282; (AX) expected data XOR'ed with actual data
1283; if ax = 0 and zf = 0 then parity error
1284; DS:SI point to failing location
1285;
1286; AX,BX,CX,DX,DI,SI ARE DESTROYED
1287;
1288;-------------------------------------------------------------------------
1289;
1290STGTST PROC
1291;
1292 CMP CS:WARM_START,'Y' ;is this a warm start?
1293 JNE STG1A ;if no then do mem test
1294 CALL CLEAR_MEM ;if yes then just clear memory
1295 XOR AX,AX ;set zero flag
1296 JMP STG6 ;exit
1297
1298
1299 ;DISABLE NMI AND ENABLE I/O CHANNEL CHECK
1300STG1A:
1301 MOV AL,CS:MODEL ;GET SAVED MODEL BYTE
1302 CMP AL,PC1 ;IS IT A PC1?
1303 JE STG1 ;IF NO THEN TRY FOR PC_XT
1304 CMP AL,PC_XT ;IS IT AN XT?
1305 JE STG1 ;IF NO THEN TRY FOR AQUARIUS
1306 CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS?
1307 JE STG1 ;IF NO THEN USE AT NMI REGS
1308 ;USE PC-AT NMI REGISTER
1309 MOV DX,AT_NMI_REG ;AT's NMI REGISTER
1310 MOV AL,AT_NMI_OFF ;MASK OFF NMI
1311 OUT DX,AL ;OUTPUT IT
1312 MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG
1313 IN AL,DX ;READ IT
1314 OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
1315 OUT DX,AL ;WRITE IT
1316 AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
1317 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
1318 ;ENABLED
1319 ;USE PC1, XT, AQUARIUS REGISTERS
1320STG1:
1321 MOV DX,XT_NMI_REG ;XT's NMI REGISTER
1322 MOV AL,XT_NMI_OFF ;MASK OFF NMI
1323 OUT DX,AL ;OUTPUT IT
1324 MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG
1325 IN AL,DX ;READ IT
1326 OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
1327 OUT DX,AL ;WRITE IT
1328 AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
1329 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
1330 ;ENABLED
1331
1332
1333
1334 ;ROLL A BIT THROUGH THE FIRST WORD
1335 SUB DI,DI ;FIRST LOCATION
1336 MOV CX,16 ;ROLL 16 BITS
1337 MOV AX,0001H ;FIRST PATTERN TO WRITE
1338 MOV BX,AX ;SAVE IT
1339STG2:
1340 MOV [DI],AX ;WRITE PATTERN
1341 MOV [DI+2],0FFFFH ;CHARGE BUS
1342 MOV AX,[DI] ;READ PATTERN
1343 XOR AX,BX ;IS IT CORRECT ?
1344 JNE STG_EXIT ;IF NO - THEN EXIT
1345 SHL BX,1 ;SHIFT BIT
1346 MOV AX,BX ;GET IT INTO AX
1347 LOOP STG2 ;REPEAT
1348;
1349 CLD ;FILL FORWARD
1350 SUB DI,DI ;POINT TO FIRST LOCATION
1351 MOV CX,8000H ;32K WORDS
1352 MOV AX,55AAH ;INITIAL PATTERN TO WRITE
1353 REP STOSW ;FILL ENTIRE SEGMENT
1354;
1355 MOV BX,55AAH ;PATTERN TO LOOK FOR
1356 MOV DX,0AA55H ;NEXT PATTERN TO WRITE
1357 CALL STG_CNT
1358 JNZ STG_EXIT ;EXIT IF ERROR
1359;
1360 MOV BX,0AA55H ;PATTERN TO LOOK FOR
1361 MOV DX,0101H ;NEXT PATTERN TO WRITE
1362 CALL STG_CNT
1363 JNZ STG_EXIT ;EXIT IF ERROR
1364;
1365 MOV BX,0101H ;PATTERN TO LOOK FOR
1366 MOV DX,0000H ;NEXT PATTERN TO WRITE
1367 CALL STG_CNT
1368 JNZ STG_EXIT ;EXIT IF ERROR
1369;
1370; MOV BX,0000H ;PATTERN TO LOOK FOR
1371; MOV DX,0000H ;NEXT PATTERN TO WRITE
1372; CALL STG_CNT
1373; JNZ STG_EXIT ;EXIT IF ERROR
1374;
1375 ;IF TEST REACHES THIS POINT THEN MEMORY IS GOOD
1376 ;NEED TO CHECK PARITY BITS...IF PARITY ERROR EXISTS THEN
1377 ;CAN ASSUME BAD PARITY BIT OR BAD PARITY GENERATOR
1378;
1379 MOV AL,CS:MODEL ;GET SAVED MODEL BYTE
1380 CMP AL,PC1 ;IS IT A PC1?
1381 JE STG3 ;USE XT REGISTERS
1382 CMP AL,PC_XT ;IS IT AN XT?
1383 JE STG3 ;USE XT REGISTERS
1384 CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS?
1385 JE STG3 ;USE XT REGISTERS
1386 ;IF NONE OF THE ABOVE THEN...
1387 ;USE AT NMI REGISTER
1388 MOV DX,AT_CHCHK_REG ;AT's I/O CH CHK REG
1389 IN AL,DX ;READ IT
1390 AND AL,AT_CHCHK ;IS CH CHK BIT ON ?
1391 JZ STG4 ;IF NO - THEN EXIT
1392 MOV AX,0 ;ELSE - CLEAR AX TO INDICATE
1393 ;PARITY ERROR
1394 JMP STG4 ;EXIT
1395 ;USE XT/AQUARIUS NMI REGISTER
1396STG3:
1397 MOV DX,XT_CHCHK_REG ;XT's I/O CH CHK REG
1398 IN AL,DX ;READ IT
1399 AND AL,XT_CHCHK ;IS CH CHK BIT ON ?
1400 JZ STG4 ;IF NO - THEN EXIT
1401 MOV AX,0 ;ELSE - CLEAR AX TO INDICATE
1402 ;PARITY ERROR
1403STG4:
1404STG_EXIT:
1405 PUSH AX ;SAVE THESE REGS
1406 PUSH DX ;THEY CONTAIN
1407 PUSH SI
1408 PUSHF ;USEFUL ERROR INFORMATION
1409 ;BEFORE NMI IS ENABLED, CLEAR PARITY CHECK LATCH ON XMA
1410 MOV SI,0
1411 MOV AX,[SI] ;READ 1ST WORD OF THIS SEG
1412 MOV [SI],AX ;WRITE BACK SAME WORD
1413 ;THE WRITE WILL CLEAR PCHK LTCH
1414 ;CLEAR I/O CHANNEL CHECK LATCHES AND ENABLE NMI
1415 MOV AL,CS:MODEL ;GET SAVED MODEL BYTE
1416 CMP AL,PC1 ;IS IT A PC1?
1417 JE STG5 ;USE XT REGISTERS
1418 CMP AL,PC_XT ;IS IT AN XT?
1419 JE STG5 ;USE XT REGISTERS
1420 CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS?
1421 JE STG5 ;USE XT REGISTERS
1422 ;IF NONE OF THE ABOVE THEN...
1423 ;USE AT NMI REGISTER
1424 MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG
1425 IN AL,DX ;READ IT
1426 OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
1427 OUT DX,AL ;WRITE IT
1428 AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
1429 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
1430 ;ENABLED
1431 MOV DX,AT_NMI_REG ;AT's NMI REGISTER
1432 MOV AL,AT_NMI_ON ;MASK ON NMI
1433 OUT DX,AL ;OUTPUT IT
1434 ;USE XT/AQUARIUS NMI REGISTER
1435STG5:
1436 MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG
1437 IN AL,DX ;READ IT
1438 OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
1439 OUT DX,AL ;WRITE IT
1440 AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
1441 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
1442 ;ENABLED
1443 MOV DX,XT_NMI_REG ;XT's NMI REGISTER
1444 MOV AL,XT_NMI_ON ;MASK ON NMI
1445 OUT DX,AL ;OUTPUT IT
1446;
1447 POPF
1448 POP SI
1449 POP DX
1450 POP AX ;RESTORE REGS
1451STG6:
1452 RET ;RETURN TO CALLER
1453
1454
1455
1456CLEAR_MEM PROC ;INTERNAL PROC TO CLEAR MEMORY
1457 XOR DI,DI ;start of segment
1458 XOR CX,CX ;clear entire segment
1459 XOR AX,AX ;write zeroes
1460
1461 STOSB ;just write
1462 RET ;back to caller
1463CLEAR_MEM ENDP
1464
1465
1466STGTST ENDP
1467
1468
1469PAGE
1470;-------------------------------------------------------------------------
1471;-------------------------------------------------------------------------
1472;
1473; STORAGE TEST SUBROUTINE
1474;
1475; DESCRIPTION : This routine performs a bit and address test on a
1476; 64K block of storage.
1477;
1478; (i) a word is read and compared against the value in (BX)
1479; (ii) if good the value in (DX) is written into that location
1480; (iii) point to next location and repeat steps (i) to (ii)
1481;
1482;
1483; FUNCTION/ : See description
1484; PURPOSE
1485;
1486; ENTRY POINT : STG_CNT
1487;
1488; ENTRY : (ES) storage segment to be tested
1489; CONDITIONS (DS) storage segment to be tested
1490; (BX) value to be compared
1491; (DX) new value to be written
1492;
1493; EXIT : (zero flag) = 0 if storage error
1494; (AX) expected data XOR'ed with actual data
1495; if ax = 0 and zf = 0 then parity error
1496; DS:SI point to failing location
1497;-------------------------------------------------------------------------
1498;
1499STG_CNT PROC
1500;
1501 MOV CX,8000H ;32K WORDS
1502 SUB DI,DI ;FIRST LOCATION
1503 MOV SI,DI ;FIRST LOCATION
1504SC1:
1505 LODSW ;READ OLD WORD FROM STORAGE
1506 XOR AX,BX ;DATA AS EXPECTED ?
1507 JNE SC2 ;IF NO - THEN EXIT
1508 MOV AX,DX ;GET NEW PATTERN
1509 STOSW ;WRITE IT
1510 LOOP SC1 ;REPEAT
1511SC2:
1512 RET
1513
1514STG_CNT ENDP
1515
1516
1517
1518
1519PAGE
1520;-------------------------------------------------------------------------
1521;-------------------------------------------------------------------------
1522;
1523; PRINT MEMORY GOOD
1524;
1525; DESCRIPTION : This routine will print to the screen how much memory
1526; has been tested.
1527;
1528; The format will be: xxxx KB TESTED
1529;
1530; FUNCTION/ : See description
1531; PURPOSE
1532;
1533;
1534; ENTRY POINT : KB_OK
1535;
1536; ENTRY : (DX) = 1/4 OF GOOD MEMORY + 64K IN KB
1537; CONDITIONS ex: if (DX) = 16 then
1538; (16 * 4) + 64 = 128KB is OK
1539;
1540; NOTE: if (DX) = FFF0 then 0 KB is OK
1541;
1542;
1543; EXIT : Message is displayed
1544;
1545; All registers are preserved
1546;
1547;-------------------------------------------------------------------------
1548;
1549KB_OK PROC
1550;
1551 PUSH AX
1552 PUSH BX
1553 PUSH CX
1554 PUSH DX
1555 PUSH SI
1556 PUSH DI
1557 PUSH DS ;SAVE REGISTERS
1558;
1559 PUSH CS
1560 POP DS ;GET DS TO THIS CODE SEGMENT
1561 ;CONVERT DX TO KILO BYTES
1562 SHL DX,1
1563 SHL DX,1 ;MULTIPLY BY 4
1564 ADD DX,64 ;ADJUST BY 64
1565;
1566 MOV AX,DX ;GET NUMBER INTO AX
1567 MOV BX,10 ;READY FOR DECIMAL CONVERT
1568 MOV CX,4 ;OF 4 DIGITS
1569K1:
1570 XOR DX,DX ;CLEAR HI WORD OF DIVIDEND
1571 ;AX IS LOW WORD OF DIVIDEND
1572 DIV BX ;DIVIDE BY 10
1573 OR DL,30H ;MAKE MODULO INTO ASCII
1574 PUSH DX ;SAVE IT
1575 LOOP K1 ;REPEAT FOR ALL DIGITS
1576;
1577 XOR SI,SI ;CLEAR SI
1578 MOV CX,4
1579K2:
1580 POP AX ;ASCII DIGIT GOES INTO AL
1581 MOV BX,OFFSET MEM_OK
1582 MOV CS:[BX+SI],AL ;BUILD ASCII MESSAGE
1583 INC SI
1584 LOOP K2
1585 ;MOVE THE CURSOR AND PRINT MESSAGE
1586 MOV DX,CUR_SAVE
1587 MOV BH,ACTIVE_PAGE
1588 MOV AH,2 ;SET CURSOR
1589IF DOS
1590 INT 10H ;BIOS VIDEO CALL SET CURSOR
1591 MOV AH,9 ;DOS PRINT STRING
1592 MOV DX,OFFSET SIZE_MSG1 + 1 ;OFFSET OF MEM_OK MSG
1593 INT 21H ;DISPLAY MESSAGE
1594ELSE
1595 INT 85H ;SET CURSOR POSITION
1596
1597 MOV BX,OFFSET SIZE_MSG1 ;GET OFFSET OF MEM_OK MSG
1598 MOV AX,0905H ;MAGENTA MESSAGE
1599 INT 82H ;DISPLAY MESSAGE
1600ENDIF
1601
1602 POP DS
1603 POP DI
1604 POP SI
1605 POP DX
1606 POP CX
1607 POP BX
1608 POP AX ;RESTORE ALL REGISTERS
1609
1610 RET ;RETURN TO CALLER
1611
1612KB_OK ENDP
1613
1614
1615PAGE
1616;--------------------------------------------------------------------
1617;--------------------------------------------------------------------
1618; GET MODEL BYTE
1619;
1620GETMOD PROC
1621;GET COPY OF MODEL BYTE INTO THIS SEGMENT
1622;
1623 PUSH DS ;SAVE DS
1624 LDS SI,ADDR_MODEL_BYTE
1625 MOV AL,[SI] ;GET IT INTO AL
1626 MOV CS:MODEL,AL ;SAVE IT IN THIS SEGMENT
1627 POP DS ;RESTORE DS
1628 RET
1629;
1630GETMOD ENDP
1631
1632
1633
1634
1635PAGE
1636;-------------------------------------------------------------------------
1637;-------------------------------------------------------------------------
1638;
1639; SET TRANSLATE TABLE
1640;
1641; DESCRIPTION : This routine will write the Translate Table so that
1642; a specified block of PC 'real' address will be mapped
1643; to a specified block of SMAS physycal memory. Note that
1644; this routine will map only into CONTIGUOUS blocks of
1645; SMAS memory. PC memory is referenced by segments
1646; (must be on 4K boundaries) while SMAS memory is referenced
1647; by block number (each block is 4K).
1648;
1649; EXAMPLE: segment 4000 can be mapped to block 5
1650; segment 4100 can be mapped to block 6
1651;
1652; FUNCTION/ : To map PC 'real' addresses into SMAS physical memory.
1653; PURPOSE
1654;
1655;
1656; ENTRY POINT : SETXLAT
1657;
1658; ENTRY : (AX) starting segment in PC address space to be
1659; CONDITIONS mapped. Must be on 4K boundary else
1660; this routine will round UP to next 4K block.
1661;
1662; (CX) number of 4K blocks translated.
1663;
1664; (BH) task ID for this memory allocation
1665;
1666; (BL) 01 = ENABLE
1667; 00 = INHIBIT
1668;
1669; (DX) starting block number in SMAS memory
1670;
1671;
1672; EXIT : specified entries in Translate Table are enabled or
1673; inhibited for all posible task ID's.
1674;
1675;
1676; AX,CX,DX ARE DESTROYED
1677;
1678;-------------------------------------------------------------------------
1679;
1680SETXLAT PROC
1681;
1682 ;ADJUST AX FOR TRANSLATE TABLE ENTRY
1683 XCHG AL,AH ;ROTATE RIGHT BY 8
1684 MOV AH,BH ;TASK ID INTO BH
1685 ;AX IS NOW ADJUSTED FOR ENTRY INTO
1686 ;XLAT TABLE FOR TASK ID=(BH)
1687 PUSH DX ;SAVE STARTING SMAS BLOCK NUMBER
1688;
1689 MOV DX,TTPOINTER ;ADDRESS OF TT POINTER
1690 OUT DX,AX ;SET TT POINTER TO STARTING ENTRY
1691 POP AX ;GET STARTING BLOCK NUMBER INTO AX
1692;
1693 MOV DX,AIDATA ;TT DATA REG WITH AUTO INC
1694 ;DETERMINE IF ENABLE OR INHIBIT BLOCK
1695 CMP BL,ENABLE ;WANT TO ENABLE THIS BLOCK ?
1696 JE SETX1 ;YES - THEN SKIP THE DISABLE STEP
1697 OR AH,BLK_OFF ;MASK ON INHIBIT BIT
1698SETX1:
1699 OUT DX,AX ;WRITE IT THEN INC TO NEXT TT ENTRY
1700 INC AX ;NEXT BLOCK OF SMAS MEMORY
1701 LOOP SETX1 ;REPEAT FOR EACH BLOCK OF 4K
1702SETXLAT_EXIT:
1703 RET
1704;
1705SETXLAT ENDP
1706
1707 PAGE
1708;-------------------------------------------------------------------------
1709;-------------------------------------------------------------------------
1710;
1711; AUTO-INCREMENT TEST
1712;
1713; DESCRIPTION : This routine will test the auto-increment of
1714; the Translate Table pointer. The test will procede
1715; in the following manner:
1716; (i) A basic check of the TT pointer reg is performed
1717; (ii) The TT pointer is initialized to '00'H
1718; (iii) The auto increment data reg is written
1719; (iv) The TT pointer is read and checked for increment
1720; (v) Repeat until TT pointer wraps from 'FFF'H to '000'H
1721; (vi) Repeat test for auto-increment for read of data reg
1722;
1723; FUNCTION/ : To ensure that the Translate Table pointer can auto
1724; PURPOSE increment when 31A5 is written or read.
1725;
1726; ENTRY POINT : INCTST
1727;
1728; ENTRY : NONE
1729; CONDITIONS
1730;
1731; EXIT :
1732; (zero flag) = 0 indicates an error
1733; (DX) failing register (ie.,TT pointer reg)
1734; (AX) expected data XOR'ed with actual data
1735;-------------------------------------------------------------------------
1736;
1737;
1738INCTST PROC
1739;
1740 MOV AL,AUTO_INC
1741 MOV CS:TEST_ID,AL
1742;
1743;PERFORM SIMPLE TEST OF TTPOINTER REG
1744;
1745 MOV BX,0AA55H ;SET UP PATTERN TO WRITE
1746 MOV AX,BX
1747 MOV DX,TTPOINTER ;I/O TO TTPOINTER REG
1748 MOV SI,TTDATA ;SAVE FOR I/O TO TTDATA
1749 OUT DX,AX ;WRITE THE REGISTER
1750 XCHG DX,SI ;I/O TO TTDATA REG
1751 XCHG AH,AL ;INVERSE PATTERN
1752 OUT DX,AX ;CHARGE BUS WITH OPPOSITE PATTERN
1753 XCHG DX,SI ;I/O TO TTPOINTER REG
1754 IN AX,DX ;READ TTPOINTER REG
1755 XOR AX,BX ;READ AS EXPECTED
1756 AND AX,0FFFH ;MASK OFF HI NIBBLE (INVALID)
1757 JNE INC_ERROR ;NO - THEN EXIT
1758;
1759;CONTINUE WITH AUTO-INC TEST
1760;
1761 MOV DI,2 ;2 PASSES...1 WRITE , 1 READ
1762AI1:
1763 MOV SI,AIDATA ;SAVE FOR I/O TO TTDATA WITH AUTO-INC
1764AI2:
1765 MOV CX,1000H ;TTPOINTER RANGE 0 -> FFF
1766 MOV BX,0001H ;INITIAL COMPARE VALUE
1767 MOV AX,0 ;SET TTPONTER TO ZERO
1768 OUT DX,AX ;TTPOINTER IS INITIALIZED TO ZERO
1769AI2X:
1770 XCHG DX,SI ;I/O TO TTDATA WITH AUTO-INC
1771;
1772;DETERMINE IF WRITE OR READ TEST
1773;
1774 CMP DI,2 ;DOING A AUTO-INC WRITE TEST ?
1775 JNE AI3 ;NO - THEN MUST BE AUTO-INC READ TEST
1776 OUT DX,AX ;WRITE TO AUTO-INC DATA REG
1777 JMP AI4 ;CONTINUE WITH TEST
1778AI3:
1779 IN AX,DX ;READ FROM AUTO-INC DATA REG
1780AI4:
1781 XCHG DX,SI ;I/O TO TTPOINTER REG
1782 IN AX,DX ;READ TTPOINTER (31A1 -> AH)
1783 XOR AX,BX ;DATA AS EXPECTED ?
1784 AND AX,0FFFH ;MASK OFF UPPER NIBBLE (INVALID)
1785 JNE INC_ERROR ;NO - GO TO ERROR
1786 INC BX ;NEXT VALUE TO LOOK FOR
1787 LOOP AI2X ;CONTINUE TIL ALL VALUES ARE TESTED
1788;
1789 DEC DI
1790 CMP DI,0 ;COMPLETE WITH WRITE AND READ TEST ?
1791 JE INC_EXIT ;YES - THEN EXIT
1792 JMP AI1 ;NO - THEN CONTINUE WITH READ TEST
1793;
1794INC_ERROR:
1795INC_EXIT: RET
1796;
1797INCTST ENDP
1798
1799PAGE
1800;-------------------------------------------------------------------------
1801;-------------------------------------------------------------------------
1802;
1803; TRANSLATE TABLE TEST
1804;
1805; DESCRIPTION : This routine performs a write/read storage test
1806; on the Translate Table. The test is as follows:
1807; (i) A bit is rolled through the first word of the TT
1808; (ii) A bit and address test is performed on the
1809; remainder of the TT.
1810;
1811; FUNCTION/ : To verify the integrity of the Translate Table.
1812; PURPOSE
1813;
1814; ENTRY POINT : XLATST
1815;
1816; ENTRY : NONE
1817; CONDITIONS
1818;
1819; EXIT : Entire Translate Table is left with FFF (passover code)
1820;
1821; (zero flag) = 0 indicates an error
1822; (DX) failing register (TT data register)
1823; (AX) expected data XOR'ed with actual data
1824; (31A0) address in TT of failure
1825;-------------------------------------------------------------------------
1826;
1827XLATST PROC
1828;
1829 MOV AL,XLAT_TABLE_TEST
1830 MOV CS:TEST_ID,AL
1831;
1832;ROLL A BIT THROUGH THE FIRST BYTE
1833;
1834 MOV BX,0001H ;SET UP INITIAL PATTERN
1835 MOV SI,TTDATA ;SAVE FOR I/O TO DATA REG
1836 MOV DX,TTPOINTER ;I/O TO TTPOINTER REG
1837 MOV CX,12 ;ROLL 12 BIT POSITIONS
1838 XOR AX,AX ;CLEAR AX (WRITE TO 1st TT LOCATION)
1839 OUT DX,AX ;SET TT POINTER
1840 XCHG DX,SI ;READY FOR I/O TO TTDATA REG
1841X1:
1842 MOV AX,BX ;GET BIT PATTERN
1843 OUT DX,AX ;WRITE BIT PATTERN TO TT
1844 XCHG DX,SI ;READY FOR I/O TO TTPOINTER REG
1845 XOR AX,AX ;CLEAR AX
1846 OUT DX,AX ;CHARGE BUS WITH 0000 PATTERN
1847 XCHG DX,SI ;READY FOR I/O TO TTDATA REG
1848 IN AX,DX ;READ TT (31A1 -> AH)
1849 XOR AX,BX ;DATA READ AS EXPECTED ?
1850 AND AX,0FFFH ;MASK OFF UPPER NIBBLE (INVALID)
1851 JNE XLA_ERROR ;NO - THEN EXIT
1852 SHL BX,1 ;SHIFT BIT TO NEXT POSITION
1853 LOOP X1
1854;
1855;CONTINUE REMAINDER OF TRANSLATE TABLE
1856;
1857 MOV DX,AIDATA
1858;
1859 XCHG DX,SI ;READY FOR I/O TO TTPOINTER
1860 XOR AX,AX ;CLEAR AX
1861 OUT DX,AX ;TTPOINTER AT 1st LOCATION
1862;
1863 XCHG DX,SI ;READY FOR I/O TO TT DATA W/AUTO-INC
1864 MOV AX,0AA55H ;INITIAL DATA PATTERN
1865 MOV CX,TABLEN ;NUMBER OF TT ENTRIES
1866X2:
1867 OUT DX,AX ;SETUP INVERSE PATTERN
1868 LOOP X2 ;FILL ENTIRE XLATE TABLE
1869;
1870 MOV SI,TTDATA ;ADDRESS OF TTDATA WITHOUT INC.
1871 MOV BX,AX ;SAVE VALUE FOR COMPARE
1872 MOV DI,055AAH ;NEXT PATTERN TO WRITE
1873X3:
1874 MOV CX,TABLEN ;NUMBER OF TT ENTRIES
1875X4:
1876 XCHG DX,SI ;GET IT INTO DX...SI GETS AUTO-INC
1877 IN AX,DX ;READ TABLE ENTRY (HI BYTE -> AH)
1878 XOR AX,BX ;DATA READ AS EXPECTED ?
1879 AND AX,0FFFH ;MASK OFF HI NIBBLE (INVALID)
1880 JNE XLA_ERROR ;NO - THE EXIT
1881 XCHG DX,SI ;GET TTDATA WITH AUTO-INC
1882 MOV AX,DI ;RECOVER NEXT PATTERN TO WRITE
1883 OUT DX,AX ;WRITE IT THEN INCREMENT
1884 LOOP X4 ;REPEAT TILL TABLE FILLED
1885
1886
1887;
1888 CMP DI,0FFFFH ;LAST PASS ?
1889 JE XLA_EXIT ;YES - THEN EXIT REG TEST
1890;
1891 XCHG BX,DI ;BX GETS NEXT PATTERN TO TEST
1892;
1893 CMP BX,055AAH ;LAST PASS FOR AA55,55AA PATTERN?
1894 JNE X5 ;NO
1895 MOV DI,0FF00H ;YES- PREPARE TO WRITE NEW PATTERN
1896 JMP X3 ;DO IT
1897X5:
1898 CMP BX,0FF00H ;READY TO READ 0FF00 PATTERN
1899 JNE X6 ;NO
1900 MOV DI,00FFH ;YES- PREPARE TO WRITE NEW PATTERN
1901 JMP X3 ;DO IT
1902X6:
1903 MOV DI,0FFFFH ;PREPARE TO SET ALL OF TT INACTIVE
1904 JMP X3 ;DO IT
1905;
1906XLA_ERROR:
1907XLA_EXIT: RET
1908;
1909XLATST ENDP
diff --git a/v4.0/src/DEV/XMA2EMS/EMSINIT.INC b/v4.0/src/DEV/XMA2EMS/EMSINIT.INC
new file mode 100644
index 0000000..4c2213e
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/EMSINIT.INC
@@ -0,0 +1,886 @@
1
2;------------------------------------------------------------------------;
3; Initialization... ;
4;------------------------------------------------------------------------;
5
6RESR_EXT_PGS DW 0 ;Ext mem reserved here after EMS taken ;an002; dms;
7
8MACH_MODEL_PTR DD 0F000FFFEh ;Byte in upper BIOS that indicates @RH1
9MODEL_BYTE DB (?) ; which system you are on. @RH1
10PC1 EQU 0FFh ;Values returned for: PC 1 @RH1
11PC_XT EQU 0FEh ; PC XT @RH1
12XT_AQUARIUS EQU 0FBH ; PC Aquarius @RH1
13PC_AT EQU 0FCh ; PC AT type - AT, PS/2 models @RH1
14 ; 50 and 60, etc.
15PS2MODEL80 EQU 0F8h ; 386 processor - PS/2 model 80 @RH1
16
17INT15_SEC_MOD EQU ES:BYTE PTR [BX+3] ;Secondary model byte @RH2
18SEC_MOD_TB EQU 4 ; PS/2 Model 50 @RH2
19SEC_MOD_RR EQU 5 ; PS/2 Model 60 @RH2
20
21START_BACMEM_SEG DW 0 ;Starting and ending segment addrs
22END_BACMEM_SEG DW 0 ; of memory backed by the XMA card
23
24INIT_ERR DW ? ;Initialization error flag @RH4
25NO_ERROR EQU 0 ; @RH4
26ERROR EQU 1 ; @RH4
27 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
28 ;³ Device driver IOCTL call declares ³
29 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
30EMULATOR_DD_NAME DB '386XMAEM',0 ;Device driver names for the Emulator
31XMAAVIRT_DD_NAME DB 'INDXMAII',0 ; and WSP's XMA/A init code
32DD_FILE_HANDLE DW ? ;File handle from opening either DD
33
34REQ_PACKET_STRUC STRUC ;Generic IOCTL parameter packet
35PACKET_LEN DW 4 ;Packet length (in bytes)
36PACKET_FCN DW 0 ;DD defined function number
37PACKET_WORD DW 0 ;Data area
38REQ_PACKET_STRUC ENDS
39
40REQ_PACKET REQ_PACKET_STRUC <> ;
41
42
43INIT PROC
44
45 PUSH CS
46 POP DS ;Get this segment into CS
47
48 MOV DX,SS ;save stack segment
49 MOV CX,SP ;save stack pointer
50 CLI ;ints off during swap
51 MOV AX,CS ;move cs to ss
52 MOV SS,AX ;through ax
53 MOV SP,OFFSET TOP_OF_STACK ;sp to end of code
54 STI ;ints back on
55 PUSH DX ;save old ss on new stack
56 PUSH CX ;save old sp on new stack
57
58
59 MOV DX,OFFSET WELCOME_MSG ;Print title and copy-right
60 MOV AH,9 ;
61 INT 21H
62
63 push ax ;save affected regs ;an000; dms;
64 push bx ; ;an000; dms;
65 push cx ; ;an000; dms;
66 push dx ; ;an000; dms;
67 push si ; ;an000; dms;
68 push di ; ;an000; dms;
69 push ds ; ;an000; dms;
70
71 CALL GET_PARMS ;Get the user parameters
72
73 pop ds ;restore affected regs ;an000; dms;
74 pop di ; ;an000; dms;
75 pop si ; ;an000; dms;
76 pop dx ; ;an000; dms;
77 pop cx ; ;an000; dms;
78 pop bx ; ;an000; dms;
79 pop ax ; ;an000; dms;
80
81 JE PARMS_OK
82 PUSH CS
83 POP DS
84 MOV DX,OFFSET PARM_ERR_MSG ;Print message indicating
85 MOV AH,9 ; parameter error using
86 INT 21H ; DOS function call
87 MOV DX,OFFSET NOT_INSTL_MSG ;Print that the EMS driver
88 MOV AH,9 ; has not been installed
89 INT 21H ;
90 JMP GENERAL_FAILURE ;indicate general failure
91PARMS_OK:
92
93 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
94 ;³ Does the system use the XMA Emulator? ³
95 ;³ (PS/2 model 80 with 80386 processor) ³
96 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
97 PUSH DS ; @RH1
98 LDS SI,MACH_MODEL_PTR ; DS:SI points to model descriptor @RH1
99 MOV AL,DS:BYTE PTR [SI] ; byte (F000:FEEE) @RH1
100 MOV MODEL_BYTE,AL ; @RH1
101 POP DS ; @RH1
102
103 CMP MODEL_BYTE,PS2MODEL80 ;If the model byte is for a @RH7
104 JE FIND_EMULATOR ; PS/2 model 80 @RH7
105 JMP NOT_PS2MODEL80 ; then attempt to open the 80386 @RH7
106FIND_EMULATOR: ; XMA Emulator device driver @RH7
107 MOV AX,3D00h ; (INDXMAEM.SYS) @RH7
108 LEA DX,EMULATOR_DD_NAME ; @RH7
109 INT 21h ;No carry means open successful @RH7
110 JNC EMUL_INSTALLED ; and the DD is present @RH7
111 PUSH CS ;Else open failed @RH7
112 POP DS ;Print message indicating @RH7
113 MOV DX,OFFSET NO_EMUL_MSG ; emulator not present @RH7
114 MOV AH,9 ;dos prt string @RH7
115 INT 21H ;write message @RH7
116 MOV DX,OFFSET NOT_INSTL_MSG ;Print that the EMS driver @RH7
117 MOV AH,9 ; has not been installed @RH7
118 INT 21H ; @RH7
119 JMP GENERAL_FAILURE ;indicate general failure @RH7
120EMUL_INSTALLED: ;Emulator is present @RH7
121 MOV DD_FILE_HANDLE,AX ;Do IOCTL to find # of XMA blocks @RH7
122 MOV BX,AX ;Emulator DD handle in BX @RH7
123 MOV AX,440Ch ;Handle generic IOCTL fcn code @RH7
124 XOR CH,CH ;CH = 0 means "unknown" @RH7
125 MOV CL,60h ;CL = 40h means set device info @RH7
126 PUSH CS ; = 60h means get device info @RH7
127 POP DS ; @RH7
128 LEA DX,REQ_PACKET ;DS:DX -> generic IOCTL packet @RH7
129 INT 21h ;Issue the generic IOCTL @RH7
130 JNC EMUL_VER_GOOD ;No carry means the right @RH7
131 PUSH CS ; version of the Emulator was @RH7
132 POP DS ; installed (can handle IOCTL) @RH7
133 MOV DX,OFFSET WRONG_EMUL_MSG ;Otherwise print message @RH7
134 MOV AH,9 ; indicating incorrect version @RH7
135 INT 21H ; of the Emulator detected @RH7
136 MOV DX,OFFSET NOT_INSTL_MSG ;Print that the EMS driver @RH7
137 MOV AH,9 ; has not been installed @RH7
138 INT 21H ; @RH7
139 JMP GENERAL_FAILURE ;indicate general failure @RH7
140EMUL_VER_GOOD:
141 MOV AX,REQ_PACKET.PACKET_WORD ;Get the last available XMA block@RH7
142 INC AX ; number from the emulator...add 1 @RH7
143 XOR DX,DX ; to calc total XMA blocks and @RH7
144 DIV BLOCKS_PER_PAGE ; convert it to EMS pages @RH7
145 MOV TOTAL_SYS_PAGES,AX ;Set the number of total 16K pages @RH7
146 MOV TOTAL_EMS_PAGES,AX ; (before and after mem backing) @RH7
147 MOV FREE_PAGES,AX ; and the pages free for useage @RH7
148 MOV START_BACMEM_SEG,0 ;Mark from 0-640K as taken to @RH7
149 MOV END_BACMEM_SEG,0A000h ; back conventional memory and @RH7
150 CALL BACK_CONV_MEM ; adjust TOTAL_EMS_PAGES @RH7
151 MOV AX,3E00h ;Close the XMA Emulator device @RH7
152 MOV BX,DD_FILE_HANDLE ; driver @RH7
153 MOV MEMCARD_MODE,EMUL_VIRT ;Set flag for hardware used @RH7
154 INT 21h ; @RH7
155 JMP INT_67_INSTALL ;Install int 67 vector, end init @RH7
156 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
157NOT_PS2MODEL80: ;³ Does the system use the XMA\A or XMO card? ³
158 ;³ (PS/2 models 50 and 60) ³
159 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
160 CMP MODEL_BYTE,PC_AT ;If the model byte is for an 'AT' @RH2
161 JE MODEL_AT ; type (80286 processor), check @RH2
162 JMP FAMILY_1_MACH ; the secondary model byte to @RH2
163MODEL_AT: ; see if it's a model that uses @RH2
164 MOV AH,0C0h ; the XMA/A or XMO card @RH2
165 INT 15h ; @RH2
166 CMP INT15_SEC_MOD,SEC_MOD_TB; @RH2
167 JNE NOT_PS2MODEL50 ; @RH2
168 MOV NUM_OF_SLOTS,4 ; PS2/50 has 4 adapter slots @RH2
169 JMP PS2_5060 ; Init for XMA/A and XMO @RH2
170NOT_PS2MODEL50: ; @RH2
171 CMP INT15_SEC_MOD,SEC_MOD_RR;If 'AT' but not PS/2 50 or 60, @RH2
172 JE IS_PS2MODEL60 ; then family 1 (uses XMA 1 card) @RH2
173 JMP FAMILY_1_MACH ; @RH2
174IS_PS2MODEL60:
175 MOV NUM_OF_SLOTS,8 ;PS2/60 has 8 adapter slots @RH2
176 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
177PS2_5060: ;³ Machine is a PS/2 Model 50 (TB) or 60 (RR). ³
178 ;³ Check for the Workstation Program's XMA/A ³
179 ;³ virtual mode device driver (INDXMAA.SYS). If ³
180 ;³ present, use only that card in virtual mode. ³
181 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
182 MOV AX,3D00h ;Attempt to open WSP's XMA/A @RH6
183 LEA DX,XMAAVIRT_DD_NAME ; virtual mode device driver @RH6
184 INT 21h ;Carry means open failed and the @RH6
185 JC PS2_5060_REAL ; DD is not present. Use XMA/A @RH6
186 ; in real mode and XMO card. @RH6
187INDXMAA_INSTALLED: ;Else driver found. XMA/A virtual @RH6
188 MOV DD_FILE_HANDLE,AX ;Do IOCTL to find # of XMA/A blks @RH6
189 MOV BX,AX ;INDXMAA.SYS DD handle in BX @RH6
190 MOV AX,440Ch ;Handle generic IOCTL fcn code @RH6
191 XOR CH,CH ;CH = 0 means "unknown" @RH6
192 MOV CL,60h ;CL = 40h means set device info @RH6
193 PUSH CS ; = 60h means get device info @RH6
194 POP DS ; @RH6
195 LEA DX,REQ_PACKET ;DS:DX -> generic IOCTL packet @RH6
196 INT 21h ;Issue the generic IOCTL @RH6
197 JNC XMAA_VER_GOOD ;No carry means the right @RH6
198 PUSH CS ; version of the XMAA DD was @RH6
199 POP DS ; installed (can handle IOCTL) @RH6
200 MOV DX,OFFSET WRONG_XMAA_MSG ;Otherwise print message @RH6
201 MOV AH,9 ; indicating incorrect version @RH6
202 INT 21H ; of the XMAA DD detected @RH6
203 MOV DX,OFFSET NOT_INSTL_MSG ;Print that the EMS driver @RH6
204 MOV AH,9 ; has not been installed @RH6
205 INT 21H ; @RH6
206 JMP GENERAL_FAILURE ;indicate general failure @RH6
207XMAA_VER_GOOD:
208 MOV AX,REQ_PACKET.PACKET_WORD ;Get the last available XMA/A blk@RH6
209 INC AX ; number from the XMA/A DD...add 1 @RH6
210 XOR DX,DX ; to calc total XMA/A blocks and @RH6
211 DIV BLOCKS_PER_PAGE ; convert it to EMS pages @RH6
212 MOV TOTAL_SYS_PAGES,AX ;Set the number of total 16K pages @RH6
213 MOV TOTAL_EMS_PAGES,AX ; (before and after mem backing) @RH6
214 MOV FREE_PAGES,AX ; and the pages free for useage @RH6
215 MOV START_BACMEM_SEG,0 ;Mark from 0-640K as taken to @RH6
216 MOV END_BACMEM_SEG,0A000h ; back conventional memory and @RH6
217 CALL BACK_CONV_MEM ; adjust TOTAL_EMS_PAGES @RH6
218 MOV AX,3E00h ;Close the XMA/A virtual mode @RH6
219 MOV BX,DD_FILE_HANDLE ; device driver @RH6
220 INT 21h ; @RH6
221 MOV MEMCARD_MODE,XMAA_VIRT ;Set hardware flag to XMAA virtual @RH6
222 JMP INT_67_INSTALL ;Install int 67 vector,end init @RH6
223
224 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
225PS2_5060_REAL: ;³ PS/2 Model 50 or 60 without XMA/A virtual DD. ³
226 ;³ Use XMA/A card in real mode (Bank ID reg ³
227 ;³ not used) or XMO card. ³
228 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
229 CALL INIT_MOD_50_60 ;Init for XMA/A and XMO @RH2
230 CMP INIT_ERR,ERROR ;If no error then install the @RH2
231 JE PS2_5060_ERROR ; int 67 vector, print msgs @RH2
232 JMP INT_67_INSTALL ; @RH2
233PS2_5060_ERROR:
234 ;Else error in intialization @RH2
235 PUSH CS ;
236 POP DS ;
237 MOV AH,9 ; Barf out 1st part of msg @RH2
238 INT 21H ; set by subproc (DX = ptr) @RH2
239 MOV DX,OFFSET NOT_INSTL_MSG ;Print that the EMS driver @RH2
240 MOV AH,9 ; has not been installed @RH2
241 INT 21H ; @RH2
242 JMP GENERAL_FAILURE ;indicate general failure @RH2
243
244
245FAMILY_1_MACH: ;Family 1 machine (pre-PS/2)
246 mov rom_scan_type,family1 ; set flag for rom scan code - gga
247 MOV START_BACMEM_SEG,04000h ;Memory is backed from 256K to
248 MOV END_BACMEM_SEG,0A000h ; 640K on XMA 1 card
249 CALL PRESTST ;Insure XMA 1 card is present
250 JE XMA1_FOUND ;Zero flag = 1 means XMA 1 found
251 PUSH CS ;Else error..get this segment
252 POP DS ;into ds
253 MOV DX,OFFSET NOT_FOUND_MSG ;Print message for cannot
254 MOV AH,9 ; find adapter
255 INT 21H ;write message
256 MOV DX,OFFSET NOT_INSTL_MSG ;Print that the EMS driver
257 MOV AH,9 ; has not been installed
258 INT 21H ;
259 JMP GENERAL_FAILURE ;indicate general failure
260XMA1_FOUND:
261 MOV MEMCARD_MODE,XMA1_VIRT ;Indicate an XMA 1 card present @RH2
262 CALL TRY4MEG ;determine the size of the XMA memory card
263
264 PUSH CS
265 POP DS
266 MOV DX,OFFSET DGS_START_MSG ;start of diagnostics message
267 MOV AH,9 ;dos prt string
268 INT 21H ;starting diagnostics message
269 CALL CUR_POS ;save cursor position for KB OK msg
270
271 MOV DX,MODE_REG ;determine if this is a warm start
272 IN AL,DX ;read mode reg
273 AND AL,WARM_MASK ;isolate warm start bit
274 JZ DO_XMA1DIAG ;If off perform full XMA 1 diags
275 MOV CS:WARM_START,'Y' ;Else warm start..limited diags
276DO_XMA1DIAG:
277 CALL XMA1DIAGS ;Perform XMA 1 diagnostics
278 JE XMA1_OK ;Zero flag set means all OK
279 PUSH CS ;Else error..get this segment
280 POP DS ;into ds
281 MOV DX,OFFSET XMA1_ERR_MSG ;'XMA001 Adapter error'
282 MOV AH,9 ;dos prt string
283 INT 21H ;write message
284 MOV DX,OFFSET NOT_INSTL_MSG ;Print that the EMS driver
285 MOV AH,9 ; has not been installed
286 INT 21H ;
287 JMP GENERAL_FAILURE ;indicate general failure
288XMA1_OK:
289 PUSH CS ;get this segment
290 POP DS ;into ds
291 MOV DX,OFFSET DGS_END_MSG ;start of message
292 MOV AH,9 ;dos prt string
293 INT 21H ;write message
294
295;Set XMA in virtual mode to look like it was in real mode
296 CALL VIRT2REAL
297;Mark pages used on XMA card to back conventional memory
298 CALL BACK_CONV_MEM
299
300
301;Set up interrupt 67 vector
302INT_67_INSTALL:
303;------------------------
304; added by GGA
305;------------------------
306;-------------------------------------------------------------------
307 call romscan ; just for grins
308 jc ROM_Scan_Fail ; error - prompt user to hit any key ;an000; dms;
309 jmp Skip_Pars ; continue load of XMA2EMS ;an000; dms;
310
311ROM_Scan_Fail:
312
313 PUSH CS ;set up addressibility ;an000; dms;
314 POP DS ; ;an000; dms;
315 MOV DX,OFFSET Prompt_Msg ;Press any key to continue... ;an000; dms;
316 MOV AH,9 ;dos prt string ;an000; dms;
317 INT 21H ;
318
319 mov ah,07h ;keyboard input without ECHO ;an000; dms;
320 int 21h ;wait until input ;an000; dms;
321 jmp General_Failure ;
322;-------------------------------------------------------------------
323skip_pars:
324;------------------------
325; end of adds by GGA
326;------------------------
327
328 CALL INIT_PAL ;Initialize the Page Allocation @RH8
329 ; linked List RH8
330 CALL STEAL_INT67 ;
331
332
333
334
335 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
336 ;³ Initialize the entries in the Page Allocation List ³
337 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
338 MOV CX,TOTAL_SYS_PAGES
339
340
341;write variables into message string
342 PUSH CS ;get this segment
343 POP ES ;into es
344 MOV DI,OFFSET CONV_PAGES ;ascii string for numb fill pgs
345 MOV AX,END_BACMEM_SEG ;upper limit of fill
346 SUB AX,START_BACMEM_SEG ;minus lower start of fill
347 MOV CL,10
348 SHR AX,CL ;convert to number 16k blocks
349 CALL CNVDECAT
350
351 MOV DI,OFFSET RES_PAGES ;ascii string for pinta reserved pages
352 MOV AX,STARTING_BLOCK ;number of 4k pages res for pinta
353 SHR AX,1
354 SHR AX,1 ;convert to 16k pages
355 CALL CNVDECAT
356
357 MOV DI,OFFSET EMS_PAGES ;ascii string available ems pages
358 MOV AX,FREE_PAGES ;free pages
359 CALL CNVDECAT
360
361 MOV DI,OFFSET PF_START ;ascii string page frame
362 MOV AX,PAGE_FRAME_STA ;page frame
363 CALL CNVHEXAT
364
365;gga MOV DX,OFFSET PAGE_FRAME_MSG ;start of message
366;gga MOV AH,9 ;dos prt string
367;gga INT 21H ;status msg1
368
369 CMP STARTING_BLOCK,0
370; $IF A
371 JNA $$IF117
372 MOV DX,OFFSET RESERVE_MSG ;start of message
373 MOV AH,9 ;dos prt string
374 INT 21H ;status msg2
375; $ENDIF
376$$IF117:
377
378;gga MOV DX,OFFSET AVAIL_MSG ;start of message
379;gga MOV AH,9 ;dos prt string
380;gga INT 21H ;status msg3
381
382;indicate that the card has been tested
383 MOV DX,MODE_REG
384 IN AL,DX ;read mode reg
385 OR AL,WARM_MASK ;turn on warm start bit
386 OUT DX,AL ;write it back
387
388 call Calc_INT15_Space ;calculate remaining INT 15h space ;an000; dms;
389 call Steal_INT15 ;hook INT 15h ;an000; dms;
390 call Steal_Int13 ;hook INT 13h ;an004; dms;
391
392 JMP COMMON_EXIT_PATH
393
394
395GENERAL_FAILURE:
396
397 LDS BX,CS:RH_PTRA ;ELSE ...
398 MOV AX,STAT_GENFAIL ;INDICATE A GENERAL FAILURE
399 MOV RH.RHC_STA,AX ;WRITE IT TO RH STATUS
400;------------------------
401; adds by GGA
402;------------------------
403 xor ax,ax ; zero segment and offset
404 mov rh.rh0_endo,ax ; offset of ending addr
405 push cs
406 pop ax
407 mov rh.rh0_ends,ax ; segment of ending addr
408
409 mov rh.rh0_err,0ffh ; error flag for DOS
410
411 mov rh.rh0_nun,al ; = 0 causes installation failure
412
413 jmp skip_size
414;------------------------
415COMMON_EXIT_PATH:
416;move cursor to next line so other messages are clear
417 PUSH CS ;get cs
418 POP DS ;into ds
419 MOV DX,OFFSET NEXT_LINE + 1 ;get offset of string
420 MOV AH,9 ;dos print string
421 INT 21H
422
423 LDS BX,CS:RH_PTRA ;ADDRESSABILITY INTO RH
424 MOV AX,OFFSET RESIDENT + STACK_SIZE + 100H
425 MOV RH.RH0_ENDO,AX ;OFFSET OF ENDING ADDR
426 PUSH CS
427 POP AX
428 MOV RH.RH0_ENDS,AX ;OFFSET OF ENDING ADDR
429
430skip_size: ; gga
431
432 POP CX ;recover old ss
433 POP DX ;recover old sp
434 CLI ;ints off during swap
435 MOV SP,CX ;restore old sp
436 MOV SS,DX ;restore old ss
437 STI ;ints back on
438
439
440 RET
441INIT ENDP
442
443;-----------------------------------------------------------------------;
444; STEAL_INT67 changes the INT 67H vector to point to this ;
445; Memory Manager to field subsequent calls. ;
446;-----------------------------------------------------------------------;
447STEAL_INT67 PROC
448 PUSH DS
449 XOR AX,AX
450 MOV DS,AX ;set DS = 0
451 ASSUME DS:INT_VEC
452 CLI ;disable interrupts
453 LES DI,DS:EMS_VEC ;get addressing into vector
454 MOV DS:EMS_VECO,OFFSET EMS_INT67 ;offset of new INT routine
455 MOV DS:EMS_VECS,CS ;segment of new INT routine
456 STI ;enable interrupts again
457 POP DS ;restore DS
458 RET
459STEAL_INT67 ENDP
460
461;-----------------------------------------------------------------------;
462; VIRT2REAL puts the XMA into 'virtual' mode with the translate ;
463; table written such that memory is mapped just as it was ;
464; in 'real' mode. (Either 256-640k or 512-640k reamains fixed ;
465; for all ID's) ;
466; ;
467; all registers are preserved ;
468; ;
469;-----------------------------------------------------------------------;
470VIRT2REAL PROC
471 PUSH AX
472 PUSH BX
473 PUSH CX
474 PUSH DX
475 PUSH DS ;save these registers
476
477 PUSH CS ;get this segment
478 POP DS ;into ds
479;inhibit all of XMA memory before going into virtual mode
480 XOR AX,AX ;start at segment 0
481 XOR BL,BL ;inhibit
482 MOV CX,1024/4 ;all 4k blocks in pc space
483 CALL INHIBLK
484;now map virtual mode to look like real mode
485 MOV AX,START_BACMEM_SEG ;starting 'fill' segment
486 MOV DX,AX ;get it into dx
487 XCHG DH,DL ;and shr 8 to convert it to 4k block #
488 XOR BH,BH ;start at task ID=0
489 MOV BL,1 ;enable
490 MOV CX,16 ;do for all 16 task ID's
491; $DO
492$$DO119:
493 PUSH AX ;save these
494 PUSH CX ;because they are
495 PUSH DX ;destroyed by call
496 MOV CX,160 ;640K = 160*4K blocks
497 SUB CX,DX ;minus starting 4K block
498 ;is # 4K blocks to map for this ID
499 CALL SETXLAT ;write trans table accordingly
500 POP DX ;recover these registers
501 POP CX
502 POP AX
503 INC BH ;next ID
504; $ENDDO LOOP
505 LOOP $$DO119
506
507 MOV DX,MODE_REG
508 IN AL,DX ;read mode reg
509 OR AL,VIRT_MODE ;turn on virtual bit
510 OUT DX,AL ;write it back
511
512 POP DS ;restore these registers
513 POP DX
514 POP CX
515 POP BX
516 POP AX
517 RET
518VIRT2REAL ENDP
519
520
521include romscan.inc ; code to do romscan for hole location/verification
522INCLUDE PARMPARS.INC ;Routines to parse the parameters
523 ; on the CONFIG.SYS line
524
525;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
526;³ Subprocedure: BACK_CONV_MEM ³
527;³ ³
528;³ Purpose: Called when a portion of the XMA card is used to back ³
529;³ conventional memory. This is the case on an XMA 1 ³
530;³ card (256K - 640K disabled on planar) and on the ³
531;³ XMA/A card when WSP's XMA/A initialization device ³
532;³ driver has disabled the planar. ³
533;³ This procedure will mark the Page Allocation List for ³
534;³ these entries with an ASCII value (for debugging) that ³
535;³ is above the range of eligible pointer values. ³
536;³ At the time this proc is called the PAL has not been ³
537;³ initialized. Initialization will skip these entries. ³
538;³ ³
539;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
540BACK_CONV_MEM PROC
541 MOV AX,END_BACMEM_SEG ;upper segment of backed memory
542 SUB AX,START_BACMEM_SEG ;subtract seg of backed memory start
543 MOV CL,10 ;conver # of segments to # of 16 K
544 SHR AX,CL ; pages used for fill (div by 1024)
545 SUB TOTAL_EMS_PAGES,AX ;subtract from total EMS pages
546 ; (but not from TOTAL_SYStem_PAGES)
547 SUB FREE_PAGES,AX ;subtract from free EMS pages
548 MOV CX,AX ;Put # of backing pages into CX
549 PUSH CX ; and save it on stack
550
551 MOV AX,START_BACMEM_SEG ;Convert the segment value for the
552 MOV CL,10 ; start of backed memory to its
553 SHR AX,CL ; corresponding page number
554 MOV DX,TYPE PAGE_ALLOC_LIST ; then convert to the correct @RH8
555 MUL DX ; entry in the page alloc list @RH8
556 MOV SI,AX ; store PAL offset into SI
557 POP CX ;recover loop counter for # backed
558;mark these pages used in page list but do not assign a handle
559BACK_MEM_PAL:
560 MOV PAGE_LIST_ENTRY,BACMEM_ALLOC ;Mark the PAL with ascii @RH8
561 ADD SI,TYPE PAGE_ALLOC_LIST ;Next entry in PAL @RH8
562 LOOP BACK_MEM_PAL
563 ;Remove code here that used to reserve pages for
564 ; WSP by reading a value on the CONFIG.SYS line.
565 ; Instead, WSP will make an IOCTL call for the
566 ; number of pages it needs.
567BACK_CONV_MEM ENDP
568
569;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
570;³ Subprocedure: INIT_PAL ³
571;³ ³
572;³ Purpose: This subprocedure will link the Page Allocation List. ³
573;³ The head pointer to the list of available pages ³
574;³ (PAL_FREE_PTR) is initialized to the top EMS page, ³
575;³ and all available pages are linked from top to bottom. ³
576;³ All free pages will initially be contiguous, except on ³
577;³ an XMA 1 system. With XMA 1, 256-640K on the card is ³
578;³ used to back conventional memory. The free list will ³
579;³ skip around these pages (pages 16 to 40). ³
580;³ ³
581;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
582INIT_PAL PROC
583 push cs ;set up addressibility ;an000; dms;
584 pop ds ; ;an000; dms;
585
586 cmp Total_EMS_Pages,0 ;any pages? ;an000; dms;
587 je Init_Pal_End ;no - exit ;an000; dms;
588
589 mov ax,Total_Sys_Pages ;top of EMS pages = ;an000; dms;
590 add ax,Resr_Ext_Pgs ; total EMS pages + ;an000; dms;
591 dec ax ; rsv ext. pages - 1 ;an000; dms;
592
593
594 mov si,ax ;ptr to free page ;an000; dms;
595 shl si,1 ;make an index ;an000; dms;
596 mov Page_List_Entry,Pal_Null ;set last entry to null ;ac007; dms;
597 shr si,1 ;convert to ptr value ;an007; dms;
598 mov di,si ;place in di ;an007; dms;
599
600 dec ax ;next page ;an000; dms;
601 mov cx,Total_EMS_Pages ;loop for all entries ;an000; dms;
602 dec cx ; but the last ;an000; dms;
603
604INIT_PAL_LP:
605
606 cmp cx,0 ;at end? ;an000; dms;
607 je Init_Pal_Loop_Exit ;yes - exit ;an000; dms;
608
609 mov si,ax ;ptr to next page ;ac007; dms;
610 shl si,1 ;make an index ;ac007; dms;
611 cmp Page_Alloc_List[si],BacMem_Alloc ;backfilled memory? ;ac007; dms;
612 jne Init_Pal_Entry ;no - set up ptr's ;an000; dms;
613 dec ax ;yes - next ptr value ;an000; dms;
614 jmp Init_Pal_LP ;keep on looping ;an000; dms;
615INIT_PAL_ENTRY:
616 mov Page_List_Entry,di ;set up ptr value ;ac007; dms;
617 mov di,si ;next ptr value ;ac007; dms;
618 shr di,1 ;make a ptr value ;an007; dms;
619INIT_PAL_BOT:
620 dec ax ;get next ptr value ;an000; dms;
621 dec cx ;dec loop counter ;an000; dms;
622 jmp INIT_PAL_LP ;continue looping ;an000; dms;
623
624Init_Pal_Loop_Exit:
625 mov Pal_Free_Ptr,di ;init free ptr ;an007; dms;
626
627INIT_PAL_END:
628 ret ;return to caller ;an000; dms;
629INIT_PAL ENDP
630
631;-----------------------------------------------------------------------;
632; This routine will convert a number in (AX) to a ;
633; 4 byte ascii string equivalent to a 4 digit decimal ;
634; number and write it at the address pointed to ;
635; by ES:DI. Leading zeroes are suppressed. ;
636; ;
637; On entry: (AX) = number to be converted ;
638; ES:DI= address where string is to be written ;
639; ;
640; On exit: all registers are preserved ;
641; ;
642;-----------------------------------------------------------------------;
643
644CNVDECAT PROC
645
646 PUSH AX
647 PUSH CX
648 PUSH DX
649 PUSH DI ;save these registers
650
651 MOV CX,4 ;loop counter 4 digits
652; $DO
653$$DO152:
654 XOR DX,DX ;clear hi word of dividend
655 ;ax is low word of dividend
656 DIV CS:TEN ;divide by 10
657 OR DL,30H ;make modulo into ascii digit
658 PUSH DX ;put it on stack
659; $ENDDO LOOP ;repeat for all 4 digits
660 LOOP $$DO152
661
662 MOV CX,4 ;recover 4 digits from stack
663; $DO
664$$DO154:
665 POP AX ;recover next most sign digit
666 CMP AL,'0' ;is it a '0'
667; $IF NE
668 JE $$IF155
669 PUSH AX ;back on stack for next loop
670 JMP LEAD_DIGIT ;if not then we found leading non zero
671; $ENDIF
672$$IF155:
673; $ENDDO LOOP ;else continiue til non zero found
674 LOOP $$DO154
675LEAD_DIGIT:
676; $IF NCXZ ;only if cx is non zero
677 JCXZ $$IF158
678; $DO
679$$DO159:
680 POP AX ;recover next digit
681 MOV ES:BYTE PTR [DI],AL ;write it to string
682 INC DI ;point to next byte
683; $ENDDO LOOP ;repeat for all digits
684 LOOP $$DO159
685; $ENDIF
686$$IF158:
687
688 POP DI ;recover these registers
689 POP DX
690 POP CX
691 POP AX
692
693 RET ;return to caller
694CNVDECAT ENDP
695
696
697
698;-----------------------------------------------------------------------;
699; This routine will convert a number in (AX) to a ;
700; 4 byte ascii string equivalent to a 4 digit hexadecimal ;
701; number and write it at the address pointed to ;
702; by ES:DI. Leading zeroes are suppressed. ;
703; ;
704; On entry: (AX) = number to be converted ;
705; ES:DI= address where string is to be written ;
706; ;
707; On exit: all registers are preserved ;
708; ;
709;-----------------------------------------------------------------------;
710
711DEC2ASCII DB '0123456789ABCDEF'
712
713
714CNVHEXAT PROC
715
716 PUSH AX
717 PUSH BX
718 PUSH CX
719 PUSH DX
720 PUSH DI ;save these registers
721 PUSH DS
722
723 PUSH CS
724 POP DS
725
726 MOV BX,OFFSET DEC2ASCII
727 MOV CX,4 ;loop counter 4 digits
728; $DO
729$$DO162:
730 XOR DX,DX ;clear hi word of dividend
731 ;ax is low word of dividend
732 DIV SIXTEEN ;divide by 10
733
734 PUSH AX ;save quotient
735 MOV AX,DX ;get modulo into ax
736 XLAT DEC2ASCII ;convert al to ascii
737 MOV DX,AX ;get it into dx
738 POP AX ;recover quotient
739 PUSH DX ;put ascii modulo on stack
740; $ENDDO LOOP ;repeat for all 4 digits
741 LOOP $$DO162
742
743 MOV CX,4 ;recover 4 digits from stack
744; $DO
745$$DO164:
746;gga POP AX ;recover next most sign digit
747;gga CMP AL,'0' ;is it a '0'
748; $IF NE
749;gga JE $$IF165
750;gga PUSH AX ;back on stack for next loop
751;gga JMP CNVH1 ;if not then we found leading non zero
752; $ENDIF
753$$IF165:
754; $ENDDO LOOP ;else continiue til non zero found
755;gga LOOP $$DO164
756CNVH1:
757; $IF NCXZ ;only if cx is non zero
758 JCXZ $$IF168
759; $DO
760$$DO169:
761 POP AX ;recover next digit
762 MOV ES:BYTE PTR [DI],AL ;write it to string
763 INC DI ;point to next byte
764; $ENDDO LOOP ;repeat for all digits
765 LOOP $$DO169
766; $ENDIF
767$$IF168:
768
769 POP DS
770 POP DI ;recover these registers
771 POP DX
772 POP CX
773 POP BX
774 POP AX
775
776 RET ;return to caller
777CNVHEXAT ENDP
778
779;-----------------------------------------------------------------------;
780; STEAL_INT15 changes the INT 15H vector to point to this EMS' ;
781; so that subsequent calls to INT15H may determine the actual ;
782; size of EM after EMS' allocation of it ;
783;-----------------------------------------------------------------------;
784STEAL_INT15 PROC
785 PUSH DS
786 push ax
787
788 CMP MODEL_BYTE,PS2MODEL80 ;If a PS2/80 treat as XMA memory ;an000; dms;
789 je Steal_INT15_Exit ;do not hook INT15h ;an000; dms;
790
791 CMP MODEL_BYTE,PC_AT ;If the model byte is for an 'AT' @RH2
792 jne Steal_INT15_Hook ; type (80286 processor), check @RH2
793
794 MOV AH,0C0h ; the XMA/A or XMO card @RH2
795 INT 15h ; @RH2
796 CMP INT15_SEC_MOD,SEC_MOD_TB; @RH2
797 JE Steal_INT15_Hook ; @RH2
798
799 CMP INT15_SEC_MOD,SEC_MOD_RR;If 'AT' but not PS/2 50 or 60, @RH2
800 JE Steal_INT15_Hook ; then family 1 (uses XMA 1 card) @RH2
801 JMP Steal_INT15_Exit ; @RH2
802
803Steal_INT15_Hook:
804
805 XOR AX,AX
806 MOV DS,AX ;set DS = 0
807 ASSUME DS:INT_VEC15
808 CLI ;disable interrupts
809 LES DI,DS:EM_VEC ;get original vector's content
810 MOV CS:INTV15O,DI ;save original vector
811 MOV CS:INTV15S,ES
812 MOV DS:EM_VECO,OFFSET XMA_INT15 ;offset of new INT routine
813 MOV DS:EM_VECS,CS ;segment of new INT routine
814 STI ;enable interrupts again
815
816Steal_INT15_Exit:
817
818 pop ax
819 POP DS ;restore DS
820 RET
821STEAL_INT15 ENDP
822
823
824;-----------------------------------------------------------------------;
825; Calc_INT15_Space calculates the remaining extended memory for ;
826; the system. This value will be used by all subsequent calls ;
827; to function 88h, INT 15h. ;
828;-----------------------------------------------------------------------;
829Calc_INT15_Space proc near ;an000; dms;
830
831 push ax ;save regs ;an000; dms;
832 push bx ; ;an000; dms;
833 push cx ; ;an002; dms;
834 push dx ; ;an000; dms;
835
836 mov ah,EM_Size_Get ;get extended mem ;an000; dms;
837 int 15h ; ;an000; dms;
838
839 mov cl,4 ;divide by 16 ;an002; dms;
840 shr ax,cl ; to get page count ;an002; dms;
841
842 sub ax,cs:Total_Sys_Pages ;new extended mem size ;an002; dms;
843 xor dx,dx ;get K count ;an002; dms;
844 mov bx,cs:Sixteen ; ;an002; dms;
845 mul bx ; ;an002; dms;
846 mov word ptr cs:EM_Ksize,ax ;save new size ;an000; dms;
847
848 pop dx ;restore regs ;an000; dms;
849 pop cx ; ;an002; dms;
850 pop bx ; ;an000; dms;
851 pop ax ; ;an000; dms;
852
853 ret
854
855Calc_INT15_Space endp ;an000; dms;
856
857
858;-----------------------------------------------------------------------;
859; STEAL_INT13 changes the INT 13H vector to point to this EMS' ;
860; so that subsequent calls to INT13H may properly handle DMA ;
861; to EMS pages. ;
862;-----------------------------------------------------------------------;
863Steal_Int13 PROC ;an004; dms;
864 PUSH DS ;an004; dms;
865 push ax ;an004; dms;
866
867 CMP MODEL_BYTE,PS2MODEL80 ;If not a PS2/80 don't hook INT 13h ;an004; dms;
868 jne Steal_INT15_Exit ; ;an004; dms;
869
870 XOR AX,AX
871 MOV DS,AX ;set DS = 0
872 ASSUME DS:INT_VEC13
873 CLI ;disable interrupts
874 LES DI,DS:DK_VEC ;get original vector's content
875 MOV CS:INTV13O,DI ;save original vector
876 MOV CS:INTV13S,ES
877 MOV DS:DK_VECO,OFFSET I13_Handler ;offset of new INT routine
878 MOV DS:DK_VECS,CS ;segment of new INT routine
879 STI ;enable interrupts again
880
881Steal_INT13_Exit:
882
883 pop ax
884 POP DS ;restore DS
885 RET
886STEAL_INT13 ENDP
diff --git a/v4.0/src/DEV/XMA2EMS/EMS_US.MSG b/v4.0/src/DEV/XMA2EMS/EMS_US.MSG
new file mode 100644
index 0000000..72100b8
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/EMS_US.MSG
@@ -0,0 +1,110 @@
1LF EQU 0AH ;ASCII line feed
2CR EQU 0DH ;ASCII carriage return
3
4CRLF DB CR,LF ; gga used to skip a blank line
5 db '$'
6
7WELCOME_MSG DB 'XMA2EMS: Expanded Memory Manager'
8 DB CR,LF
9 DB '(c)Copyright 1988 Microsoft Corporation All rights reserved'
10 DB CR,LF
11 DB '$'
12
13DGS_START_MSG DB CR,LF
14 DB 'Performing XMA diagnostics: '
15 DB '$'
16
17DGS_END_MSG DB CR,LF
18 DB 'Diagnostics completed '
19 DB CR,LF,LF
20 DB '$'
21
22PAGE_FRAME_MSG DB 'Page Frame starts at........................ '
23PF_START DB 'XXXX'
24 DB ':0'
25 DB CR,LF
26 DB 'Pages mapped to conventional memory......... '
27CONV_PAGES DB '0 '
28 DB CR,LF
29 DB '$'
30RESERVE_MSG DB 'Pages reserved for 3270 PC Control Program.. '
31RES_PAGES DB '0 '
32 DB CR,LF
33 DB '$'
34AVAIL_MSG DB 'Pages available for expanded memory......... '
35EMS_PAGES DB '0 '
36 DB CR,LF
37 DB '$'
38
39XMA1_ERR_MSG DB CR,LF
40 DB 'Adapter error '
41 DB CR,LF
42 DB '$'
43
44NOT_FOUND_MSG DB CR,LF
45 DB 'Cannot find adapter '
46 DB CR,LF
47 DB '$'
48
49PARM_ERR_MSG DB CR,LF
50 DB 'Parameter syntax or value error '
51 DB CR,LF
52 DB '$'
53
54NO_EMUL_MSG DB CR,LF
55 DB 'Cannot find XMA Emulator device driver '
56 DB CR,LF
57 DB '$'
58
59WRONG_EMUL_MSG DB CR,LF
60 DB 'Incorrect version of XMAEM.SYS '
61 DB CR,LF
62 DB '$'
63
64WRONG_XMAA_MSG DB CR,LF
65 DB 'Incorrect version of INDXMAA.SYS '
66 DB CR,LF
67 DB '$'
68
69REQ_EMS_ERR_MSG DB CR,LF
70 DB 'Too many EMS pages requested in /X parameter '
71 DB CR,LF
72 DB '$'
73
74NOT_INSTL_MSG DB 'Expanded Memory Manager has NOT been installed'
75 DB CR,LF
76 DB '$'
77
78CONFLICT_MSG DB 'Specified page address conflicts with installed adapter at address '
79CONFL_ADDRESS DB '0 '
80 DB CR,LF
81 DB '$'
82
83HOLE_MSG DB 'Possible 16KB page available at address '
84HOLE_ADDRESS DB '0 '
85 DB CR,LF
86 DB '$'
87
88FRAME_MSG DB CR,LF
89 DB 'Possible 64KB frame available at address '
90FRAME_ADDRESS DB '0 '
91 DB CR,LF
92 DB '$'
93
94NO_PAGES_MSG DB 'No page addresses specified'
95 DB CR,LF
96 DB '$'
97
98
99SIZE_MSG1 DB SIZE1_END - 2 -$
100MEM_OK DB 4 DUP (?)
101 DB ' KB OK$'
102SIZE1_END EQU $
103
104NEXT_LINE DB NXT_LN_END - 2 -$
105 DB ' ',CR,LF,'$'
106NXT_LN_END EQU $
107
108Prompt_Msg db 'Press any key to continue . . .',CR,LF
109 db '$'
110
diff --git a/v4.0/src/DEV/XMA2EMS/GENIOCTL.INC b/v4.0/src/DEV/XMA2EMS/GENIOCTL.INC
new file mode 100644
index 0000000..1580fce
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/GENIOCTL.INC
@@ -0,0 +1,167 @@
1
2GENERIC_IOCTL_P PROC
3;ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸
4;³ This routine handles the Generic IOCTL call. The EMS device driver ³
5;³ provides an interface through the Generic IOCTL call to allocate pages ³
6;³ for the Workstation Program. Since WSP needs memory off the 'bottom' of ³
7;³ the XMA card in order to bank switch memory, an IOCTL call is needed to ³
8;³ mark these pages as allocated in the Page Allocation Table. ³
9;³ ³
10;³ The pages for EMS are taken from the linked Page Allocation List. ³
11;³ The PAL is initialized from top down, meaning pages that correspond to ³
12;³ the highest physical addresses on the card are at the beginning of the ³
13;³ free list. Therefore, WSP needs to get the pages from the end of the ³
14;³ free list. ³
15;³ ³
16;³ Programs may load before WSP and allocate and deallocate pages. ³
17;³ This will work fine for WSP, since these pages will come from the 'top' ³
18;³ using the standard function 43 allocate call. It will even work if ³
19;³ an application allocates these bottom pages and then deallocates to ³
20;³ the EMS pool, since the deallocated pages are returned to the top of ³
21;³ the free list and linked in reverse order. The allocates and deallocates ³
22;³ must, however, occur in a stack (LIFO) order or problems will arise. ³
23;³ For example, suppose the system has 30 EMS pages. Handle A allocs ³
24;³ 20 pages that come from the 'top' of the memory card. Handle B then ³
25;³ allocs the bottom 10. Handle A goes counter to LIFO order and deallocs ³
26;³ its 20. WSP then issues this generic IOCTL call asking for 20 pages. ³
27;³ The pages are available, but they are not from the bottom physical ³
28;³ blocks on the card. For this we return error code '91'x (see below). ³
29;³ ³
30;³ The call from WSP's loader will be function 0. No other functions are ³
31;³ supported at this time. If an error is encountered, the return code ³
32;³ is set in the request packet, but not the device driver header. The ³
33;³ header error is set by previous versions of the EMS driver that didn't ³
34;³ handle the IOCTL. ³
35;³ ³
36;ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
37;³ On entry: ES:BX -> Device driver request header ³
38;³ ³
39;³ The IOCTL code will set standard EMS return codes in the packet's function ³
40;³ field on exit. These include: ³
41;³ '00'x - Good - Requested pages reserved for WSP ³
42;³ '80'x - Software malfunction in EMS software ³
43;³ '84'x - Function code passed is not defined ³
44;³ '87'x - Insufficient total pages to satisfy request ³
45;³ '88'x - Insufficient free pages to satisfy request ³
46;³ '89'x - 0 pages requested ³
47;³ '90'x - Parameter list has an invalid length (Not an EMS return code) ³
48;³ '91'x - Allocated pages do not correspond to ³
49;³ the 'bottom' blocks of XMA memory (Not an EMS return code) ³
50;³ ³
51;ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
52
53GIP EQU ES:[DI] ;Pointer to the Generic IOCTL packet @RH6
54
55GEN_IOCTL_PARM STRUC ; @RH6
56GIO_PLEN DW ? ; Length of the parameter list @RH6
57GIO_FCNRC DW ? ; Function code on call, ret code on ret
58GIO_WSPP DW ? ; Number of pages to reserve for WSP @RH6
59GEN_IOCTL_PARM ENDS ;
60
61GENERIC_IOCTL: ; @RH6
62 PUSH ES ;Save pointer to the request header
63 PUSH BX
64 LES DI,RH.RH19_RQPK ;Point ES:DI to the Generic IOCTL @RH6
65 ; request packet @RH6
66 PUSH CS ;Set addressability to our data @RH6
67 POP DS ; @RH6
68 XOR AH,AH ;Init upper half of user's ret code @RH6
69 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
70 ;³ First insure the parameter list is long enough ³
71 ;³ to input the number of pages needed by WSP ³
72 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
73 CMP GIP.GIO_PLEN,4 ;If the length is 4 bytes then OK @RH6
74 JE GIO_FCN_CHK ;Else give invalid len ret code @RH6
75 MOV AL,90h ; and error exit @RH6
76 JMP GIP_EXIT ; @RH6
77 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
78 ;³ Check for function code 0 (only one available) ³
79GIO_FCN_CHK: ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
80 CMP GIP.GIO_FCNRC,0 ; @RH6
81 JE GIO_REQNOT0_CHK ; @RH6
82 MOV AL,EMS_CODE84 ; @RH6
83 JMP GIP_EXIT ; @RH6
84 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
85 ;³ Parm list is OK. Attempt to reserve WSP pages. ³
86GIO_REQNOT0_CHK: ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
87 MOV BX,GIP.GIO_WSPP ;BX = requested WSP pages @RH6
88 CMP BX,0 ;Check that request was not 0 @RH6
89 JNE GIO_NOT0 ; @RH6
90 MOV AL,EMS_CODE89 ; @RH6
91 JMP GIP_EXIT ; @RH6
92
93GIO_NOT0: ; @RH6
94 CMP BX,TOTAL_EMS_PAGES ;Check for enough total pages @RH6
95 JNA GIO_OKTOTAL ; @RH6
96 MOV AL,EMS_CODE87 ; @RH6
97 JMP GIP_EXIT ; @RH6
98
99 ;Note: section is not reentrant. It is possible RH8
100 ; that between the time FREE_PAGES is loaded and RH8
101 ; then changed, an EMS allocate or deallocate RH8
102 ; could occur and hose this up. However, since RH8
103 ; WSP is loading at this point, it is unlikely. RH8
104GIO_OKTOTAL:
105 CLI ;Don't allow other alloc or deall @RH8
106 CMP BX,FREE_PAGES ;Check for enough free pages @RH6
107 JNA GIO_REMOVE_FREE ; If not enough pages free then @RH6
108 MOV AX,FREE_PAGES ; return number of free in parm @RH6
109 STI ; list and set ret code @RH8
110 MOV GIP.GIO_WSPP,AX ; @RH6
111 MOV AL,EMS_CODE88 ; @RH6
112 JMP GIP_EXIT ; @RH6
113
114 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
115 ;³ Remove WSP pages from the end of the free list ³
116 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
117GIO_REMOVE_FREE:
118 SUB FREE_PAGES,BX
119 MOV CX,FREE_PAGES
120 MOV SI,PAL_FREE_PTR
121 STI
122 SHL SI,1
123
124 CMP CX,0 ;WSP LEAVE NOTHING FREE?
125 JNE GIO_GET_LAST_FREE ;YES SET FREE PTR TO NULL
126 MOV PAL_FREE_PTR,PAL_NULL
127 JMP SHORT GIO_MARK_WSP
128
129
130GIO_GET_LAST_FREE:
131 DEC CX
132 CMP CX,0
133 JE GIO_GOT_LAST_FREE
134GIO_LAST_FREE_LOOP:
135 MOV SI,PAGE_LIST_ENTRY ;BASED OFF SI
136 SHL SI,1
137 LOOP GIO_LAST_FREE_LOOP
138
139
140GIO_GOT_LAST_FREE:
141 MOV AX,PAGE_LIST_ENTRY ;STORE OFFSET FOR 1ST WSP
142 MOV PAGE_LIST_ENTRY,PAL_NULL ;THEN MAKE IT END OF FREE LIST
143 MOV SI,AX ;RESTORE 1ST WSP (TOP)
144 SHL SI,1
145
146GIO_MARK_WSP:
147 MOV CX,BX ;LOOPR FOR WSP PAGES
148GIO_WSP_LOOP:
149 MOV AX,PAGE_LIST_ENTRY ;STORE INDEX OF NEXT
150 MOV PAGE_LIST_ENTRY,WSP_ALLOC ;MARK AS WSP
151 MOV SI,AX ;RESTOER INEX OF NEXT
152 SHL SI,1
153 LOOP GIO_WSP_LOOP
154
155 XOR AX,AX ;Set good return code
156
157GIP_EXIT: ;GGA
158
159 MOV GIP.GIO_FCNRC,AX ;Store ret code in user's req packet
160 POP BX ;Restore for ptr to request header @RH6
161 POP ES ; @RH6
162 MOV RH.RHC_STA,STAT_DONE ; Store done status and good return@RH6
163 ; code into request header @RH6
164 RET
165GENERIC_IOCTL_P ENDP
166
167 \ No newline at end of file
diff --git a/v4.0/src/DEV/XMA2EMS/I13HOOK.INC b/v4.0/src/DEV/XMA2EMS/I13HOOK.INC
new file mode 100644
index 0000000..2f981c2
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/I13HOOK.INC
@@ -0,0 +1,449 @@
1
2include MSBDS.INC ;include BDS struc ;an000; dms;
3
4
5
6
7;=========================================================================
8; I13_Handler - This routine is the main driver of the
9; INT 13h hook.
10;=========================================================================
11
12I13_Handler proc far ; ;an000; dms;
13
14 jmp I13_Handler_Start
15
16
17I13_Max_Head db ? ;max head count on drive ;an000; dms;
18I13_SPT db ? ;max sectors/track count ;an000; dms;
19I13_BPS dw ? ;max number bytes/sector ;an000; dms;
20I13_Bytes_Per_Para dw 10h ;number of bytes per paragraph ;an000; dms;
21I13_Bytes_Per_EMS_Page dw 4000h ;bytes per EMS page ;an000; dms;
22I13_Paras_Per_Sector dw ? ;paras per sector ;an000; dms;
23I13_DD_Per_Sector dw ? ;double words per sector ;an000; dms;
24I13_Operation db ? ;INT 13h function ;an000; dms;
25I13_Sector_Count db ? ;sector count ;an000; dms;
26I13_Track_Number dw ? ;track number ;an000; dms;
27I13_Sector_Number db ? ;sector number ;an000; dms;
28I13_Head_Number db ? ;head number ;an000; dms;
29I13_Drive_Number db ? ;drive number ;an000; dms;
30I13_Sectors_To_Trf db 1 ;current sectors to trf ;an000; dms;
31I13_Curr_Trf_Cnt db ? ;total transfer count in secs ;an000; dms;
32I13_Trf_Off dw ? ;current address for trf ;an000; dms;
33I13_Trf_Seg dw ? ;an000; dms;
34I13_512_Byte_Buffer db 512 dup(0) ;buffer for sector ;an000; dms;
35
36I13_Handler_Start:
37
38 sti ;ints on ;an000; dms;
39 cmp ah,02h ;read operation? ;an000; dms;
40 je I13_Handler_Get_Parms ;yes - get drive parms ;an000; dms;
41
42 cmp ah,03h ;write operation? ;an000; dms;
43 je I13_Handler_Get_Parms ;yes - get drive parms ;an000; dms;
44
45 jmp cs:IntV13 ;neither - go to old INT 13h ;an000; dms;
46
47I13_Handler_Get_Parms:
48
49 call I13_Get_Dev_Parms ;get device parms for this drive;an000; dms;
50 jnc I13_Handler_Range_Ck ;we have device data ;an000; dms;
51 jmp cs:IntV13 ;go to old INT 13h vector ;an000; dms;
52
53I13_Handler_Range_Ck:
54
55 call I13_Target_Source_Range_Ck ;crosses the 640k boundary? ;an000; dms;
56 jc I13_Handler_Request_Break ;break up the request ;an000; dms;
57 jmp cs:IntV13 ;go to old INT 13h vector ;an000; dms;
58
59I13_Handler_Request_Break:
60
61 call I13_Request_Break_Up ;break up I13 request ;an000; dms;
62
63 ret 2 ;return to caller ;an000; dms;
64 ;clear the flags from the stack
65 ; and pass back ours
66I13_Handler endp ; ;an000; dms;
67
68
69
70;=========================================================================
71; I13_Target_Source_Range_Ck - This routine determines if the
72; target or source resides in an EMS
73; page.
74;
75; Inputs : ES:BX - Source/target address
76;
77; Outputs : CY - if address resides in an EMS page
78; NC - address not in an EMS page
79;=========================================================================
80
81
82I13_Target_Source_Range_Ck proc near ; ;an000; dms;
83
84 push ax ;save regs ;an000; dms;
85 push bx ; ;an000; dms;
86 push cx ; ;an000; dms;
87 push si ; ;an000; dms;
88 push ds ; ;an000; dms;
89
90 mov ax,cs ;get cs addressibility ;an000; dms;
91 mov ds,ax ; ;an000; dms;
92 mov si,offset cs:Map_Table ;point to the map table ;an000; dms;
93
94 mov cx,cs:Map_Count ;get the number of phys. pages ;an000; dms;
95
96I13_Target_Source_Loop:
97
98 cmp cx,0 ;at end? ;an000; dms;
99 je I13_Target_Source_Not_EMS_Page ;yes - source/target not in pg ;an000; dms;
100
101 mov ax,ds:[si].Phys_Page_Segment ;get the segment value ;an000; dms;
102 mov bx,es ; ;an000; dms;
103 cmp bx,ax ;source/target > EMS page? ;an000; dms;
104 jb I13_Target_Source_Not_EMS_Page ;no - we are OK for old INT 13 ;an000; dms;
105 ;must be >= EMS page
106
107 add ax,400h ;get end address of EMS page ;an000; dms;
108 cmp bx,ax ;source/target < end of EMS pg? ;an000; dms;
109 jb I13_Target_Source_In_EMS_Page ;yes - we are in a page ;an000; dms;
110
111 add si,type Mappable_Phys_Page_Struct ;adjust pointer to next page ;an000; dms;
112 dec cx ;dec counter ;an000; dms;
113
114 jmp I13_Target_Source_Loop ;continue loop ;an000; dms;
115
116I13_Target_Source_Not_EMS_Page:
117
118 clc ;flag not in EMS page ;an000; dms;
119 jmp I13_Target_Source_Exit ;exit routine ;an000; dms;
120
121I13_Target_Source_In_EMS_Page:
122
123 stc ;flag in an EMS page ;an000; dms;
124
125I13_Target_Source_Exit:
126
127 pop ds ;restore regs ;an000; dms;
128 pop si ; ;an000; dms;
129 pop cx ; ;an000; dms;
130 pop bx ; ;an000; dms;
131 pop ax ; ;an000; dms;
132
133 ret ; ;an000; dms;
134
135I13_Target_Source_Range_Ck endp ; ;an000; dms;
136
137
138;=========================================================================
139; I13_Request_Break_Up - Break up the INT 13h request onto 16k
140; boundaries.
141;
142; Inputs : AH - 02 (Read)
143; 03 (Write)
144; AL - Sector count
145; CH - Track number
146; CL - Sector number
147; DH - Head number
148; DL - Drive number
149; ES:BX - Buffer address
150;
151; Outputs : Data transferred
152;=========================================================================
153
154
155I13_Request_Break_Up proc near ; ;an000; dms;
156
157 push bx ;save regs ;an000; dms;
158 push cx ; ;an000; dms;
159 push dx ; ;an000; dms;
160 push di ; ;an000; dms;
161 push si ; ;an000; dms;
162 push ds ; ;an000; dms;
163 push es ; ;an000; dms;
164
165
166 mov cs:I13_Trf_Seg,es ;save segment ;an000; dms;
167 mov cs:I13_Trf_Off,bx ;save offset ;an000; dms;
168 mov cs:I13_Curr_Trf_Cnt,0 ;init transfer count ;an000; dms;
169 mov cs:I13_Operation,ah ;save operation ;an000; dms;
170 mov cs:I13_Sector_Count,al ;save sector count ;an000; dms;
171
172
173 mov byte ptr cs:I13_Track_Number,ch ;save starting track number ;an000; dms;
174 mov ch,cl ;xchg bytes ;an000; dms;
175 shr ch,1 ;shift 6 bits ;an000; dms;
176 shr ch,1 ; ;an000; dms;
177 shr ch,1 ; ;an000; dms;
178 shr ch,1 ; ;an000; dms;
179 shr ch,1 ; ;an000; dms;
180 shr ch,1 ; ;an000; dms;
181
182 mov byte ptr cs:I13_Track_Number[+1],ch ;high byte for cylinder ;an000; dms;
183 and cl,00111111b ;get bits 0-5 for sector number ;an000; dms;
184
185 mov cs:I13_Sector_Number,cl ;save starting sector number ;an000; dms;
186 mov cs:I13_Head_Number,dh ;save starting head number ;an000; dms;
187 mov cs:I13_Drive_Number,dl ;save drive number ;an000; dms;
188
189 mov cl,cs:I13_Sector_Count ;while sectors ;an000; dms;
190
191 cmp cs:I13_Operation,02h ;read? ;an000; dms;
192 jne I13_Request_Write ;must be a write ;an000; dms;
193
194I13_Request_Read:
195
196 cmp cl,0 ;at end? ;an000; dms;
197 je I13_Request_Success ;exit we are done ;an000; dms;
198
199 lea bx,cs:I13_512_Byte_Buffer ;point to 512 byte buffer ;an000; dms;
200 mov ax,cs ;pass cs to es ;an000; dms;
201 mov es,ax ; ;an000; dms;
202
203 call I13_Invoke ;do the INT 13h to our buffer ;an000; dms;
204 jc I13_Request_Failed ;signal failure ;an000; dms;
205 mov ax,cs ;point to our buffer to the ;an000; dms;
206 mov ds,ax ; transfer ;an000; dms;
207 mov si,offset cs:I13_512_Byte_Buffer; ;an000; dms;
208
209 mov es,cs:I13_Trf_Seg ;restore seg to target ;an000; dms;
210 mov di,cs:I13_Trf_Off ;restore off to target ;an000; dms;
211
212 push cx ;save cx across move ;an000; dms;
213 cld ;do a forward move ;an000; dms;
214 mov cx,cs:I13_DD_Per_Sector ; for 128 dd's ;an000; dms;
215 db 66h ;op code for dd word move ;an000; dms;
216 rep movsw ;do the move - wow that was fast;an000; dms;
217 pop cx ;restore it ;an000; dms;
218
219 call I13_Adjust ;adjust our pointers ;an000; dms;
220
221 dec cl ;decrease sector counter ;an000; dms;
222 jmp I13_Request_Read ;continue loop ;an000; dms;
223
224I13_Request_Write:
225
226 cmp cl,0 ;at end? ;an000; dms;
227 je I13_Request_Success ;exit we are done ;an000; dms;
228
229 mov ax,cs ;point to 512 byte buffer ;an000; dms;
230 mov es,ax ; ;an000; dms;
231 mov di,offset cs:I13_512_Byte_Buffer; ;an000; dms;
232
233 mov ds,cs:I13_Trf_Seg ;get source segment ;an000; dms;
234 mov si,cs:I13_Trf_Off ;get source offset ;an000; dms;
235
236 push cx ;save cx across move ;an000; dms;
237 cld ;do a forward move ;an000; dms;
238 mov cx,cs:I13_DD_Per_Sector ; for 128 dd's ;an000; dms;
239 db 66h ;op code for dd word move ;an000; dms;
240 rep movsw ;do the move - wow that was fast;an000; dms;
241 pop cx ;restore it ;an000; dms;
242
243 lea bx,cs:I13_512_Byte_Buffer ;point to 512 byte buffer ;an000; dms;
244 mov ax,cs ;pass cs to es ;an000; dms;
245 mov es,ax ; ;an000; dms;
246
247 call I13_Invoke ;do the INT 13h to our buffer ;an000; dms;
248 jc I13_Request_Failed ;signal failure ;an000; dms;
249 call I13_Adjust ;adjust our pointers ;an000; dms;
250
251 dec cl ;decrease sector counter ;an000; dms;
252 jmp I13_Request_Write ;continue loop ;an000; dms;
253
254I13_Request_Failed:
255
256 jmp I13_Request_Exit ;exit on error ;an000; dms;
257
258
259I13_Request_Success:
260
261 xor ax,ax ;clear status byte ;an000; dms;
262
263I13_Request_Exit:
264
265 pop es ;restore regs ;an000; dms;
266 pop ds ; ;an000; dms;
267 pop si ; ;an000; dms;
268 pop di ; ;an000; dms;
269 pop dx ; ;an000; dms;
270 pop cx ; ;an000; dms;
271 pop bx ; ;an000; dms;
272
273
274 ret ; ;an000; dms;
275
276I13_Request_Break_Up endp ; ;an000; dms;
277
278
279
280;=========================================================================
281; I13_Adjust - This routine adjusts the needed fields for
282; the next iteration of INT 13h.
283;
284; Inputs : I13_Sectors_To_Trf - Sectors just read/written
285; I13_Sector_Number - Starting sector number for trf
286; I13_Head_Number - Starting head number for trf
287; I13_Track_Number - Starting track number for trf
288;
289; Outputs : I13_Sector_Number - New starting sector for trf
290; I13_Head_Number - New starting head for trf
291; I13_Track_Number - New starting track for trf
292;=========================================================================
293
294
295I13_Adjust proc near ;adjust values ;an000; dms;
296
297 push ax ;save regs ;an000; dms;
298
299 inc cs:I13_Sector_Number ;next sector ;an000; dms;
300 mov al,cs:I13_Sector_Number ; ;an000; dms;
301 cmp al,cs:I13_SPT ;> sectors on track? ;an000; dms;
302 jna I13_Adjust_Exit ;no ;an000; dms;
303 mov cs:I13_Sector_Number,1 ;yes - start at next ;an000; dms;
304 inc cs:I13_Head_Number ;next head ;an000; dms;
305 mov al,cs:I13_Head_Number ; ;an000; dms;
306 cmp al,cs:I13_Max_Head ;> head count ;an000; dms;
307 jb I13_Adjust_Exit ;no ;an000; dms;
308 mov cs:I13_Head_Number,0 ;yes - head 0 ;an000; dms;
309 inc cs:I13_Track_Number ;next track ;an000; dms;
310
311I13_Adjust_Exit:
312
313 mov ax,cs:I13_Paras_Per_Sector ;get bytes per sector ;an000; dms;
314 add cs:I13_Trf_Seg,ax ;adjust segment ;an000; dms;
315
316 pop ax ;restore regs ;an000; dms;
317
318 ret ; ;an000; dms;
319
320I13_Adjust endp ; ;an000; dms;
321
322
323;=========================================================================
324; I13_Invoke - This routine sets up the regs for the INT 13h
325; and invokes it for the sector we need.
326;
327; Inputs : I13_Operation - read/write
328; I13_Track_Number - cylinder to read/write
329; I13_Sector_Number - starting sector for read/write
330; I13_Head_Number - starting head
331; I13_Drive_Number - starting drive
332;
333; Outputs : NC - good read/write
334; CY - bad read/write
335;=========================================================================
336
337I13_Invoke proc near ;invoke INT 13h ;an000; dms;
338
339 push bx ;save regs ;an000; dms;
340 push cx ; ;an000; dms;
341 push dx ; ;an000; dms;
342
343 mov ah,cs:I13_Operation ;get function call ;an000; dms;
344 mov al,cs:I13_Sectors_To_Trf ;get sectors to transfer ;an000; dms;
345
346 mov ch,byte ptr cs:I13_Track_Number ;get track number ;an000; dms;
347 mov cl,byte ptr cs:I13_Track_Number[+1] ;get high 2 bits ;an000; dms;
348 shl cl,1 ;put bit is positions 6&7 ;an000; dms;
349 shl cl,1 ; ;an000; dms;
350 shl cl,1 ; ;an000; dms;
351 shl cl,1 ; ;an000; dms;
352 shl cl,1 ; ;an000; dms;
353 shl cl,1 ; ;an000; dms;
354 or cl,cs:I13_Sector_Number ;place the sector number in cl ;an000; dms;
355
356 mov dh,cs:I13_Head_Number ;get head number ;an000; dms;
357 mov dl,cs:I13_Drive_Number ;get drive number ;an000; dms;
358 pushf
359 call cs:IntV13 ;go to old vector ;an000; dms;
360 inc cs:I13_Curr_Trf_Cnt ;increment counter ;an000; dms;
361
362 pop dx ;restore regs ;an000; dms;
363 pop cx ; ;an000; dms;
364 pop bx ; ;an000; dms;
365
366 ret ; ;an000; dms;
367
368I13_Invoke endp ; ;an000; dms;
369
370
371;=========================================================================
372; I13_Get_Dev_Parms - This routine obtains the device parameters for
373; the drive being accessed for the INT 13h.
374;
375; Inputs : DL - drive number
376;
377; Outputs : I13_Max_Head - max head count on drive
378; I13_SPT - max sectors/track count for drive
379; CY - error
380; NC - no error
381;=========================================================================
382
383
384
385I13_Get_Dev_Parms proc near ;get sectors/track & head cnt. ;an000; dms;
386
387 push ax ;save regs ;an000; dms;
388 push bx ; ;an000; dms;
389 push cx ; ;an000; dms;
390 push dx ; ;an000; dms;
391 push di ; ;an000; dms;
392 push ds ; ;an000; dms;
393
394 mov ax,0803h ;get the BDS table ;an000; dms;
395 int 2fh ; ;an000; dms;
396
397I13_Get_Dev_Next_Entry:
398
399 cmp ds:[di].Drivenum,dl ;do we have our drive? ;an000; dms;
400 je I13_Get_Dev_Save_Parms ;yes get data ;an000; dms;
401 cmp word ptr ds:[di].Link[+0],-1 ;last entry in list? ;an000; dms;
402 je I13_Get_Dev_Parms_Error_Exit ;yes - did not find drive ;an000; dms;
403 mov ax,word ptr ds:[di].Link[+0] ;get offset of next entry ;an000; dms;
404 mov bx,word ptr ds:[di].Link[+2] ;get segment of next entry ;an000; dms;
405 mov ds,bx ;stuff into ds:di ;an000; dms;
406 mov di,ax ; ;an000; dms;
407 jmp I13_Get_Dev_Next_Entry ;continue ;an000; dms;
408
409I13_Get_Dev_Save_Parms:
410
411 mov ax,ds:[di].BytePerSec ;get byte count per sector ;an000; dms;
412 mov cs:I13_BPS,ax ; ;an000; dms;
413
414 xor dx,dx ;clear high word ;an000; dms;
415 div cs:I13_Bytes_Per_Para ;get number of paras in sector ;an000; dms;
416 mov cs:I13_Paras_Per_Sector,ax ;save it ;an000; dms;
417 shl ax,1 ;get DD's per sector ;an000; dms;
418 shl ax,1 ; ;an000; dms;
419 mov cs:I13_DD_Per_Sector,ax ; ;an000; dms;
420
421 mov ax,ds:[di].SecLim ;get sectors per track ;an000; dms;
422 mov cs:I13_SPT,al ; ;an000; dms;
423
424 mov ax,ds:[di].HdLim ;get max head count ;an000; dms;
425 mov cs:I13_Max_Head,al ; ;an000; dms;
426
427 clc ;flag data found ;an000; dms;
428
429 jmp I13_Get_Dev_Parms_Exit ; ;an000; dms;
430
431
432I13_Get_Dev_Parms_Error_Exit:
433
434 stc ;flag no data found ;an000; dms;
435
436I13_Get_Dev_Parms_Exit:
437
438 pop ds ;restore regs ;an000; dms;
439 pop di ; ;an000; dms;
440 pop dx ; ;an000; dms;
441 pop cx ; ;an000; dms;
442 pop bx ; ;an000; dms;
443 pop ax ; ;an000; dms;
444
445 ret ; ;an000; dms;
446
447I13_Get_Dev_Parms endp ; ;an000; dms;
448
449
diff --git a/v4.0/src/DEV/XMA2EMS/LIM40.INC b/v4.0/src/DEV/XMA2EMS/LIM40.INC
new file mode 100644
index 0000000..8cd006c
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/LIM40.INC
@@ -0,0 +1,1792 @@
1 page
2;-------------------------------------------------------------------
3;
4; Equates that are specific to LIM 4.0 functions go here
5;
6;-------------------------------------------------------------------
7
8null equ 0 ; null value, used everywhere
9max_phys_pages equ 255 ; largest allowable phys page
10
11sf_pm_get equ 0 ; 4f00 - get partial map
12sf_pm_set equ 1 ; 4f01 - set partial map
13sf_pm_size equ 2 ; 4f02 - get partial map size
14
15mu_ppn equ 0 ; 5000 - map/unmap multiple
16mu_seg equ 1 ; 5001 - map/unmap multiple
17mu_max_fcn equ 1 ; 50 - map/unmap multiple
18
19Hn_Attr_Max_Fcn equ 2 ; 52xx - max subfunction ;an000; dms;
20
21sf_hn_get equ 0 ; 5300 - get handle name
22sf_hn_set equ 1 ; 5301 - set handle name
23hn_max_fcn equ 1 ; 53 - handle name sub-functions 00, 01
24
25sf_hd_get equ 0 ; 5400 - get handle dir
26sf_hd_search equ 1 ; 5401 - search for named handle
27sf_hd_total equ 2 ; 5402 - get total number of handles
28hd_max_fcn equ 2 ; 54 - get handle directory s-f's 00, 01, 02
29
30Add_Get_Array equ 0 ; 5800 - Get Mappable Physical Address Array
31Add_Get_Size equ 1 ; 5801 - Get Mappable Physical Address Array Entries
32
33hi_info equ 0 ; 5900 - hardware info
34hi_raw equ 1 ; 5901 - # raw pages
35
36am_get equ 0 ; 5b00 - get alternate map register set
37am_set equ 1 ; 5b01 - set alternate map register set
38am_size equ 2 ; 5b02 - get alternate map save array size
39am_alloc equ 3 ; 5b03 - allocate alternate map register set
40am_dealloc equ 4 ; 5b04 - deallocate alternate map register set
41am_dma_alloc equ 5 ; 5b05 - allocate DMA register set
42am_dma_enable equ 6 ; 5b06 - enable DMA register set
43am_dma_disable equ 7 ; 5b07 - disable DMA register set
44am_dma_dealloc equ 8 ; 5b08 - deallocate DMA register set
45
46os_enable equ 0 ; 5d00 - enable OS/E function
47os_disable equ 1 ; 5d01 - disable OS/E function
48os_access equ 2 ; 5d02 - "return" access key function
49
50map_pages_fcn equ 44h ; function code used to map pages
51get_free_pages equ 42h ; function code used to get free page count
52
53read_clock equ 2ch ; function code to read clock
54dos_int equ 21h ; interrupt 21
55xor_mask equ 0ffffh ; mask used to confuse the random numbers a little
56
57ppm_struct STRUC ; define the structure
58phys_page_offset dw ? ; offsets into PPM entry
59ppm_handle_offset dw ?
60ppm_log_page_offset dw ?
61ppm_struct ENDS
62
63 page
64;-------------------------------------------------------------------
65;
66; 4F - get/set partial page map
67;
68; INPUT:
69; AL = 00, get partial page map pm_get
70; 01, set partial page map pm_set
71; 02, get partial page map size pm_size
72;
73; OUTPUT:
74; See individual function headers
75;
76;-------------------------------------------------------------------
77partial_map proc
78
79; use AL value to select sub-function
80
81 cmp al,sf_pm_get ; al = 00, get partial page map
82 je pm_get
83
84 cmp al,sf_pm_set ; al = 01, set partial page map
85 je pm_set
86
87 cmp al,sf_pm_size ; al = 02, get partial page map size
88 jne pm_invalid_sfcn
89 jmp pm_size
90
91
92; invalid sub-function, report the error
93
94pm_invalid_sfcn:
95 mov ah,ems_code8F ; invalid sub-function code
96 ret
97
98 page
99;-------------------------------------------------------------------
100;
101; 4F00 - get partial page map
102;
103; INPUT:
104; DS:SI -> partial page map
105;
106; dw ? ; segment count (number
107; ; of following entries)
108; dw ? ; segment address to save
109; : ; (repeats count times)
110; :
111;
112; ES:DI -> user array for mapping info
113; size determined by function 4F02
114;
115;
116; OUTPUT:
117; AH = 00, No error
118; 80H, Software error
119; 81H, Hardware error
120; 84H, Invalid function
121; 8FH, Invalid sub-function
122; A3H, Contents of control structure are invalid
123;
124; ES:DI -> saved partial state array
125; format for this is un-disclosed to the user
126; but will be:
127;
128; ppm_count dw ? ; number of saved entries
129; ppm_phys_page dw ? ; physical page
130; ppm_handle dw ? ; handle
131; ppm_log_page dw ? ; logical page
132; : ; repeats for each requested page
133; :
134;
135;
136;-------------------------------------------------------------------
137pm_get:
138
139 push bx ; save some regs
140 push cx
141 push dx
142 push di
143 push si
144 push ds
145
146 mov di,cs:[bp].IE_Saved_DI_Reg ; restore caller's DI, pointer to mapping control structure
147
148
149;-------------------------------------------------------------------
150
151; get count from caller's control structure
152
153 mov cx,ds:[si] ; the first word of the control
154 ; structure holds the # of entries
155
156 cmp cx,0 ; 0 pages requested? ;an000; dms;
157 je PM_Get_Error_A3 ; yes - flag an error ;an000; dms;
158
159 cmp cx,cs:Map_Count ; do some sanity checking
160 jbe pm_phys_ok ; requested number is ok, do the copies
161
162; They asked for more than we can possibly have. Sounds like trouble.
163
164PM_Get_Error_A3:
165
166 mov ah,ems_codea3 ; bad stuff in the control structure
167 jmp pm_exit00 ; return the error code
168
169pm_phys_ok:
170 mov cx,DS:word ptr [si] ; get count from control structure
171 mov ES:word ptr [di],cx ; save count in save area
172 add di,2 ; increment save area pointer
173
174;-------------------------------------------------------------------
175;
176; everything is OK so far, copy the entries requested
177;
178;-------------------------------------------------------------------
179
180ppm_copies:
181
182 add si,2 ; point to next segment number
183 mov ax,DS:word ptr [si] ; get segment value from control structure
184
185 push si ; save user's si
186 push ds ; save user's ds
187 push cx ; save counter for outer loop
188
189; ready to do the lookup and copy operation
190
191 push cs ; make DS:SI point to internal data area
192 pop ds
193 lea si,map_table
194
195 mov cx,map_count ; number of mappable segments
196
197ppm_inner_copy_loop:
198 cmp ax,ds:word ptr [si+phys_page_segment] ; is this entry the requested?
199 jne ppm_not_yet ; no, try again
200
201 mov cx,ppm_size ; number of bytes to copy
202 cld ; make sure direction flag is right
203 add si,2 ; point to phys_page_number
204
205 rep movsb ; copy the entry
206
207 sub si,2 ; reset si
208
209 jmp ppm_entry_done ; done with this copy, go on
210
211ppm_not_yet:
212 add si,type mappable_phys_page_struct ; point to next entry
213 loop ppm_inner_copy_loop ; try some more
214
215 pop cx ; restore counter for outer loop
216 pop ds ; restore user's ds
217 pop si ; restore user's si
218 mov ah,EMS_Code8B ; we have an invalid segment specified ;an000; dms;
219 jmp PM_Exit00 ; exit the program
220
221ppm_entry_done:
222
223; restore pointer to control structure
224
225 pop cx ; restore counter for outer loop
226 pop ds ; restore user's ds
227 pop si ; restore user's si
228
229
230 loop ppm_copies ; keep going until proper number of
231 ; entries have been copied
232
233 xor ah,ah ; good return code
234;-------------------------------------------------------------------
235pm_exit00:
236 pop ds ; restore these registers
237 pop si
238 pop di
239 pop dx
240 pop cx
241 pop bx
242
243 ret ; return to caller
244
245
246
247 page
248;-------------------------------------------------------------------
249;
250; 4F01 - set partial page map
251;
252; INPUT:
253; DS:SI -> source array
254; Format:
255;
256; ppm_count dw ? ; number of saved entries
257; ppm_phys_page dw ? ; physical page
258; ppm_handle dw ? ; handle
259; ppm_log_page dw ? ; logical page
260; : ; repeats ppm_count times
261; :
262;
263;
264; OUTPUT:
265; AH = 00, No error
266; 80H, Software error
267; 81H, Hardware error
268; 84H, Invalid function
269; 8FH, Invalid sub-function
270; A3H, Contents of source array invalid
271;
272;-------------------------------------------------------------------
273pm_set:
274
275 push bx ; save some regs
276 push cx
277 push dx
278 push di
279 push si
280 push ds
281
282 mov cx,DS:word ptr [si] ; get number of entries in save area
283
284 cmp cx,0 ; is the count zero?
285 je pm_set_error_A3 ; yes - error ;an000; dms;
286
287 cmp cx,cs:Map_Count ; greater than phys pages avail? ;an000; dms;
288 jbe count_ok ; no - data not corrupted ;an000; dms;
289
290pm_set_error_A3:
291
292 mov ah,EMS_CODEA3 ; control structure error
293 jmp pm_exit01 ; exit
294
295count_ok:
296 add si,2 ; point to first entry in save area
297
298pm01_loop:
299
300 mov ax,DS:word ptr [si+phys_page_offset] ; set up regs for map_l_to_p
301 mov ah,map_pages_fcn
302 mov dx,DS:word ptr [si+ppm_handle_offset]
303 mov bx,DS:word ptr [si+ppm_log_page_offset]
304
305 cmp dx,0ffffh ; is there a real entry?
306 je no_map ; no, skip the call to map_l_to_p
307
308 call map_l_to_p ; make the mapping call
309
310no_map:
311 add si,type ppm_struct ; point to next entry
312
313 loop pm01_loop ;
314
315 xor ah,ah ; good return code
316pm_exit01:
317
318 pop ds ; restore these registers
319 pop si
320 pop di
321 pop dx
322 pop cx
323 pop bx
324
325 ret ; return to caller
326
327
328 page
329;-------------------------------------------------------------------
330;
331; 4F02 - get partial page map size
332;
333; INPUT:
334; AX = 4f02h
335;
336; BX = number of pages in partial page map
337;
338; OUTPUT:
339; AH = 00, No error
340; 80H, Software error
341; 81H, Hardware error
342; 84H, Invalid function
343; 8FH, Invalid sub-function
344;
345; AL = size of partial page map save array
346; number of bytes that will be needed
347; to save the requested number of pages
348;
349;-------------------------------------------------------------------
350pm_size:
351
352 push dx ; save dx
353
354 cmp bx,0 ; 0 pages requested? ;an000; dms;
355 je PM_Size_Error_8B ; yes flag an error ;an000; dms;
356
357 cmp bx,cs:Map_Count ; page count > phys pages? ;an000; dms;
358 jbe PM_Size_Return ; no - continue ;an000; dms;
359
360PM_Size_Error_8B:
361
362 mov ah,EMS_Code8B ; signal page count exceeded ;an000; dms;
363 jmp PM_Exit02 ; exit routine ;an000; dms;
364
365PM_Size_Return:
366
367 mov dx,bx ; number of pages times ...
368 mov ax,ppm_size ; * size of an entry ...
369 mul dx ; = number of bytes in save array
370 add ax,2 ; increase by 2 to include count word
371
372 xor ah,ah ; good return code
373
374pm_exit02:
375 pop dx ; restore dx
376
377 ret ; return to caller
378
379partial_map endp
380
381
382 page
383;-------------------------------------------------------------------
384;
385; 50 - map/unmap multiple handle pages
386;
387; INPUT:
388; AH = 00 physical page numbers
389; 01 segment numbers
390;
391;-------------------------------------------------------------------
392map_mult proc
393
394 cmp al,mu_ppn ; is this a map request?
395 je mu_ppn_fcn ; yes, go do it
396
397 cmp al,mu_seg ; no, is this an unmap request?
398 je mu_seg_fcn ; yes, go do it
399
400 xor al,al ; clear al, why not?
401 mov ah,ems_code8f ; no, return invalid sub-function code
402 ret ; return to caller
403
404;-------------------------------------------------------------------
405;
406; 5000 - map/unmap multiple handle pages using physical page numbers
407;
408; INPUT:
409; AX = 5000h
410;
411; DX = handle
412;
413; CX = num entries in control structure
414;
415; DS:SI -> points to control structure
416; Format:
417;
418; log_pg_num dw ? ; logical page number
419; phys_pg_num dw ? ; physical page number
420; : ; repeats CX times
421; :
422;
423; OUTPUT:
424;
425; AH = 00, No error
426; 80H, Software error
427; 81H, Hardware error
428; 83H, Invalid handle
429; 84H, Invalid function
430; 8AH, Invalid logical page
431; 8BH, Invalid physical page
432; 8FH, Invalid sub-function
433;
434;-------------------------------------------------------------------
435
436mu_ppn_fcn:
437
438 push bx ; save regs ;an000; dms;
439 push cx ; save count
440 push dx ; ;an000; dms;
441 push si ; save pointer
442
443 xor ah,ah ; good return code
444 cmp cx,0 ; is count 0?
445 je mu_ppn_exit
446
447mu_ppn_loop:
448 mov bx,ds:word ptr[si+0] ; get logical page number
449 mov ax,ds:word ptr[si+2] ; get physical page number
450 mov ah,map_pages_fcn ; fcn code for mapping
451
452 push cx
453 call map_l_to_p ; call the mapping routine
454 pop cx
455
456 cmp ah,0 ; was return code OK
457 jne mu_ppn_error
458
459 add si,4 ; point to next entry
460
461 loop mu_ppn_loop ; do it again
462
463 xor ah,ah ; good return code
464 jmp mu_ppn_exit
465
466mu_ppn_error:
467mu_ppn_exit:
468 pop si ; restore pointer
469 pop dx ; ;an000; dms;
470 pop cx ; restore count
471 pop bx ; restore regs ;an000; dms;
472
473 ret ; return to caller
474
475
476;-------------------------------------------------------------------
477;
478; 5001 - map/unmap multiple handle pages using segment addresses
479;
480; INPUT:
481; AX = 5001h
482;
483; DX = handle
484;
485; CX = num entries in control structure
486;
487; DS:SI -> points to control structure
488; Format:
489;
490; log_pg_num dw ? ; logical page number
491; seg_address dw ? ; physical segment address
492; : ; repeats CX times
493; :
494;
495; OUTPUT:
496;
497; AH = 00, No error
498; 80H, Software error
499; 81H, Hardware error
500; 83H, Invalid handle
501; 84H, Invalid function
502; 8AH, Invalid logical page
503; 8BH, Invalid physical page
504; 8FH, Invalid sub-function
505;
506;-------------------------------------------------------------------
507
508mu_seg_fcn:
509
510 push bx ; save regs ;an000; dms;
511 push cx ; save count
512 push dx ; ;an000; dms;
513 push si ; save pointer
514
515 xor ah,ah ; good return code
516 cmp cx,0 ; is count 0?
517 je mu_seg_exit
518
519mu_seg_loop:
520 mov bx,ds:word ptr[si+0] ; get logical page number
521
522 push dx ; save handle
523 mov dx,ds:word ptr[si+2] ; get physical page number
524 call Get_Phys_Seg_Page ; convert to logical page circle
525 mov ax,dx ; must be in AX
526 pop dx ; restore handle
527
528 mov ah,map_pages_fcn ; fcn code for mapping
529
530 push cx
531 call map_l_to_p ; call the mapping routine
532 pop cx
533
534 cmp ah,0 ; was return code OK
535 jne mu_seg_error
536
537 add si,4 ; point to next entry
538
539 loop mu_seg_loop ; do it again
540
541 xor ah,ah ; good return code
542 jmp mu_seg_exit
543
544mu_seg_error:
545mu_seg_exit:
546 pop si ; restore pointer
547 pop dx ; ;an000; dms;
548 pop cx ; restore count
549 pop bx ; restore regs ;an000; dms;
550
551 ret ; return to caller
552
553map_mult endp
554
555;-------------------------------------------------------------------
556include lim40b.inc
557;-------------------------------------------------------------------
558
559 page
560;-------------------------------------------------------------------
561;
562; 52 - get/set handle attributes
563;
564; The LIM 4.0 spec strongly advises EMS implementers to avoid this
565; call. Our current implementation of this function is not to provide
566; support. Possibly in future releases it will be supported, if
567; the proper hardware becomes available.
568;
569; DMS 4/29/88
570;
571;-------------------------------------------------------------------
572handle_attrib proc
573
574
575 cmp al,Hn_Attr_Max_Fcn ;maximum subfunction number ;an000; dms;
576 jbe Handle_Attrib_Cont ;continue routine ;an000; dms;
577 mov ah,EMS_Code8F ;we have an invalid subfunction ;an000; dms;
578 jmp Handle_Attrib_Exit ; exit the routine ;an000; dms;
579
580Handle_Attrib_Cont:
581
582 mov ah,EMS_Code91 ;this function is not supported ;an000; dms;
583
584Handle_Attrib_Exit:
585
586 RET ; return to caller
587
588handle_attrib endp
589
590 page
591;-------------------------------------------------------------------
592;
593; 53 - get/set handle name
594;
595; Virtual Mode Note: The Handle Name functions (53 and 54) will @RH6
596; be handled differently when running on a system in virtual mode. @RH6
597; This is to accommadate the Workstation Program's bank switching. @RH6
598; In this case, handle names and ID's will only be returned for @RH6
599; handles allocated in the same PC bank, or for handles in bank 0. @RH6
600; Bank 0 is for device drivers, system extensions, or applications @RH6
601; that install resident before WSP loads. @RH6
602; When interfacing with handles in bank 0, one must be aware of @RH6
603; the problem of two PC applications running simultaneously that @RH6
604; get the handle ID of the resident program and map its pages. @RH6
605; Data corruption will occur if both map and write to the same page @RH6
606; at the same time. @RH6
607; While these new LIM 4.0 functions will return info only for @RH6
608; bank 0 and the current bank, the existing LIM 3.2 functions will @RH6
609; continue to return total system values. For example, function 4B @RH6
610; will return the number of active handles in all banks. @RH6
611;
612; INPUT:
613; AL = sub-function code
614; 00 = get handle name hn_get
615; 01 = set handle name hn_set
616;
617; DX = handle
618;
619; ES:DI -> Get caller's name buffer (8 char's)
620; DS:SI -> Set caller's name buffer (8 char's)
621;
622;
623; OUTPUT:
624; AH = 00, No error
625; 80H, Software error
626; 81H, Hardware error
627; 83H, Handle not found
628; 84H, Invalid function
629; 8FH, Invalid sub-function
630;
631; AL = 0
632;
633;
634; gga 8/21/87
635;
636;-------------------------------------------------------------------
637
638 Null_Handle_Name db 8 dup(0) ;null handle value ;an000; dms;
639
640handle_name proc
641
642 push bx ; save some regs
643 push cx
644 push dx
645 push di
646 push si
647 push ds
648
649 PUSH CS ;Set addressability to our tables @RH8
650 POP DS ;Must restore DS for Set name @RH8
651
652 cmp al,hn_max_fcn ; al = 00 or 01, anything else = error
653 jbe hn_val_sf
654
655; invalid sub-function, report the error
656
657 mov ah,ems_code8F ; invalid sub-function code
658 jmp hn_exit ; exit
659
660; check the handle for valid range
661
662hn_val_sf:
663
664 cmp dx,num_handles-1 ; handle within range ?
665 jnae hn_range_ok ; yes, get down to business
666
667 mov ah,ems_code83 ; handle not found
668 jmp hn_exit ; exit
669
670;------------------------
671; handle is within valid range, now see if it is valid handle (i.e. in use)
672
673hn_range_ok:
674
675 push ax ; save fcn code
676 push dx ; save handle
677
678 MOV AX,DX ;DX = handle id
679 MOV DX,TYPE H_LOOKUP_STRUC ;DI = entry's offset into
680 MUL DX ; the handle lookup table
681 MOV DI,AX ;
682 POP DX ; restore handle
683 POP AX ; restore fcn code
684
685 CMP HANDLE_LOOKUP_TABLE.H_PAGES[DI],REUSABLE_HANDLE
686 JNE HN_IN_USE ;Is this handle valid (in use)?
687 ; No...error
688 mov ah,ems_code83 ; handle not found
689 jmp hn_exit ; return the error code
690
691HN_IN_USE: ;Check bank ID if in virutal mode
692
693 mov bx,ax ;save ax ;an000; dms;
694 TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6
695 JZ HN_VALID ; (i.e. bank swapping), then read @RH6
696 MOV DX,IDREG ; the current bank ID. @RH6
697 IN AL,DX ; @RH6
698 CMP HANDLE_LOOKUP_TABLE.H_BANK[DI],AL ;If handle's bank ID @RH6
699 JE HN_VALID ; is 0 (resident) or @RH6
700 CMP HANDLE_LOOKUP_TABLE.H_BANK[DI],0 ; = requesters bank @RH6
701 JE HN_VALID ; then OK @RH6
702 ;Else invalid requester bank @RH6
703 MOV AH,EMS_CODE83 ;Indicate handle not found @RH6
704 JMP HN_EXIT
705
706;------------------------
707; find out if get or set operation
708
709hn_valid:
710 mov ax,bx ;restore ax ;an000; dms;
711 cmp al,sf_hn_get ; al = 00 means GET
712 je hn_get
713
714 cmp al,sf_hn_set ; = 01 means SET
715 je hn_set
716
717; invalid sub-function, report the error
718
719 mov ah,ems_code8F ; invalid sub-function code
720 jmp hn_exit ; exit
721
722
723
724 page
725;-------------------------------------------------------------------
726;
727; 5300 - GET sub-function
728; ES:DI -> User's area where name is stored
729;-------------------------------------------------------------------
730hn_get:
731 ;Here DI = offset into h lookup
732 LEA SI,HANDLE_LOOKUP_TABLE ;Set the source SI to the handle's
733 ADD SI,DI ; name field in the handle lookup
734 ADD SI,H_NAME ; lookup table
735
736 MOV DI,cs:[bp].IE_Saved_DI_Reg ;Restore the user's dest where
737 ; the handle name will be stored
738
739 MOV CX,8 ; want to copy 8 characters
740 CLD ; make sure direction flag is right
741 REP MOVSB ; copy the string
742
743 XOR AH,AH ; set good return code
744 JMP HN_EXIT ; exit
745
746
747 page
748;-------------------------------------------------------------------
749;
750; 5301 - SET sub-function
751; DS:SI -> User's area where name comes from
752;
753;-------------------------------------------------------------------
754
755hn_set:
756
757 POP DS ;Restore the user's source where @RH6
758 PUSH DS ; the handle name will come from
759
760
761;------------------------
762 push si ;save regs ;an000; dms;
763 push di ; ;an000; dms;
764 push cx ; ;an000; dms;
765 push es ; ;an000; dms;
766
767 push cs ;swap segs for compare ;an000; dms;
768 pop es ; ;an000; dms;
769
770 mov di,offset cs:Null_Handle_Name ;point to null handle name ;an000; dms;
771 mov cx,8 ;8 bytes to compare ;an000; dms;
772 cld
773 cli ;ints off ;an000; dms;
774 rep cmpsb ;null string entered? ;an000; dms;
775 sti ;ints on ;an000; dms;
776
777 pop es ;restore regs ;an000; dms;
778 pop cx ; ;an000; dms;
779 pop di ; ;an000; dms;
780 pop si ; ;an000; dms;
781 je HN_Set_Null_Entered ;continue - don't look for match ;an000; dms;
782
783 push dx
784 call hd_named_handle ; find out if name is in use
785 pop dx
786
787 cmp ah,0 ; is return code good
788 je name_in_use
789
790HN_Set_Null_Entered:
791
792;------------------------
793 ;Here DI = offset into h lookup
794 ADD DI,OFFSET HANDLE_LOOKUP_TABLE ;Set the dest. DI to the @RH6
795 ADD DI,OFFSET H_NAME ; handle's name field in @RH6
796 ; the handle lookup table @RH6
797
798 PUSH ES ;Make ES:DI -> destination in
799 PUSH CS ; the handle lookup table where
800 POP ES ; the name will be stored
801
802 mov cx,8 ; want to copy 8 characters
803 cld ; clear DF to auto-increment
804 rep movsb ; copy the string
805
806; all done with the SET function, set good return code and exit
807
808 pop es ; restore user's ES
809 xor ax,ax ; set good return code
810 jmp hn_exit
811
812
813;------------------------
814name_in_use:
815 mov ah,ems_codea1 ; name is use error
816
817
818hn_exit:
819 pop ds ; restore these registers
820 pop si
821 pop di
822 pop dx
823 pop cx
824 pop bx
825
826 ret
827
828handle_name endp
829
830
831
832 page
833;-------------------------------------------------------------------
834;
835; 54 - get handle directory
836;
837; SUB-FCNS:
838; AL = 00, get handle directory hd_directory
839; 01, search for named handle hd_named_handle
840; 02, get total handles hd_total_handles
841;
842;-------------------------------------------------------------------
843handle_dir proc
844
845 cmp al,sf_hd_get ; 00 get handle dir
846 je hd_directory
847
848 cmp al,sf_hd_search ; 01 search for named handle
849 je hd_named_handle
850
851 cmp al,sf_hd_total ; 02 get total number of handles
852 jne hd_invalid_sfcn ; must be an invalid function code
853
854 jmp hd_total_handles ; go display total handles
855
856
857; invalid sub-function, report the error
858
859hd_invalid_sfcn:
860 mov ah,ems_code8F ; invalid sub-function code
861
862; invalid sub-function, fall through to exit
863
864hd_exit:
865
866 ret
867
868
869;-------------------------------------------------------------------
870; 5400 - get handle directory
871;
872;
873; INPUT:
874; AL = 00, get handle directory
875;
876; ES:DI -> caller's buffer for handle directory
877;
878; OUTPUT:
879; AH = 00H, no error
880; 80H, software error
881; 81H, hardware error
882; 84H, invalid function
883; 8FH, invalid subfunction
884;
885; AL = number of entries in handle directory
886;
887; ES:DI -> handle directory
888;
889; dw ? ; handle number
890; db 8 dup(?) ; handle name
891; :
892; : ; repeats AL times
893;
894;-------------------------------------------------------------------
895hd_directory:
896
897 push bx ; save some regs
898 push cx
899 push dx
900 push di
901 push si
902 push ds
903
904 TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6
905 JZ HD_LOOP_INIT ; (i.e. bank swapping), then read @RH6
906 MOV DX,IDREG ; the current bank ID and save it. @RH6
907 IN AL,DX ; @RH6
908 MOV cs:BANKID,AL
909
910
911; initialize some things for the loop
912HD_LOOP_INIT:
913 mov di,cs:[bp].IE_Saved_DI_Reg ;restore users DI ;an000; dms;
914 xor al,al ; al = num entries
915 xor dx,dx ; dx = handle index
916 mov cx,NUM_HANDLES ; loop enough for all handles
917 cld ; make sure direction flag cleared
918
919 push cs ; get cs
920 pop ds ; into ds
921 XOR SI,SI ; SI = offset into handle lookup @RH6
922 ; table
923hd_loop:
924 CMP HANDLE_LOOKUP_TABLE.h_pages[SI],REUSABLE_HANDLE
925 ; If handle not active, then @RH6
926 je hd_next_hndl ; loop and look again
927;-------------------------
928; Active handle...if in virtual mode check bank ID @RH6
929;-------------------------
930
931 TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6
932 JZ HD_ACTIVE ; (i.e. bank swapping), then check @RH6
933 MOV BL,cs:BANKID ; handle's bank id @RH6
934 CMP HANDLE_LOOKUP_TABLE.H_BANK[SI],BL ;If handle's bank ID @RH6
935 JE HD_Active ; is 0 (resident) or @RH6
936 CMP HANDLE_LOOKUP_TABLE.H_BANK[SI],0 ; = requesters bank @RH6
937 JE HD_Active ; then OK @RH6
938 jmp HD_Next_Hndl ;Else skip to next one @RH6
939
940;------------------------
941; found an active handle, copy info to directory
942;------------------------
943hd_active:
944 mov es:word ptr[di],dx ; put handle number in directory
945 add di,2 ; move directory table pointer along,
946 ; must point to area for handle name now
947
948 push cx ; save counter for outer loop
949 push si ; save si for outer loop
950
951 mov cx,8 ; need to copy 8 chars
952 add si,offset Handle_LookUp_Table ;point to entry ;an000; dms;
953 add si,h_name ; make DS:SI -> handle name in lookup table
954
955rep movsb ; copy the string
956
957 pop si ; restore si for outer loop
958 pop cx ; restore counter for outer loop
959 inc al ; increment entry count
960
961;------------------------
962; done with the copy
963;------------------------
964
965hd_next_hndl:
966 inc dx ; update handle index
967 add si,type h_lookup_struc ; point to next entry in lookup table
968 loop hd_loop ; look for more
969
970 xor ah,ah ; good return code
971
972; all done, fall through to exit
973
974hd_exit00:
975
976 pop ds ;restore these registers
977 pop si
978 pop di
979 pop dx
980 pop cx
981 pop bx
982
983 ret
984
985
986
987 page
988;-------------------------------------------------------------------
989;
990; 5401 - Search for named handle sub-function
991;
992;
993; INPUT:
994; AL = 01, search for named handle
995;
996; DS:SI = Pointer to handle name to search for
997;
998;
999; OUTPUT sub-fcn 01: Search for named handle
1000;
1001; AH = 00H, no error
1002; 80H, software error
1003; 81H, hardware error
1004; 84H, invalid function
1005; 8FH, invalid subfunction
1006; A0H, no matching handle found
1007; A1H, duplicate handle found
1008;
1009; DX = value of named handle
1010;
1011;-------------------------------------------------------------------
1012
1013hd_named_handle:
1014
1015 push bx ; save some regs
1016 push cx
1017 push di
1018 push si
1019 push ds
1020 push es ;an000; dms;
1021
1022 TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6
1023 JZ HD1_LOOP_INIT ; (i.e. bank swapping), then read @RH6
1024 MOV DX,IDREG ; the current bank ID and save it. @RH6
1025 IN AL,DX ; @RH6
1026 MOV cs:BANKID,AL
1027
1028
1029; initialize some things for the loop
1030HD1_LOOP_INIT:
1031 xor ah,ah ; good return code
1032 xor dx,dx ; dx = handle index
1033 mov cx,NUM_HANDLES ; loop enough for all handles
1034 cld ; make sure direction flag cleared
1035
1036 push cs ; get cs
1037 pop es ; into es
1038 XOR DI,DI ; DI = offset into handle lookup @RH6
1039 ; table @RH6
1040hd1_loop:
1041 CMP ES:HANDLE_LOOKUP_TABLE.h_pages[DI],REUSABLE_HANDLE
1042 ; If handle not active, then @RH6
1043 je hd1_next_hndl ; loop and look again
1044;-------------------------
1045; Active handle...if in virtual mode check bank ID @RH6
1046;-------------------------
1047
1048 TEST MEMCARD_MODE,WSP_VIRT ;If using a card in virtual mode @RH6
1049 JZ HD1_ACTIVE ; (i.e. bank swapping), then check @RH6
1050 MOV BL,cs:BANKID ; handle's bank id @RH6
1051 CMP ES:HANDLE_LOOKUP_TABLE.H_BANK[DI],BL ;If handle's bank ID @RH6
1052 JE HD1_Active ; is 0 (resident) or @RH6
1053 CMP ES:HANDLE_LOOKUP_TABLE.H_BANK[DI],0 ; = requesters bank @RH6
1054 JE HD1_Active ; then OK @RH6
1055 jmp HD1_Next_Hndl ;Else skip to next one @RH6
1056;------------------------
1057; found an active handle, check the name
1058;------------------------
1059
1060HD1_ACTIVE:
1061 push cx ; save counter for outer loop
1062 push si ; save si for outer loop
1063 push di ; save di for outer loop
1064
1065 mov cx,8 ; need to compare 8 chars
1066 add di,offset Handle_LookUp_Table ;point to entry ;an000; dms;
1067 add di,offset H_Name ; must point to area for handle name now;an000; dms;
1068
1069rep cmpsb ; compare the strings
1070
1071 pop di ; restore di for outer loop
1072 pop si ; restore si for outer loop
1073 pop cx ; restore counter for outer loop
1074 je hd_exit01 ; found a match, exit
1075
1076;------------------------
1077; done with the check
1078;------------------------
1079
1080hd1_next_hndl:
1081 inc dx ; update handle index
1082 add di,type h_lookup_struc ; point to next entry in lookup table
1083 loop hd1_loop ; look for more
1084
1085
1086
1087; all done, if we fall through loop without finding a match,
1088; must report the error
1089
1090 mov ah,ems_codea0 ; no matching handle
1091 xor dx,dx ; invalid handle
1092
1093hd_exit01:
1094
1095
1096 pop es ;restore these registers ;an000; dms;
1097 pop ds
1098 pop si
1099 pop di
1100 pop cx
1101 pop bx
1102
1103 ret
1104
1105
1106
1107 page
1108;-------------------------------------------------------------------
1109;
1110; 5402 - Get total handles sub-function
1111;
1112; INPUT:
1113; AL = 02, get total handles
1114;
1115;
1116; OUTPUT:
1117; AH = 00H, no error
1118; 80H, software error
1119; 81H, hardware error
1120; 84H, invalid function
1121; 8FH, invalid subfunction
1122;
1123; BX = total number of handles (includes OS handle, 0)
1124;
1125;-------------------------------------------------------------------
1126
1127hd_total_handles:
1128
1129 mov bx,NUM_HANDLES ; return number of handles
1130 xor ah,ah ; good return code
1131
1132; all done, fall through to exit
1133
1134hd_exit02:
1135
1136 ret ; return to caller
1137
1138handle_dir endp
1139
1140 page
1141;-------------------------------------------------------------------
1142;
1143; 58 - Get mappable physical address array
1144;
1145;
1146; INPUT:
1147; AX = 5800h
1148;
1149; ES:DI -> mappable physical array address
1150;
1151; OUTPUT:
1152; AH = 00, no error
1153; 80H, software error
1154; 81H, hardware error
1155; 84H, invalid function
1156; 8FH, invalid subfunction
1157;
1158; CX = number of entries returned in the table below
1159;
1160; ES:DI -> DW ? ; phys_page_segment
1161; DW ? ; phys_page_number
1162; :
1163; : ; repeats CX times
1164;
1165;-------------------------------------------------------------------
1166address_array proc
1167
1168 cmp al,Add_Get_Array ; subfunction 00 Get Mappable Physical ;an000; dms;
1169 ; Address Array
1170 je Address_Get_Physical_Address
1171
1172 cmp al,Add_Get_Size ; subfunction 01 Get Mappable Physical ;an000; dms;
1173 ; Address Array Entries
1174 je Address_Get_Size_Entries
1175
1176 mov ah,EMS_Code8F ; none of the above - invalid sub parm ;an000; dms;
1177
1178 ret
1179
1180
1181Address_Get_Physical_Address:
1182
1183 push si ; save some regs
1184 push di ; save di ;an000; dms;
1185 push ds ; save DS
1186
1187
1188; set up some things for the loop
1189
1190 mov di,cs:[bp].IE_Saved_DI_Reg ; restore caller's DI, pointer to handle area
1191
1192 mov cx,map_count ; number of entries in table
1193
1194 push cs ; make DS:SI -> array
1195 pop ds
1196
1197 lea si,map_table
1198
1199 cld ; make sure direction flag is right
1200
1201copy_address_array:
1202
1203 mov ax,DS:[si+phys_page_segment]
1204 mov ES:[di],ax
1205 add di,2 ; increment destination pointer
1206 mov ax,DS:[si+phys_page_number]
1207 mov ES:[di],ax
1208
1209 add si,type mappable_phys_page_struct ; increment pointer
1210 add di,2 ; increment destination pointer
1211
1212 loop copy_address_array
1213
1214 mov cx,map_count ; number of entries
1215 xor ah,ah ; good return code
1216
1217 pop ds ; restore DS
1218 pop di ; restore di
1219 pop si ; restore SI
1220
1221 RET ; return to caller
1222
1223Address_Get_Size_Entries:
1224
1225 mov cx,cs:Map_Count ; return the number of pages allocated ;an000; dms;
1226 xor ax,ax ; clear error flag ;an000; dms;
1227 ret ; return to caller ;an000; dms;
1228
1229
1230address_array endp
1231
1232
1233
1234 page
1235;-------------------------------------------------------------------
1236;
1237; 59 - Get extended momory hardware information
1238;
1239;-------------------------------------------------------------------
1240hardware_info proc
1241
1242 cmp ose_functions,ose_enabled ; first, check for fcns enabled
1243 je hi_enabled ;
1244
1245
1246 mov ah,EMS_CODEA4 ; access denied
1247 jmp hi_exit ; exit
1248
1249hi_enabled:
1250 cmp al,hi_info ; 5900 - hardware info fcn
1251 je hi_info_fcn
1252
1253 cmp al,hi_raw ; 5901 - unallocated raw page count
1254 je hi_raw_fcn
1255
1256 mov ah,EMS_CODE8F ; invalid sub-function
1257
1258hi_exit:
1259 RET ; return to caller
1260
1261
1262 page
1263;-------------------------------------------------------------------
1264;
1265; hi_info_fcn
1266;
1267;-------------------------------------------------------------------
1268
1269hi_info_fcn:
1270
1271 mov di,cs:[bp].IE_Saved_DI_Reg ; get di register
1272
1273 mov es:word ptr[di+0],1024 ; raw page size = 16KB
1274 mov es:word ptr[di+2],0 ; number of alternate register sets
1275 mov es:word ptr[di+4],type H_SAVE_STRUC ; size of save array
1276 mov es:word ptr[di+6],0 ; number of DMA register sets
1277 mov es:word ptr[di+8],1 ; 1 = no special DMA register sets
1278
1279 xor ah,ah ; good return code
1280 ret ; return to caller
1281
1282 page
1283;-------------------------------------------------------------------
1284;
1285; hi_raw_fcn
1286;
1287;-------------------------------------------------------------------
1288
1289hi_raw_fcn:
1290
1291 mov ah,get_free_pages ; function code to get free pages
1292
1293 call q_pages ; pass this one through, since our
1294 ; raw pages = 16 KB
1295 ; this fcn returns exacly the same
1296 ; regs as are needed here
1297
1298 ret ; return to caller
1299
1300hardware_info endp
1301
1302 page
1303;-------------------------------------------------------------------
1304;
1305; 5B - alternate map register set
1306;
1307;-------------------------------------------------------------------
1308
1309 AM_ES_Save dw 0 ;ES save variable ;an000; dms;
1310 AM_DI_Save dw 0 ;DI save variable ;an000; dms;
1311 AM_Set_Flag db 0 ;set called flag ;an000; dms;
1312
1313alternate_map proc
1314
1315 cmp ose_functions,ose_enabled ; first, check for fcns enabled
1316 je am_enabled ;
1317
1318
1319 mov ah,EMS_CODEA4 ; access denied
1320 jmp am_exit ; exit
1321
1322am_enabled:
1323 cmp al,am_get ; 5b00 - get alternate map register set
1324 je _am_get
1325
1326 cmp al,am_set ; 5b01 - set alternate map register set
1327 je _am_set
1328
1329 cmp al,am_size ; 5b02 - get alternate map save array size
1330 je _am_size
1331
1332 cmp al,am_alloc ; 5b03 - allocate alternate map register set
1333 je _am_alloc
1334
1335 cmp al,am_dealloc ; 5b04 - deallocate alternate map register set
1336 je _am_dealloc
1337
1338 cmp al,am_dma_alloc ; 5b05 - allocate DMA register set
1339 je _am_dma_alloc
1340
1341 cmp al,am_dma_enable ; 5b06 - enable DMA register set
1342 je _am_dma_enable
1343
1344 cmp al,am_dma_disable ; 5b07 - disable DMA register set
1345 je _am_dma_disable
1346
1347 cmp al,am_dma_dealloc ; 5b08 - deallocate DMA register set
1348 je _am_dma_dealloc
1349
1350 mov ah,EMS_CODE8F ; invalid sub-function
1351
1352am_exit:
1353 ret ; return to caller
1354
1355
1356 page
1357;-------------------------------------------------------------------
1358;
1359; _am_get
1360;
1361;-------------------------------------------------------------------
1362_am_get:
1363
1364 cmp cs:AM_Set_Flag,0 ;flag set? ;an000; dms;
1365 jne AM_Get_Continue ;yes ;an000; dms;
1366 xor di,di ;signal set has not ;an000; dms;
1367 mov es,di ; been performed ;an000; dms;
1368 xor ah,ah ;signal good exit ;an000; dms;
1369 jmp AM_Get_Exit ;exit routine ;an000; dms;
1370
1371AM_Get_Continue:
1372
1373 mov di,cs:AM_DI_Save
1374 mov es,cs:AM_ES_Save
1375 mov cs:[bp].IE_Saved_DI_Reg,di;set instance table entry ;an000; dms;
1376
1377 call GET_SUBFCN ; copy the save area info to user's buffer
1378
1379 xor bl,bl ; bl = 0 for our implementation
1380 ; this indicates to user that ES:DI
1381 ; buffer has been filled in with save
1382 ; area info
1383AM_Get_Exit:
1384
1385 ret
1386
1387 page
1388;-------------------------------------------------------------------
1389;
1390; _am_set
1391;
1392;-------------------------------------------------------------------
1393_am_set:
1394
1395 push si
1396 push ds
1397
1398 cmp bl,null ; bl must be 0 for us
1399 jne _am_set_error ; set error code and exit
1400
1401 mov di,cs:[bp].IE_Saved_DI_Reg ; restore caller's DI, pointer to mapping control structure
1402
1403 mov cs:AM_ES_Save,es ; save es value ;an000; dms;
1404 mov cs:AM_DI_Save,di ; save di value ;an000; dms;
1405 mov cs:AM_Set_Flag,01 ; flag indicates set performed ;an000; dms;
1406 mov si,di ; restore_pgfrm_map expects DS:SI to point to save area
1407 push es
1408 pop ds
1409
1410 call RESTORE_PGFRM_MAP
1411
1412 xor ah,ah ; good return code
1413
1414 jmp _am_set_exit
1415
1416_am_set_error:
1417 mov ah,EMS_CODE9C ; fast regs not supported and BL != 0
1418
1419_am_set_exit:
1420
1421 pop ds
1422 pop si
1423
1424 ret
1425
1426 page
1427;-------------------------------------------------------------------
1428;
1429; _am_size
1430;
1431;-------------------------------------------------------------------
1432_am_size:
1433
1434 mov dx,type h_save_struc ; get size requirements for save area
1435
1436 xor ah,ah ; good return code
1437
1438 ret
1439
1440 page
1441;-------------------------------------------------------------------
1442;
1443; _am_alloc
1444;
1445;-------------------------------------------------------------------
1446_am_alloc:
1447
1448
1449 xor bl,bl ; We don't support this function
1450 ; in hardware, so return 0.
1451 ; This indicates we will do software
1452 ; emulation of these register sets.
1453
1454 xor ah,ah ; good return code
1455
1456 ret
1457
1458 page
1459;-------------------------------------------------------------------
1460;
1461; _am_dealloc - 5b04
1462;
1463;-------------------------------------------------------------------
1464_am_dealloc:
1465
1466 xor ah,ah ; assume good return code
1467
1468 cmp bl,0 ; is this a deallocate for 0?
1469 je _am_dealloc_exit ; yes, goo return code
1470
1471 mov ah,EMS_CODE9C ; error code for dealloc of unsupported
1472 ; register set
1473
1474_am_dealloc_exit:
1475
1476 ret
1477
1478 page
1479;-------------------------------------------------------------------
1480;
1481; _am_dma_alloc
1482;
1483;-------------------------------------------------------------------
1484_am_dma_alloc:
1485
1486 xor ah,ah ; good return code
1487 xor bl,bl ; no DMA sets available
1488
1489 ret
1490
1491 page
1492;-------------------------------------------------------------------
1493;
1494; _am_dma_enable
1495;
1496;-------------------------------------------------------------------
1497_am_dma_enable:
1498
1499 mov ah,EMS_CODE9E ; dedicated DMA not supported
1500
1501 ret
1502
1503 page
1504;-------------------------------------------------------------------
1505;
1506; _am_dma_disable
1507;
1508;-------------------------------------------------------------------
1509_am_dma_disable:
1510
1511 mov ah,EMS_CODE9E ; dedicated DMA not supported
1512
1513 ret
1514
1515 page
1516;-------------------------------------------------------------------
1517;
1518; _am_dma_dealloc
1519;
1520;-------------------------------------------------------------------
1521_am_dma_dealloc:
1522
1523 xor ah,ah ; assume good return code
1524
1525 cmp bl,null ; is the DMA channel 0?
1526 je _am_dma_de_exit
1527
1528 mov ah,EMS_CODE9C ; DMA register sets are not
1529 ; supported and bl != 0
1530
1531_am_dma_de_exit:
1532 ret
1533
1534
1535alternate_map endp
1536
1537 page
1538;-------------------------------------------------------------------
1539;
1540; 5D - enable/disable OS/E functions set functions
1541;
1542;-------------------------------------------------------------------
1543enable_os proc
1544
1545 cmp al,os_enable ; fcn code for enable
1546 je os_enable_fcn
1547
1548 cmp al,os_disable ; fcn code for disable
1549 je os_disable_fcn
1550
1551 cmp al,os_access ; fcn code for access key return
1552 je os_access_fcn
1553
1554 mov ah,EMS_CODE8F ;invalid sub-function code error
1555
1556 ret ; return to caller
1557
1558 page
1559;-------------------------------------------------------------------
1560;
1561; 5d00 - enable OS/E function set
1562;
1563; INPUT:
1564;
1565; BX,CX = Access key
1566;
1567; OUTPUT:
1568;
1569; AH = 00h, no error
1570; 80H, software error
1571; 81H, hardware error
1572; 84H, invalid function
1573; 8FH, invalid subfunction
1574; A4H, access denied, incorrect access key supplied
1575;
1576;-------------------------------------------------------------------
1577os_enable_fcn:
1578
1579; find out if this is the first time
1580
1581 cmp word ptr access_code[0],0 ; access_code = 0, means enabled
1582 jne ose_check_code ; not 0, must check access code
1583
1584 cmp word ptr access_code[2],0 ; access_code = 0, means enabled
1585 jne ose_check_code ; not 0, must check access code
1586
1587 call get_code ; get access code to return
1588
1589 xor ah,ah ; good return code
1590 jmp ose_exit
1591
1592; not the first time, must check access code
1593
1594ose_check_code:
1595
1596 cmp word ptr access_code[0],bx ; does it match?
1597 jne ose_bad ; no, return access denied error
1598
1599 cmp word ptr access_code[2],cx ; get second word of access code
1600 jne ose_bad ; no, return access denied error
1601
1602; access code was OK, enable functions and return no error condition
1603
1604 mov word ptr ose_functions,ose_enabled ; reset enabled flag
1605
1606 xor ah,ah ; good return code
1607 jmp ose_exit ; all done, exit
1608
1609ose_bad:
1610 mov ah,EMS_CODEA4 ; return access denied error code
1611
1612ose_exit:
1613 ret ; return to caller
1614
1615
1616 page
1617;-------------------------------------------------------------------
1618;
1619; 5d01 - disable OS/E function set
1620;
1621; INPUT:
1622;
1623; BX,CX = Access key
1624;
1625; OUTPUT:
1626;
1627; AH = 00h, no error
1628; 80H, software error
1629; 81H, hardware error
1630; 84H, invalid function
1631; 8FH, invalid subfunction
1632; A4H, access denied, incorrect access key supplied
1633;
1634;-------------------------------------------------------------------
1635os_disable_fcn:
1636
1637; find out if this is the first time
1638
1639 cmp word ptr access_code[0],0 ; access_code = 0, means enabled
1640 jne osd_check_code ; not 0, must check access code
1641
1642 cmp word ptr access_code[2],0 ; access_code = 0, means enabled
1643 jne osd_check_code ; not 0, must check access code
1644
1645; yes, first time, must set access code and disable fcns
1646
1647 call get_code ; get access code to return
1648
1649 mov word ptr ose_functions,ose_disabled ; disable fcns
1650
1651 xor ah,ah ; good return code
1652 jmp osd_exit
1653
1654; not the first time, must check access code
1655
1656osd_check_code:
1657
1658 cmp word ptr access_code[0],bx ; does it match?
1659 jne osd_bad ; no, return access denied error
1660
1661 cmp word ptr access_code[2],cx ; get second word of access code
1662 jne osd_bad ; no, return access denied error
1663
1664; access code was OK, enable functions and return no error condition
1665
1666 mov word ptr ose_functions,ose_disabled ; disable functions
1667
1668 xor ah,ah ; good return code
1669 jmp osd_exit ; all done, exit
1670
1671osd_bad:
1672 mov ah,EMS_CODEA4 ; return access denied error code
1673
1674osd_exit:
1675 ret ; return to caller
1676
1677 page
1678;-------------------------------------------------------------------
1679;
1680; 5d02 - return OS/E function set access code
1681;
1682; INPUT:
1683;
1684; BX,CX = Access key
1685;
1686; OUTPUT:
1687;
1688; AH = 00h, no error
1689; 80H, software error
1690; 81H, hardware error
1691; 84H, invalid function
1692; 8FH, invalid subfunction
1693; A4H, access denied, incorrect access key supplied
1694;
1695;-------------------------------------------------------------------
1696os_access_fcn:
1697
1698; check access code
1699
1700
1701 cmp word ptr access_code[0],bx ; does it match?
1702 jne osa_bad ; no, return access denied error
1703
1704 cmp word ptr access_code[2],cx ; get second word of access code
1705 jne osa_bad ; no, return access denied error
1706
1707; clear access code and return "no error" return code (AH = 00)
1708
1709 xor ax,ax ; clear ax
1710 mov word ptr access_code[0],ax ; clear access code
1711 mov word ptr access_code[2],ax ; clear access code
1712
1713 jmp osa_exit
1714
1715osa_bad:
1716 mov ah,ems_codeA4 ; access denied error code
1717
1718osa_exit:
1719 ret ; return to caller
1720
1721
1722
1723
1724 page
1725;-------------------------------------------------------------------
1726;
1727; get_code - returns random access code in cx,dx and stores it in
1728; system variable access_code. Access_code is a double-word
1729; which is used to save the bx,cx combination making up the
1730; "password" for OS/E functions.
1731;
1732;-------------------------------------------------------------------
1733
1734get_code:
1735
1736 push dx ; save dx
1737
1738; get a "random" number for first word of access code
1739
1740redo1:
1741 call get_rand ; returns "random" num in dx
1742 xor dx,xor_mask ; confuse it a little
1743
1744 cmp dx,0 ; make sure we didn't end up w/0
1745 je redo1
1746
1747 mov word ptr access_code[0],dx ; save it away
1748 mov bx,dx
1749
1750; get another one for second word of access code
1751
1752redo2:
1753 call get_rand
1754 add dx,dx ; confuse it a little
1755 xor dx,xor_mask
1756
1757 cmp dx,0 ; make sure we didn't end up w/0
1758 je redo2
1759
1760 mov word ptr access_code[2],dx ; save it away
1761 mov cx,dx ; put second word in cx
1762
1763 pop dx ; restore
1764
1765 ret ; return to caller
1766
1767
1768;-------------------------------------------------------------------
1769;
1770; get_rand - returns a "random" number in dx
1771;
1772;-------------------------------------------------------------------
1773get_rand:
1774
1775 push ax ; save some regs
1776 push cx
1777
1778redo:
1779 mov ah,read_clock ; function code to read clock
1780 int dos_int ; read the time
1781 ; keep DX since it changes the most
1782
1783 cmp dx,0 ; did we end up with 0?
1784 je redo ; yes, redo it ... never want 0
1785
1786 pop cx ; restore some regs
1787 pop ax
1788
1789 ret ; return to caller
1790
1791enable_os endp
1792
diff --git a/v4.0/src/DEV/XMA2EMS/LIM40B.INC b/v4.0/src/DEV/XMA2EMS/LIM40B.INC
new file mode 100644
index 0000000..1e7683f
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/LIM40B.INC
@@ -0,0 +1,3468 @@
1
2 page
3;=========================================================================
4; This module contains all the EQU's, STRUC's, data, and routines necessary
5; for LIMDMS.INC.
6; This module is to be INCLUDE'd as part of LIMDMS.INC.
7;
8;=========================================================================
9
10;=========================================================================
11;========== Begin EQUate Definitions =====================================
12;=========================================================================
13
14AAJ_Option_Max equ 1h ;max option value ;an000; dms;
15AAJ_Segment equ 1h ;segment request value ;an000; dms;
16AAJ_No_Pages_To_Map equ 0h ;0 page map request ;an000; dms;
17
18MAC_Stack_Status_Request equ 02h ;stack size request ;an000; dms;
19
20ER_Conv_Memory equ 00h ;conv. memory request ;an000; dms;
21ER_EMS_Memory equ 01h ;EMS memory request ;an000; dms;
22EMS_Page_Size_In_Bytes equ (16*1024)-1 ;page size in bytes ;an000; dms;
23ER_Max_Type equ 01h ;max type possible ;an000; dms;
24ER_Max_Function equ 01h ;max function possible ;an000; dms;
25ER_Move equ 00h ;move data ;an000; dms;
26ER_Exchange equ 01h ;exchange data ;an000; dms;
27ER_EMS_Page_FE equ 0FEh ;phys. page FEh ;an000; dms;
28ER_EMS_Page_FF equ 0FFh ;phys. page FFh ;an000; dms;
29ER_Dest_EMS_Memory equ 01h ;bit 0 set ;an000; dms;
30ER_Source_EMS_Memory equ 02h ;bit 1 set ;an000; dms;
31ER_Up equ 00h ;signal forward move ;an000; dms;
32ER_Down equ 0ffh ;signal reverse move
33ER_10H equ 10h ;equ for 10h ;an000; dms;
34
35AR_Sub_Max equ 01h ;5ah max. sub functions ;an000; dms;
36
37;=========================================================================
38;========== End EQUate Definitions =======================================
39;=========================================================================
40
41 page
42;=========================================================================
43;========== Begin STRUC Definitions ======================================
44;=========================================================================
45
46Log_Phys_Map_Struc struc ;page structure ;an000; dms;
47
48 Log_Page_Number dw ? ;logical page number ;an000; dms;
49 Phys_Page_Number_Seg dw ? ;physical page or seg ;an000; dms;
50 ; determined by AL
51Log_Phys_Map_Struc ends
52
53
54Map_And_Jump_Struc struc ;carries jump info. ;an000; dms;
55
56 Target_Address dd ? ;jump address ;an000; dms;
57 Log_Phys_Map_Len db ? ;entry count in ;an000; dms;
58 ; Log_Phys_Map_Struct
59 Log_Phys_Map_Ptr dd ? ;Log_Phys_Map_Struct ptr;an000; dms;
60
61Map_And_Jump_Struc ends ;an000; dms;
62
63
64Map_And_Call_Struc struc ;carries jump info. ;an000; dms;
65
66 MAC_Target_Address dd ? ;jump address ;an000; dms;
67 MAC_New_Page_Map_Len db ? ;entry count in ;an000; dms;
68 ; Log_Phys_Map_Struct
69 ; for new map scheme
70 MAC_New_Page_Map_Ptr dd ? ;Log_Phys_Map_Struc ptr ;an000; dms;
71 ; for new map scheme
72 MAC_Old_Page_Map_Len db ? ;entry count in ;an000; dms;
73 ; Log_Phys_Map_Struc
74 ; for old map scheme
75 MAC_Old_Page_Map_Ptr dd ? ;Log_Phys_Map_Struc ptr ;an000; dms;
76 ; for old map scheme
77 MAC_Reserved dw 4 DUP (?) ;Used to restore map ;an000; dms;
78 ; context
79
80Map_And_Call_Struc ends ;an000; dms;
81
82
83Move_Source_Dest_Struc struc ;structure for move ;an000; dms;
84
85 Region_Length_Low_Word dw ? ;
86 Region_Length_High_Word dw ? ;length of region ;an000; dms;
87
88 Source_Memory_Type db ? ;conv/EMS ;an000; dms;
89 Source_Handle dw ? ;handle if EMS, else 0 ;an000; dms;
90 Source_Initial_Offset dw ? ;offset of source region;an000; dms;
91 Source_Initial_Seg_Page dw ? ;logical page if EMS ;an000; dms;
92 ; seg if conv.
93 Dest_Memory_Type db ? ;conv/EMS ;an000; dms;
94 Dest_Handle dw ? ;handle if EMS, else 0 ;an000; dms;
95 Dest_Initial_Offset dw ? ;offset of source region;an000; dms;
96 Dest_Initial_Seg_Page dw ? ;logical page if EMS ;an000; dms;
97 ; seg if conv.
98Move_Source_Dest_Struc ends ;end structure ;an000; dms;
99
100Realloc_Struc Struc ;BP addressible struc ;an000; dms;
101
102 Realloc_Reserved db size Instance_Entry_Struc dup (?) ;an000; dms;
103 Realloc_Alloc_Byte db ? ;reserved ;an000; dms;
104 Realloc_Reg_DI dw ? ;reserved ;an000; dms;
105 Realloc_Handle dw ? ;handle ;an000; dms;
106
107 Realloc_Page_Count dw ? ;new page count ;an000; dms;
108 Realloc_Page_Alloc dw ? ;pages to be allocated ;an000; dms;
109 Realloc_Page_Dealloc dw ? ;pages to be deallocated ;an000; dms;
110
111 Realloc_Handle_Xref_Index dw ? ;index to end of handle table ;an000; dms;
112 Realloc_LookUp_Index dw ? ;index to applicable handle ;an000; dms;
113 Realloc_Mult dw ? ;multiplier ;an000; dms;
114
115Realloc_Struc Ends ;end structure ;an000; dms;
116
117AAJ_Struc Struc ;BP addressible struc ;an000; dms;
118
119 AAJ_Reserved db size Instance_Entry_Struc dup (?) ;an000; dms;
120 AAJ_Xref_Pages dw ? ;save logical page count ;an000; dms;
121 AAJ_Handle dw ? ;saved handle ;an000; dms;
122 AAJ_Option db ? ;saved selector state ;an000; dms;
123 AAJ_LookUp_Index dw ? ;save index ;an000; dms;
124 AAJ_Mult dw ? ;multiplier ;an000; dms;
125
126AAJ_Struc Ends ;end structure ;an000; dms;
127
128MAC_Struc Struc ;BP addressible struc ;an000; dms;
129
130 MAC_Reserved_Area db size Instance_Entry_Struc dup (?) ;an000; dms;
131 MAC_LookUp_Index dw ? ;save index ;an000; dms;
132 MAC_Xref_Pages dw ? ;save logical page count ;an000; dms;
133 MAC_Option db ? ;saved selector state ;an000; dms;
134
135 EMS_Reg_ES dw ? ;ES reg ;an000; dms;
136 EMS_Reg_DS dw ? ;DS reg ;an000; dms;
137 EMS_Reg_FL dw ? ;FL reg ;an000; dms;
138 EMS_Reg_SI dw ? ;SI reg ;an000; dms;
139 EMS_Reg_DI dw ? ;DI reg ;an000; dms;
140 EMS_Reg_DX dw ? ;DX reg ;an000; dms;
141 EMS_Reg_CX dw ? ;CX reg ;an000; dms;
142 EMS_Reg_BX dw ? ;BX reg ;an000; dms;
143
144 MAC_M_C_Data db size Map_And_Call_Struc dup (?) ;an000; dms;
145 MAC_M_C_Log db size Log_Phys_Map_Struc*Map_Count_Def dup (?) ;an000; dms;
146 MAC_Map_Table db size Mappable_Phys_Page_Struct*Map_Count_Def dup (?) ;an000; dms;
147 MAC_Mult dw ? ;multiplier ;an000; dms;
148
149MAC_Struc Ends ;end structure ;an000; dms;
150
151
152ER_Struc Struc ;BP addressible struc ;an000; dms;
153
154 ER_Reserved db size Instance_Entry_Struc dup (?) ;an000; dms;
155 ER_Direction_Flag db ER_Up ;default to forward move;an000; dms;
156
157 ER_Sub_Function db ? ;save subfunction byte ;an000; dms;
158
159 ER_Src_Abs_Beg_Low dw ? ;abs add of src EMS page;an000; dms;
160 ER_Src_Abs_Beg_High dw ? ; beginning of trf area;an000; dms;
161 ER_Src_Abs_End_Low dw ? ;abs add of src EMS page;an000; dms;
162 ER_Src_Abs_End_High dw ? ; end of trf area ;an000; dms;
163
164 ER_Dst_Abs_Beg_Low dw ? ;abs add of src EMS page;an000; dms;
165 ER_Dst_Abs_Beg_High dw ? ; beginning of trf area;an000; dms;
166 ER_Dst_Abs_End_Low dw ? ;abs add of src EMS page;an000; dms;
167 ER_Dst_Abs_End_High dw ? ; end of trf area ;an000; dms;
168
169 ER_Current_Move_Count dw ? ;bytes moved this time ;an000; dms;
170
171 ER_Move_Xchg_Buffer1 db 10h dup (?) ;buffer for move/xchg ;an000; dms;
172 ER_Move_Xchg_Buffer2 db 10h dup (?) ;buffer for move/xchg ;an000; dms;
173
174 ER_Move_Count_Low dw ? ;low word of count ;an000; dms;
175 ER_Move_Count_High dw ? ;high word of count ;an000; dms;
176
177 ER_Source_Phys_Page dw ? ;page number of source ;an000; dms;
178 ER_Dest_Phys_Page dw ? ;page number of dest ;an000; dms;
179
180 ER_Source_Page dw ? ;active source page ;an000; dms;
181 ER_Dest_Page dw ? ;active dest page ;an000; dms;
182
183 ER_Source_Handle dw ? ;active handle ;an000; dms;
184 ER_Dest_Handle dw ? ;active handle ;an000; dms;
185 ; 10h byte moves
186
187 ER_Save_Context_Buffer dw 2*Type Mappable_Phys_Page_Struct dup (0) ;room for 2 pgs;an000; dms;
188
189 ER_Dest_Seg dw ? ;seg value of dest ;an000; dms;
190 ER_Source_Seg dw ? ;seg value of source ;an000; dms;
191
192 ER_Dest_Off dw ? ;off value of dest ;an000; dms;
193 ER_Source_Off dw ? ;off value of source ;an000; dms;
194
195 ER_Mem_Type dw ? ;memory type ;an000; dms;
196
197
198ER_Struc Ends ;end structure ;an000; dms;
199
200;=========================================================================
201;========== End STRUC Definitions ========================================
202;=========================================================================
203
204 page
205;=========================================================================
206;========== Begin Macro Definitions ======================================
207;=========================================================================
208
209
210;=========================================================================
211; MAC_Expand_Stack_And_Copy : This routine will place data in the
212; instance table by copying the data pointed
213; at by ES:DI.
214;
215; Inputs : AX - Size of stack adjustment
216; ES:DI - Pointer to data to be copied to stack
217;
218; Outputs : BP - data place in instance table
219;
220;=========================================================================
221
222MAC_Expand_Stack_And_Copy proc
223
224 mov cx,ax ;get adjustment factor ;an000; dms;
225 shr cx,1 ;convert to word move ;an000; dms;
226 mov ax,es ;get data source seg ;an000; dms;
227 mov ds,ax ;place in ds ;an000; dms;
228 mov si,di ;get data source off ;an000; dms;
229
230 mov ax,cs ;get dest. seg ;an000; dms;
231 mov es,ax ;place in es ;an000; dms;
232 mov di,bx ;get dest. off ;an000; dms;
233
234 cli ;ints off ;an000; dms;
235 rep movsw ;move data to stack ;an000; dms;
236 sti ;ints on ;an000; dms;
237
238 ret ;end routine ;an000; dms;
239
240MAC_Expand_Stack_And_Copy endp
241
242 page
243;=========================================================================
244; MAC_Shrink_Stack_And_Copy : This routine move data from the instance
245; table and place it at ES:DI.
246;
247; Inputs : AX - Size of stack adjustment
248; ES:DI - Pointer to where data is to be copied
249;
250; Outputs : BP - data removed from instance table
251;
252;=========================================================================
253
254MAC_Shrink_Stack_And_Copy proc
255
256 mov cx,ax ;get adjustment factor ;an000; dms;
257 mov ax,cs ;get data source seg ;an000; dms;
258 mov ds,ax ;place in ds ;an000; dms;
259 mov si,bx ;get data source off ;an000; dms;
260 mov ax,cx ;save count across move ;an000; dms;
261 shr cx,1 ;convert to word move ;an000; dms;
262
263 cli ;ints off ;an000; dms;
264 rep movsw ;move data from stack ;an000; dms;
265 sti ;ints on ;an000; dms;
266
267 ret ;end routine ;an000; dms;
268
269MAC_Shrink_Stack_And_Copy endp
270
271
272;=========================================================================
273;========== End Macro Definitions ========================================
274;=========================================================================
275
276 page
277;=========================================================================
278;========== Begin Generic PROC Definitions ===============================
279;=========================================================================
280
281;=========================================================================
282; Map_Pages : This routine will map the pages being
283; requested in the struc pointed to by
284; DS:SI.
285;
286; Inputs : ES:DI - Pointer to data in Log_Phys_Map_Struc format
287; CX - Count of data iterations in ES:DI
288; DX - handle
289; BX - page count for handle
290; AL - option
291;
292; Outputs : Revised map
293; AH - 0 = no error
294; > 0 = error
295;=========================================================================
296
297Map_Pages proc ; ;an000; dms;
298
299 push si ;save reg ;an000; dms;
300
301 mov si,ax ;save option ;an000; dms;
302 cmp cx,AAJ_No_Pages_To_Map ;no pages? ;an000; dms;
303 je Map_Error_Exit ;yes - exit loop ;an000; dms;
304
305Map_Loop_Continue:
306
307 cmp [di].Log_Page_Number,bx ;logical page out of ;an000; dms;
308 ; range?
309 jbe Map_Get_Segment ;no - in range ;an000; dms;
310 mov ah,EMS_Code8A ;yes - out of range ;an000; dms;
311 jmp Map_Error_Exit ;exit routine ;an000; dms;
312
313Map_Get_Segment:
314
315 cmp si,AAJ_Segment ;segment request? ;an000; dms;
316 mov ax,[di].Phys_Page_Number_Seg ;get physical page ;an000; dms;
317 jne Map_Page_Request ;no - page request ;an000; dms;
318 push dx ;save handle
319 mov dx,[di].Phys_Page_Number_Seg ;get segment ;an000; dms;
320 call Get_Phys_Seg_Page ;get the associated ;an000; dms;
321 ; page for the segment
322 mov ax,dx ;place page in ax ;an000; dms;
323 pop dx ;restore handle
324 jnc Map_Page_Request ;no error - continue ;an000; dms;
325 mov ah,EMS_Code8B ;phys page not found ;an000; dms;
326 jmp Map_Error_Exit ;exit routine ;an000; dms;
327
328Map_Page_Request:
329
330 push bx ;save bx across call ;an000; dms;
331 mov bx,[di].Log_Page_Number ;logical page to map ;an000; dms;
332 call Map_L_To_P ;map the page ;an000; dms;
333 pop bx ;restore bx ;an000; dms;
334 or ah,ah ;error? ;an000; dms;
335 jnz Map_Error_Exit ;pass error on & exit ;an000; dms;
336 add di,Type Log_Phys_Map_Struc ;adjust pointer ;an000; dms;
337 loop Map_Loop_Continue ;continue loop ;an000; dms;
338 xor ax,ax ;signal good finish ;an000; dms;
339
340Map_Error_Exit:
341
342 pop si ;restore reg ;an000; dms;
343
344 ret ;return to caller ;an000; dms;
345
346Map_Pages endp ;end proc ;an000; dms;
347
348
349 page
350;=========================================================================
351; Get_Phys_Seg_Page : This routine will obtain the physical page
352; number for a given segment.
353;
354; Inputs : DX - Segment value
355; Outputs : DX - Physical page number
356; CY - Error
357; NC - No error
358;=========================================================================
359
360Get_Phys_Seg_Page proc ;begin routine ;an000; dms;
361
362 push ax ;save regs ;an000; dms;
363 push cx ; ;an000; dms;
364 push di ; ;an000; dms;
365
366 cli ;ints off ;an000; dms;
367 mov di,offset Map_Table ;point to table map ;an000; dms;
368 mov cx,Map_Count ;number of table entries;an000; dms;
369 sti ;ints on ;an000; dms;
370
371GPSP_Loop:
372
373 cli ;ints off ;an000; dms;
374 cmp dx,cs:[di].Phys_Page_Segment ;segment match? ;an000; dms;
375 je GPSP_Got_Segment ;yes ;an000; dms;
376 add di,Type Mappable_Phys_Page_Struct ;adjust pointer ;an000; dms;
377 loop GPSP_Loop ;continue search ;an000; dms;
378
379GPSP_Got_Segment:
380
381 sti ;ints on ;an000; dms;
382 cmp cx,0 ;data found? ;an000; dms;
383 je GPSP_Not_Found ;exit with error ;an000; dms;
384 mov dx,cs:[di].Phys_Page_Number ;exit with page number ;an000; dms;
385 clc ;clear cy ;an000; dms;
386 jmp GPSP_Found ;exit ;an000; dms;
387
388GPSP_Not_Found:
389
390 stc ;signal error ;an000; dms;
391
392GPSP_Found: ;exit ;an000; dms;
393
394 pop di ;restore regs ;an000; dms;
395 pop cx ; ;an000; dms;
396 pop ax ; ;an000; dms;
397
398 ret ;return to caller ;an000; dms;
399
400Get_Phys_Seg_Page endp ;end proc ;an000; dms;
401
402
403;=========================================================================
404;========== End Generic PROC Definitions =================================
405;=========================================================================
406
407
408
409 page
410
411;-------------------------------------------------------------------
412; Reallocate Pages - Function 18
413;
414; Entry - AX = 51??
415; BX = count of new allocation pages
416; DX = handle
417;
418; Exit - AH = status
419; BX = new page count
420; if error - original page count
421;-------------------------------------------------------------------
422reallocate proc
423
424 push cx ;save affected regs ;an000; dms;
425 push dx ; ;an000; dms;
426 push di ; ;an000; dms;
427 push si ; ;an000; dms;
428
429 push ds ;save segments ;an000; dms;
430 push es ; ;an000; dms;
431
432 mov ax,cs ;get code segment ;an000; dms;
433 mov ds,ax ;put int ds and ;an000; dms;
434 mov es,ax ; es ;an000; dms;
435
436
437 mov cs:[bp].Realloc_Page_Count,bx ;new page count ;an000; dms;
438 mov cs:[bp].Realloc_Handle,dx ;handle ;an000; dms;
439
440
441
442 mov ax,cs:[bp].Realloc_Handle ;get handle for search ;an000; dms;
443 mov cs:[bp].Realloc_Mult,Type H_LookUp_Struc;handle lookup table ;an000; dms;
444 mul cs:[bp].Realloc_Mult ;obtain index position ;an000; dms;
445 mov cs:[bp].Realloc_LookUp_Index,ax ;index to handle ;an000; dms;
446 mov di,ax ;place index in si ;an000; dms;
447 mov dx,cs:[bp].Realloc_Handle ;get handle number ;an000; dms;
448
449
450 cmp dx,Num_Handles-1 ;dx > handle count? ;an000; dms;
451 jbe Realloc_Handle_Search ;handle within range ;an000; dms;
452 mov ah,EMS_Code83 ;EMS handle non-existent;an000; dms;
453 jmp Realloc_Error_Exit ;exit program ;an000; dms;
454
455Realloc_Handle_Search:
456
457 cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms;
458 jne Realloc_Status_Of_Handle ;handle good ;an000; dms;
459 mov ah,EMS_Code83 ;EMS handle not alloc ;an000; dms;
460 jmp Realloc_Error_Exit ;exit program ;an000; dms;
461
462Realloc_Status_Of_Handle:
463
464
465 mov ax,Handle_LookUp_Table.H_Pages[di] ;get current page count ;an000; dms;
466 sub ax,cs:[bp].Realloc_Page_Count ;more or less pages? ;an000; dms;
467 jc Realloc_More_Pages ;more pages to alloc ;an000; dms;
468
469Realloc_Less_Pages:
470
471 mov bx,ax ;pages to deallocate ;an000; dms;
472 mov cs:[bp].Realloc_Page_Dealloc,ax ;save dealloc value ;an000; dms;
473
474 mov si,Handle_LookUp_Table.H_Pal_Ptr[di] ;get start of links ;an000; dms;
475 mov cx,Handle_LookUp_Table.H_Pages[di] ;current pages allocated;an000; dms;
476 sub cx,bx ;pages to remain alloc ;an000; dms;
477
478
479Realloc_Dealloc_Loop1:
480
481 cmp cx,0 ;pages? ;an000; dms;
482 je Realloc_Dealloc_Loop1_Exit ;no - exit ;an000; dms;
483 shl si,1
484 mov si,Page_Alloc_List[si] ;get next pointer ;an000; dms;
485 dec cx ;dec loop count ;an000; dms;
486 jmp Realloc_Dealloc_Loop1 ;continue ;an000; dms;
487
488Realloc_Dealloc_Loop1_Exit:
489
490;***** Adjust pointers *****
491
492 mov cx,cs:[bp].Realloc_Page_Dealloc ;get dealloc count ;an000; dms;
493 mov ax,cs:PAL_Free_Ptr ;get the free ptr ;an001; dms;
494 cmp cx,0 ;0 pages to dealloc? ;an001; dms;
495 je Realloc_Dealloc_Loop2_Exit1 ;yes - bypass dealloc ;an001; dms;
496 mov cs:PAL_Free_Ptr,si ;no - set new free ptr ;an001; dms;
497 dec cx ;don't loop past last pg;an001; dms;
498
499Realloc_Dealloc_Loop2:
500
501 cmp cx,0 ;end of deallocate? ;an000; dms;
502 je Realloc_Dealloc_Loop2_Exit ;yes - exit ;an000; dms;
503 shl si,1 ;get index entry ;an001; dms;
504 mov si,Page_Alloc_List[si] ;get next ptr ;an001; dms;
505 dec cx ;decrement counter ;an000; dms;
506 jmp Realloc_Dealloc_Loop2
507
508Realloc_Dealloc_Loop2_Exit:
509
510 shl si,1 ;get index entry ;an001; dms;
511 mov Page_Alloc_List[si],ax ;pt. last page to orig. ;an001; dms;
512 ; free ptr.
513
514Realloc_Dealloc_Loop2_Exit1:
515
516 mov ax,cs:[bp].Realloc_Page_Count ;new page count ;an000; dms;
517 mov Handle_LookUp_Table.H_Pages[di],ax ; ;an000; dms;
518
519 mov ax,cs:[bp].Realloc_Page_Dealloc ;adj. value ;an000; dms;
520 add cs:Free_Pages,ax ;free up page ;an000; dms;
521
522 mov bx,cs:[bp].Realloc_Page_Count ;pass back page request ;an000; dms;
523 xor ah,ah ;clear error ;an000; dms;
524 jmp Realloc_Exit ;exit ;an000; dms;
525
526Realloc_More_Pages:
527
528 mov cx,cs:[bp].Realloc_Page_Count ;get page request count ;an000; dms;
529 mov di,cs:[bp].Realloc_LookUp_Index ;get LookUp Table ptr ;an000; dms;
530 mov ax,Handle_LookUp_Table.H_Pages[di] ;get current page count ;an000; dms;
531 sub cx,ax ;get additional pages ;an000; dms;
532 mov cs:[bp].Realloc_Page_Alloc,cx ;new pages to alloc ;an000; dms;
533 cmp cx,Free_Pages ;> pages remaining? ;an000; dms;
534 jbe Realloc_Pages ;reallocate pages ;an000; dms;
535 mov ah,EMS_Code87 ;Too few pages avail ;an000; dms;
536 jmp Realloc_Error_Exit ;exit prog ;an000; dms;
537
538Realloc_Pages:
539
540 mov cx,Handle_LookUp_Table.H_Pages[di] ;current pages allocated;an000; dms;
541 cmp cx,0 ;any pages? ;an000; dms;
542 jne Realloc_More_Pages_Cont ;yes ;an000; dms;
543 cmp cs:[bp].Realloc_Page_Alloc,0 ;any pages requested? ;an000; dms;
544 je Realloc_Alloc_Loop1_Exit ;continue ;an000; dms;
545
546 mov cx,cs:[bp].Realloc_Page_Alloc ;get new page count ;an001; dms;
547 cli ;ints off ;an001; dms;
548 call EMS_Page_Contig_Chk ;contig pages avail? ;an001; dms;
549 jnc Realloc_New_Pages
550 mov ah,EMS_Code87 ;Too few pages avail ;an000; dms;
551 sti ;ints on ;an001; dms;
552 jmp Realloc_Error_Exit ;exit prog ;an000; dms;
553
554Realloc_New_Pages:
555
556 call EMS_Link_Set ;set up page list ;an001; dms;
557
558 mov Handle_LookUp_Table.H_Pal_Ptr[di],si ;set table to pointer ;an000; dms;
559 mov Handle_LookUp_Table.H_Pages[di],cx ;new page count ;an000; dms;
560 mov bx,cs:[bp].Realloc_Page_Count ;return new page count ;an001; dms;
561 sub cs:Free_Pages,bx ;new free count ;an000; dms;
562 sti ;ints on ;an001; dms;
563 xor ax,ax ;clear error flag ;an001; dms;
564
565 jmp Realloc_Exit ;exit routine ;an001; dms;
566
567
568Realloc_More_Pages_Cont:
569
570 dec cx
571 mov si,Handle_LookUp_Table.H_Pal_Ptr[di] ;get start of links ;an000; dms;
572
573Realloc_Alloc_Loop1:
574 cmp cx,0 ;at end ;an000; dms;
575 je Realloc_Alloc_Loop1_Exit ;yes ;an000; dms;
576 shl si,1 ;word entry ;an000; dms;
577 mov si,Page_Alloc_List[si] ;get next pointer ;an000; dms;
578 dec cx ;decrement loop count ;an000; dms;
579 jmp Realloc_Alloc_Loop1 ;continue ;an000; dms;
580
581Realloc_Alloc_Loop1_Exit:
582
583 mov cx,cs:[bp].Realloc_Page_Alloc ;new pages to alloc ;an000; dms;
584 cmp cx,0 ;pages requested? ;an001; dms;
585 je Realloc_Alloc_Exit ;no - exit routine ;an001; dms;
586
587 mov bx,si ;save si ;an001; dms;
588 cli ;ints off ;an001; dms;
589 call EMS_Page_Contig_Chk ;contig pages? ;an001; dms;
590 jnc Realloc_Next_Pages ;yes ;an001; dms;
591 mov ah,EMS_Code87 ;Too few pages avail ;an000; dms;
592 sti ;ints on ;an001; dms;
593 jmp Realloc_Error_Exit ;exit prog ;an000; dms;
594
595Realloc_Next_Pages:
596
597;;;; mov ax,si ;ptr to new list ;an001; dms;
598;;;; inc ax ;contig to new links? ;an001; dms;
599;;;; cmp ax,bx ; ;an001; dms;
600;;;; je Realloc_Next_Pages1 ;yes continue ;an001; dms;
601;;;; mov ah,EMS_Code87 ;Too few pages avail ;an000; dms;
602;;;; sti ;ints on ;an001; dms;
603;;;; jmp Realloc_Error_Exit ;exit prog ;an000; dms;
604
605Realloc_Next_Pages1:
606
607 call EMS_Link_Set ;set up page list ;an001; dms;
608 mov ax,si ;ptr to new list ;an001; dms;
609 mov si,bx ;end of old list ;an001; dms;
610 shl si,1 ;index entry ;an001; dms;
611 mov Page_Alloc_List[si],ax ;pick up new links ;an001; dms;
612
613Realloc_Alloc_Exit:
614
615 mov bx,cs:[bp].Realloc_Page_Alloc ;additional pages ;an001; dms;
616 sub cs:Free_Pages,bx ;new free count ;an000; dms;
617 mov bx,cs:[bp].Realloc_Page_Count ;pass back page request ;an000; dms;
618 mov Handle_LookUp_Table.H_Pages[di],bx ;new page count ;an000; dms;
619 sti ;ints on ;an001; dms;
620 xor ah,ah ;clear ah ;an000; dms;
621 jmp Realloc_Exit ;exit ;an000; dms;
622
623
624Realloc_Error_Exit:
625
626 cli ;ints off ;an000; dms;
627 mov si,cs:[bp].Realloc_LookUp_Index ;get handle index ;an000; dms;
628 mov bx,Handle_LookUp_Table.H_Pages[si] ;get orig. count ;an000; dms;
629 mov Handle_LookUp_Table.H_Pages[si],bx ;new page count ;an000; dms;
630 sti ;ints on ;an000; dms;
631
632Realloc_Exit:
633
634 pop es ;restore segments ;an000; dms;
635 pop ds ; ;an000; dms;
636
637 pop si ;restore regs ;an000; dms;
638 pop di ; ;an000; dms;
639 pop dx ; ;an000; dms;
640 pop cx ; ;an000; dms;
641
642 ret ;return to caller ;an000; dms;
643
644reallocate endp
645
646
647
648 page
649;=========================================================================
650;=============== Function 55h Logic - Alter Page Map & Jump =============
651;=========================================================================
652;=========================================================================
653; Alter_And_Jump - This routine alters the page map and jumps
654; to the specified address.
655;
656; Inputs : AH - 55h (Alter page map & jump)
657; AL - Physical page number/segment selector
658; 0 = Physical page numbers specified
659; 1 = Segment addresses specified in lieu of
660; physical page numbers
661; DX - handle number
662; DS:SI - Pointer to map and jump structure
663; (see Map_And_Jump_Struct above)
664;
665; Outputs : Revised map
666; AH - Non-zero if error
667;
668;=========================================================================
669Alter_And_Jump proc ;modify map ;an000; dms;
670
671 push bx ;save regs for jump ;an000; dms;
672 push cx ; ;an000; dms;
673 push di ; ;an000; dms;
674 push si ; ;an000; dms;
675
676 pushf ;save flags ;an000; dms;
677 push ds ;save segments ;an000; dms;
678 push es ; ;an000; dms;
679
680 mov bx,cs ;get code segment ;an000; dms;
681 mov es,bx ; es ;an000; dms;
682
683 mov cs:[bp].AAJ_Handle,dx ;save handle ;an000; dms;
684 mov cs:[bp].AAJ_Option,al ;save selector option ;an000; dms;
685
686
687
688 cmp dx,Num_Handles-1 ;dx > handle count ;an000; dms;
689 jbe AAJ_Check_Reusable ;continue test ;an000; dms;
690 mov ah,EMS_Code83 ;EMS handle bad ;an000; dms;
691 jmp AAJ_Error_Exit ;exit routine ;an000; dms;
692
693AAJ_Check_Reusable:
694
695 mov ax,dx ;get handle ;an000; dms;
696 mov cs:[bp].AAJ_Mult,Type H_LookUp_Struc ;handle lookup table ;an000; dms;
697 mul cs:[bp].AAJ_Mult ;obtain index position ;an000; dms;
698 mov cs:[bp].AAJ_LookUp_Index,ax ;index to handle ;an000; dms;
699 mov di,ax ;place index in di ;an000; dms;
700
701 cli ;ints off ;an000; dms;
702 mov ax,Handle_LookUp_Table.H_Pages[di] ;get logical page count ;an000; dms;
703 mov cs:[bp].AAJ_Xref_Pages,ax ;save logical page count;an000; dms;
704 sti ;ints on ;an000; dms;
705 cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms;
706 jne AAJ_Good_Handle ;handle good ;an000; dms;
707 mov ah,EMS_Code83 ;EMS handle bad ;an000; dms;
708 jmp AAJ_Error_Exit ;exit routine ;an000; dms;
709
710AAJ_Good_Handle:
711
712 cmp cs:[bp].AAJ_Option,AAJ_Option_Max ;option in range? ;an000; dms;
713 jbe AAJ_Good_Option ;option good ;an000; dms;
714 mov ah,EMS_Code8F ;bad option ;an000; dms;
715 jmp AAJ_Error_Exit ;exit routine ;an000; dms;
716
717AAJ_Good_Option:
718
719 les di,[si].Log_Phys_Map_Ptr ;point to map data ;an000; dms;
720 xor cx,cx ;clear loop counter ;an000; dms;
721 mov cl,[si].Log_Phys_Map_Len ;get loop count ;an000; dms;
722 mov dx,cs:[bp].AAJ_Handle ;get handle for call ;an000; dms;
723 mov bx,cs:[bp].AAJ_Xref_Pages ;logical page count ;an000; dms;
724 xor ah,ah ;clear high word ;an000; dms;
725 mov al,cs:[bp].AAJ_Option ;option selected ;an000; dms;
726 call Map_Pages ;map the pages requested;an000; dms;
727 or ah,ah ;error? ;an000; dms;
728 jnz AAJ_Error_Exit ;exit with error cond. ;an000; dms;
729
730AAJ_Loop_Exit:
731
732 pop es ;restore regs ;an000; dms;
733 pop ds ; ;an000; dms;
734 popf ; ;an000; dms;
735 pop si ; ;an000; dms;
736 pop di ; ;an000; dms;
737 pop cx ; ;an000; dms;
738 pop bx ; ;an000; dms;
739
740 mov cs:[bp].IE_Alloc_Byte,Unallocated ;deallocate instance ;an000; dms;
741
742 jmp dword ptr [si].Target_Address ;jump to address & run ;an000; dms;
743
744AAJ_Error_Exit:
745
746 pop es ;restore regs ;an000; dms;
747 pop ds ; ;an000; dms;
748 popf ; ;an000; dms;
749 pop si ; ;an000; dms;
750 pop di ; ;an000; dms;
751 pop cx ; ;an000; dms;
752 pop bx ; ;an000; dms;
753
754
755 ret ;return to caller ;an000; dms;
756
757Alter_And_Jump endp ;end proc ;an000; dms;
758
759
760
761 page
762;=========================================================================
763;=============== Function 56h Logic - Alter Page Map & Call =============
764;=========================================================================
765
766
767
768;=========================================================================
769; Alter_And_Call - This routine alters the page map and calls
770; the specified address. The mapping context
771; is saved on entry to the routine and restored
772; on exit from the routine.
773;
774; Inputs : AH - 56h (Alter page map & call)
775; AL - Physical page number/segment selector
776; 0 = Physical page numbers specified
777; 1 = Segment addresses specified in lieu of
778; physical page numbers
779; 2 = Give minimum required stack size
780; DX - handle number
781; DS:SI - Pointer to map and jump structure
782; (see Map_And_Call_Struc above)
783;
784; Outputs : Revised map
785; AH - Non-zero if error
786; BX - Function 2 = size in bytes needed for stack
787;
788;=========================================================================
789
790
791Alter_And_Call proc ;modify map & call ;an000; dms;
792
793 cmp al,MAC_Stack_Status_Request ;stack report? ;an000; dms;
794 je MAC_Calc_Stack_Status ;yes ;an000; dms;
795 jb MAC_Alter_And_Call ;no - new mapping ;an000; dms;
796 mov ah,EMS_Code8F ;error occurred ;an000; dms;
797 jmp MAC_Stack_Exit ;exit routine ;an000; dms;
798
799MAC_Calc_Stack_Status:
800
801 mov bx,8h ;room for call address ;an000; dms;
802 ; and return address
803 xor ax,ax ;signal no error ;an000; dms;
804 jmp MAC_Stack_Exit ;exit routine ;an000; dms;
805
806MAC_Alter_And_Call:
807
808 cli ;ints off ;an000; dms;
809 mov cs:[bp].EMS_Reg_BX,bx ; ;an000; dms;
810 mov bx,ax ;save ax across flags ;an000; dms;
811 lahf ;move flags to ah ;an000; dms;
812 mov cs:[bp].EMS_Reg_FL,ax ;save flags ;an000; dms;
813 mov ax,bx ;restore ax ;an000; dms;
814 mov cs:[bp].EMS_Reg_CX,cx ; ;an000; dms;
815 mov cs:[bp].EMS_Reg_DX,dx ; ;an000; dms;
816 mov cs:[bp].EMS_Reg_DI,di ; ;an000; dms;
817 mov cs:[bp].EMS_Reg_SI,si ; ;an000; dms;
818 mov cs:[bp].EMS_Reg_DS,ds ; ;an000; dms;
819 mov cs:[bp].EMS_Reg_ES,es ; ;an000; dms;
820
821 mov cs:[bp].MAC_Option,al ;save option ;an000; dms;
822 sti ;ints on ;an000; dms;
823 cmp dx,Num_Handles-1 ;dx > handle count ;an000; dms;
824 jbe MAC_Check_Reusable ;continue test ;an000; dms;
825 mov ah,EMS_Code83 ;EMS handle bad ;an000; dms;
826 jmp MAC_Error_Exit ;exit routine ;an000; dms;
827
828MAC_Check_Reusable:
829
830 mov ax,dx ;get handle ;an000; dms;
831 mov cs:[bp].MAC_Mult,Type H_LookUp_Struc ;handle lookup table ;an000; dms;
832 mul cs:[bp].MAC_Mult ;obtain index position ;an000; dms;
833 mov cs:[bp].MAC_LookUp_Index,ax ;index to handle ;an000; dms;
834 mov di,ax ;place index in di ;an000; dms;
835
836 cli ;ints off ;an000; dms;
837 mov ax,Handle_LookUp_Table.H_Pages[di] ;get logical page count ;an000; dms;
838 mov cs:[bp].MAC_Xref_Pages,ax ;save logical page count;an000; dms;
839 cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms;
840 sti ;ints on ;an000; dms;
841 jne MAC_Verify_New_Count ;handle good ;an000; dms;
842 mov ah,EMS_Code83 ;EMS handle bad ;an000; dms;
843 jmp MAC_Error_Exit ;exit routine ;an000; dms;
844
845MAC_Verify_New_Count:
846
847 cli ;ints off ;an000; dms;
848 mov ax,Map_Count ;get phys. page count ;an000; dms;
849 sti ;ints on ;an000; dms;
850 cmp [si].MAC_New_Page_Map_Len,al ;> physical pages ;an000; dms;
851 jbe MAC_Verify_Old_Count ;no - continue ;an000; dms;
852 mov ah,EMS_Code8B ;out of range ;an000; dms;
853 jmp MAC_Error_Exit ;exit routine ;an000; dms;
854
855MAC_Verify_Old_Count:
856
857 cli ;ints off ;an000; dms;
858 mov ax,Map_Count ;get phys. page count ;an000; dms;
859 sti ;ints on ;an000; dms;
860 cmp [si].MAC_Old_Page_Map_Len,al ;> physical pages ;an000; dms;
861 jbe MAC_Do_Alter_and_Call ;no - continue ;an000; dms;
862 mov ah,EMS_Code8B ;yes - error ;an000; dms;
863 jmp MAC_Error_Exit ;exit routine ;an000; dms;
864
865MAC_Do_Alter_And_Call:
866
867 jmp MAC_Build_Stack_And_Map ;build stack and map ;an000; dms;
868 ; new pages
869MAC_Return_Routine:
870
871 jmp MAC_Strip_Stack_And_Map ;restore data strucs ;an000; dms;
872 ; and map old pages
873
874MAC_Exit:
875MAC_Error_Exit:
876
877 cli ;ints off ;an000; dms;
878 mov bx,ax ;save ax ;an000; dms;
879 mov ax,cs:[bp].EMS_Reg_FL ;obtain entry flag stat ;an000; dms;
880 sahf ;put in flags reg ;an000; dms;
881 mov ax,bx ;restore ax ;an000; dms;
882 mov bx,cs:[bp].EMS_Reg_BX ; ;an000; dms;
883 mov cx,cs:[bp].EMS_Reg_CX ; ;an000; dms;
884 mov dx,cs:[bp].EMS_Reg_DX ; ;an000; dms;
885 mov di,cs:[bp].EMS_Reg_DI ; ;an000; dms;
886 mov si,cs:[bp].EMS_Reg_SI ; ;an000; dms;
887 mov ds,cs:[bp].EMS_Reg_DS ; ;an000; dms;
888 mov es,cs:[bp].EMS_Reg_ES ; ;an000; dms;
889 sti ;ints on ;an000; dms;
890
891MAC_Stack_Exit:
892
893 ret ;return to caller ;an000; dms;
894
895
896;=========================================================================
897; MAC_Build_Stack_And_Map : This routine will build the required
898; stack structure for a re-entrant
899; routine and map the new pages.
900;
901; Inputs : DS:SI - Pointer to data in Map_And_Call_Struc format
902;
903; Outputs : BP - Instance table to reflect data copyied to it
904; New mapped pages
905; AH - 0 = no error
906; >0 = error (determined by Map_Pages)
907;
908; Instance Table carries this data: Old Map Data
909; New Map Data
910; Map & Call Data
911; Context
912;=========================================================================
913
914MAC_Build_Stack_And_Map:
915
916 mov cs:[bp].EMS_Reg_DS,ds ;save DS ;an000; dms;
917 mov cs:[bp].EMS_Reg_SI,si ;save SI ;an000; dms;
918
919 mov ax,word ptr [si].MAC_Old_Page_Map_Ptr[+2];get the segment ;an000; dms;
920 mov es,ax ; of the old map ;an000; dms;
921 mov di,word ptr [si].MAC_Old_Page_Map_Ptr[+0];get its offset ;an000; dms;
922
923 mov al,[si].MAC_Old_Page_Map_Len ;get length of data ;an000; dms;
924 cbw ;convert to word ;an000; dms;
925 xor dx,dx ;clear high word ;an000; dms;
926 mov bx,Type Log_Phys_Map_Struc ;struc size
927 mul bx ;get total byte count ;an000; dms;
928 cli ;ints off ;an000; dms;
929 mov bx,offset MAC_M_C_Log ;offset in struc ;an000; dms;
930 sti ;ints on ;an000; dms;
931 add bx,bp ;actual offset ;an000; dms;
932 call MAC_Expand_Stack_And_Copy ;set up stack for ;an000; dms;
933 ; copy of data and
934 ; copy the data
935 mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms;
936 mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms;
937
938 mov ax,word ptr [si].MAC_New_Page_Map_Ptr[+2];get the segment ;an000; dms;
939 mov es,ax ; of the old map ;an000; dms;
940 mov di,word ptr [si].MAC_New_Page_Map_Ptr[+0];get its offset ;an000; dms;
941
942 mov al,[si].MAC_New_Page_Map_Len ;get length of data ;an000; dms;
943 cbw ;conver to word ;an000; dms;
944 xor dx,dx ;clear high word ;an000; dms;
945 mov bx,Type Log_Phys_Map_Struc ;struc size
946 mul bx ;get total byte count ;an000; dms;
947 cli ;ints off ;an000; dms;
948 mov bx,offset MAC_M_C_Log ;Ptr in struc ;an000; dms;
949 add bx,size MAC_M_C_Log/2 ;next entry ;an000; dms;
950 sti ;ints on ;an000; dms;
951 add bx,bp ;offset BP relative ;an000; dms;
952 call MAC_Expand_Stack_And_Copy ;set up stack for ;an000; dms;
953 ; copy of data and
954 ; copy the data
955 mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms;
956 mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms;
957
958 mov ax,ds ;move seg of data to ;an000; dms;
959 mov es,ax ; es ;an000; dms;
960 mov di,si ;move off of data ;an000; dms;
961 mov ax,Type Map_And_Call_Struc ;get size of structure ;an000; dms;
962 cli ;ints off ;an000; dms;
963 mov bx,offset MAC_M_C_Data
964 sti ;ints on ;an000; dms;
965 add bx,bp ;offset BP relative ;an000; dms;
966 call MAC_Expand_Stack_And_Copy ;set up stack for ;an000; dms;
967 ; copy of data and
968 ; copy the data
969 mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms;
970 mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms;
971
972 mov ax,cs ;get seg of context ;an000; dms;
973 mov es,ax ; in es ;an000; dms;
974 cli ;ints off ;an000; dms;
975 mov di,offset cs:Map_Table ;get offset of context ;an000; dms;
976 mov ax,Map_Count ;get context entry count;an000; dms;
977 sti ;ints on ;an000; dms;
978 xor dx,dx ;clear dx ;an000; dms;
979 mov bx,Type Mappable_Phys_Page_Struct ;get struc size ;an000; dms;
980 mul bx ;get size in bytes ;an000; dms;
981 cli ;ints off ;an000; dms;
982 mov bx,offset cs:MAC_Map_Table
983 sti ;ints on ;an000; dms;
984 add bx,bp ;offset BP relative ;an000; dms;
985 call MAC_Expand_Stack_And_Copy ;set up stack for ;an000; dms;
986 ; copy of data and
987 ; copy the data
988 mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms;
989 mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms;
990
991 push cs ;save return segment ;an000; dms;
992 mov ax,offset MAC_Return_Routine ;save return offset ;an000; dms;
993 push ax ; ;an000; dms;
994
995 mov ax,word ptr [si].MAC_Target_Address[+2] ;get seg of call far ;an000; dms;
996 mov bx,word ptr [si].MAC_Target_Address[+0] ;get offset of call far ;an000; dms;
997 push ax ;put on stack ;an000; dms;
998 push bx ; ;an000; dms;
999
1000 les di,[si].MAC_New_Page_Map_Ptr ;set up for call ;an000; dms;
1001 xor cx,cx ;clear cx ;an000; dms;
1002 mov cl,[si].MAC_New_Page_Map_Len ;get array size ;an000; dms;
1003 mov dx,cs:[bp].EMS_Reg_DX ;get handle for call ;an000; dms;
1004 mov bx,cs:[bp].MAC_Xref_Pages ;get handle page count ;an000; dms;
1005 xor ah,ah ;clear high word ;an000; dms;
1006 mov al,cs:[bp].MAC_Option ;get option ;an000; dms;
1007
1008 call Map_Pages ;map the new pages ;an000; dms;
1009 or ah,ah ;error? ;an000; dms;
1010 jnz MAC_Error_Strip_Stack ;take data off stack ;an000; dms;
1011
1012 cli ;ints off ;an000; dms;
1013 mov ax,cs:[bp].EMS_Reg_FL ;obtain entry flag stat ;an000; dms;
1014 sahf ;put in flags reg ;an000; dms;
1015 mov bx,cs:[bp].EMS_Reg_BX ; ;an000; dms;
1016 mov cx,cs:[bp].EMS_Reg_CX ; ;an000; dms;
1017 mov dx,cs:[bp].EMS_Reg_DX ; ;an000; dms;
1018 mov di,cs:[bp].EMS_Reg_DI ; ;an000; dms;
1019 mov si,cs:[bp].EMS_Reg_SI ; ;an000; dms;
1020 mov ds,cs:[bp].EMS_Reg_DS ; ;an000; dms;
1021 mov es,cs:[bp].EMS_Reg_ES ; ;an000; dms;
1022 sti ;ints on ;an000; dms;
1023
1024Retf_Fake_Out Proc Far ;this proc is to ;an000; dms;
1025 ; simulate a RETF
1026 ; instruction
1027 ret ;performs a far return ;an000; dms;
1028
1029Retf_Fake_Out Endp ;end of retf fake out ;an000; dms;
1030
1031
1032MAC_Error_Strip_Stack:
1033
1034 add sp,8h ;adjust for return add. ;an000; dms;
1035 ; and target add. on
1036 ; error
1037 jmp MAC_Error_Exit ;exit routine ;an000; dms;
1038
1039
1040;=========================================================================
1041; MAC_Strip_Stack_And_Map : This routine will strip the stack of all
1042; the data placed on by MAC_Build_Stack_And_Map.
1043;
1044; Inputs : CS:BP - Pointer to data on the instance table
1045;
1046; Outputs : All data area restored
1047; Pages remapped to original
1048; AH - 0 = no error
1049; >0 = error (determined by Map_Pages)
1050;
1051; Instance Table carries this data: Old Map Data
1052; New Map Data
1053; Map & Call Data
1054; Context
1055;=========================================================================
1056
1057MAC_Strip_Stack_And_Map: ;an000; dms;
1058
1059 mov ax,cs ;seg of context ;an000; dms;
1060 mov es,ax ;place in es ;an000; dms;
1061 cli ;ints off ;an000; dms;
1062 mov di,offset cs:Map_Table ;get off of context ;an000; dms;
1063 mov ax,Map_Count ;get entries in context ;an000; dms;
1064 sti ;ints on ;an000; dms;
1065 xor dx,dx ;clear dx ;an000; dms;
1066 mov bx,Type Mappable_Phys_Page_Struct ;struc size ;an000; dms;
1067 mul bx ;get byte count ;an000; dms;
1068 cli ;ints off ;an000; dms;
1069 mov bx,offset MAC_Map_Table
1070 sti ;ints on ;an000; dms;
1071 add bx,bp ;offset BP relative ;an000; dms;
1072 call MAC_Shrink_Stack_And_Copy ;restore context ;an000; dms;
1073
1074 mov si,cs:[bp].EMS_Reg_SI ;restore pointer ;an000; dms;
1075 mov ds,cs:[bp].EMS_Reg_DS ; to data struc ;an000; dms;
1076
1077 mov ax,ds ;transfer seg of struc ;an000; dms;
1078 mov es,ax ; to dest. segment ;an000; dms;
1079 mov di,si ;di=dest. offset ;an000; dms;
1080 mov ax,Type Map_And_Call_Struc ;get size to move ;an000; dms;
1081 cli ;ints off ;an000; dms;
1082 mov bx,offset MAC_M_C_Data
1083 sti ;ints on ;an000; dms;
1084 add bx,bp ;offset BP relative ;an000; dms;
1085 call MAC_Shrink_Stack_And_Copy ;restore Map & Call buf ;an000; dms;
1086
1087 mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms;
1088 mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms;
1089
1090 mov ax,word ptr [si].MAC_New_Page_Map_Ptr[+2];get the segment ;an000; dms;
1091 mov es,ax ; of the old map ;an000; dms;
1092 mov di,word ptr [si].MAC_New_Page_Map_Ptr[+0];get its offset ;an000; dms;
1093
1094 mov al,[si].MAC_New_Page_Map_Len ;get length of data ;an000; dms;
1095 cbw ;convert to word ;an000; dms;
1096 xor dx,dx ;clear high word ;an000; dms;
1097 mov bx,Type Log_Phys_Map_Struc ;struc size ;an000; dms;
1098 mul bx ;get total byte count ;an000; dms;
1099 cli ;ints off ;an000; dms;
1100 mov bx,offset MAC_M_C_Log
1101 sti ;ints on ;an000; dms;
1102 add bx,size MAC_M_C_Log/2
1103 add bx,bp ;offset BP relative ;an000; dms;
1104 call MAC_Shrink_Stack_And_Copy ;restore new page data ;an000; dms;
1105
1106 mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms;
1107 mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms;
1108
1109 mov ax,word ptr [si].MAC_Old_Page_Map_Ptr[+2];get the segment ;an000; dms;
1110 mov es,ax ; of the old map ;an000; dms;
1111 mov di,word ptr [si].MAC_Old_Page_Map_Ptr[+0];get its offset ;an000; dms;
1112
1113 mov al,[si].MAC_Old_Page_Map_Len ;get length of data ;an000; dms;
1114 cbw ;convert to word ;an000; dms;
1115 xor dx,dx ;clear high word ;an000; dms;
1116 mov bx,Type Log_Phys_Map_Struc ;struc size ;an000; dms;
1117 mul bx ;get total byte count ;an000; dms;
1118 cli ;ints off ;an000; dms;
1119 mov bx,offset MAC_M_C_Log
1120 sti ;ints on ;an000; dms;
1121 add bx,bp ;offset BP relative ;an000; dms;
1122 call MAC_Shrink_Stack_And_Copy ;set up stack for ;an000; dms;
1123
1124 mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms;
1125 mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms;
1126
1127 mov dx,cs:[bp].EMS_Reg_DX ;get DX reg
1128
1129 les di,[si].MAC_Old_Page_Map_Ptr ;set up for call ;an000; dms;
1130 xor cx,cx ;clear cx ;an000; dms;
1131 mov cl,[si].MAC_Old_Page_Map_Len ;get array size ;an000; dms;
1132 mov bx,cs:[bp].MAC_Xref_Pages ;get handle page count ;an000; dms;
1133 xor ah,ah ;clear high byte ;an000; dms;
1134 mov al,cs:[bp].MAC_Option ;get option ;an000; dms;
1135
1136 call Map_Pages ;map the new pages ;an000; dms;
1137
1138 jmp MAC_Exit ;exit the program ;an000; dms;
1139
1140
1141Alter_And_Call endp ;end proc ;an000; dms;
1142
1143
1144 page
1145;=========================================================================
1146;=============== Function 57h Logic - Move/Exchange Memory Region =======
1147;=========================================================================
1148
1149;=========================================================================
1150; Exchng_Region - This routine moves/exchanges memory regions
1151; specified by the user. The following types of
1152; moves/exchanges are possible:
1153;
1154; Source Destination
1155; ------------------- ----------------------
1156; Conventional Memory Expanded Memory
1157; Expanded Memory Conventional Memory
1158; Expanded Memory Expanded Memory
1159;
1160; Inputs : AH - 57h (Move/Exchange Memory Region)
1161; AL - Type of transfer
1162; 0 = Move memory
1163; 1 = Exchange memory
1164; DS:SI - Pointer to Move_Source_Dest Structure
1165;
1166; Outputs : Revised map
1167; AH - Non-zero if error
1168;=========================================================================
1169
1170
1171Exchng_Region proc
1172
1173 push bx ;save regs ;an000; dms;
1174 push cx ; ;an000; dms;
1175 push dx ; ;an000; dms;
1176 push di ; ;an000; dms;
1177 push si ; ;an000; dms;
1178 push ds ; ;an000; dms;
1179 push es ; ;an000; dms;
1180
1181 mov cs:[bp].ER_Sub_Function,al ;save subfunction ;an000; dms;
1182 cmp al,ER_Max_Function ;valid function? ;an000; dms;
1183 jbe ER_Valid_Sub_Function ;yes - continue ;an000; dms;
1184 mov ah,EMS_Code8F ;no - error ;an000; dms;
1185 jmp ER_Error_Exit ;exit routine ;an000; dms;
1186
1187ER_Valid_Sub_Function:
1188
1189 call ER_Type_Check ;Proper types & ;an000; dms;
1190 or ah,ah ; type combinations? ;an000; dms;
1191 jnz ER_Error_Exit ;no - exit routine ;an000; dms;
1192
1193 call ER_Handle_Check ;valid handles? ;an000; dms;
1194 or ah,ah ; ;an000; dms;
1195 jnz ER_Error_Exit ;no - exit routine ;an000; dms;
1196
1197 call ER_Length_Check ;Region fits in page ;an000; dms;
1198 or ah,ah ; and <= 1Mb? ;an000; dms;
1199 jnz ER_Error_Exit ;no - exit routine ;an000; dms;
1200
1201 call ER_Wrap_Check ;> 1Mb wrap on move? ;an000; dms;
1202 or ah,ah ; ;an000; dms;
1203 jnz ER_Error_Exit ;yes - exit routine ;an000; dms;
1204
1205 call ER_Overlap_Check ;conv. memory overlaps ;an000; dms;
1206 or ah,ah ; EMS page frame? ;an000; dms;
1207 jnz ER_Error_Exit ;yes - exit routine ;an000; dms;
1208
1209 call ER_Log_Page_Test ;offset valid for log. ;an000; dms;
1210 or ah,ah ; page? ;an000; dms;
1211 jnz ER_Error_Exit ;no - exit routine ;an000; dms;
1212
1213 cmp cs:[bp].ER_Sub_Function,ER_Move ;move? ;an000; dms;
1214 je ER_Move_Call ;yes - perform move ;an000; dms;
1215 call ER_EMS_Overlap_Check ;EMS pages overlap? ;an000; dms;
1216 or ah,ah ;
1217 jz ER_Exchange_No_Overlap ;no - exit with error ;an000; dms;
1218 mov ah,EMS_Code97 ;signal error ;an000; dms;
1219 jmp ER_Error_Exit ;exit with error code ;an000; dms;
1220
1221ER_Exchange_No_Overlap:
1222
1223 call ER_Exchange_Data ;no - perform exchange ;an000; dms;
1224 jmp ER_Exit ;exit the routine ;an000; dms;
1225
1226ER_Move_Call:
1227
1228 call ER_EMS_Overlap_Check ;see if we had a move ;an000; dms;
1229 ; overlap
1230 push ax ;save result across call;an000; dms;
1231 call ER_Move_Data ;perform the move ;an000; dms;
1232 pop ax ;restore result ;an000; dms;
1233
1234 ER_Exit:
1235 ER_Error_Exit:
1236
1237 pop es ;restore regs ;an000; dms;
1238 pop ds ; ;an000; dms;
1239 pop si ; ;an000; dms;
1240 pop di ; ;an000; dms;
1241 pop dx ; ;an000; dms;
1242 pop cx ; ;an000; dms;
1243 pop bx ; ;an000; dms;
1244
1245 ret ;return to caller ;an000; dms;
1246
1247Exchng_Region endp
1248
1249
1250;=========================================================================
1251; ER_Handle_Check : This routine checks to see if the EMS handles
1252; specified are valid.
1253;
1254; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data
1255;
1256; Outputs : AH - Non-zero on error
1257; Possible error codes: 83h
1258;=========================================================================
1259
1260ER_Handle_Check proc ;check requested handles;an000; dms;
1261
1262 push dx ;save regs ;an000; dms;
1263 push di ; ;an000; dms;
1264
1265 cmp [si].Source_Memory_Type,ER_Conv_Memory ;Conv memory for source?;an000; dms;
1266 je ER_Handle_Check_Dest ;yes - ck dest. handle ;an000; dms;
1267
1268 push dx ;save dx ;an000; dms;
1269 xor dx,dx ;clear it ;an000; dms;
1270 mov ax,[si].Source_Handle ;get handle requested ;an000; dms;
1271 mov dx,Type H_LookUp_Struc ;handle lookup table ;an000; dms;
1272 mul dx ;obtain index position ;an000; dms;
1273 mov di,ax ;place index in di ;an000; dms;
1274 pop dx ;restore dx ;an000; dms;
1275
1276 cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms;
1277 je ER_Handle_Check_Error_Exit ;handle not allocated ;an000; dms;
1278
1279ER_Handle_Check_Dest:
1280
1281 cmp [si].Dest_Memory_Type,ER_Conv_Memory ;Conv memory for dest? ;an000; dms;
1282 je ER_Handle_Check_Good_Exit ;yes - exit routine ;an000; dms;
1283
1284 push dx ;save dx ;an000; dms;
1285 xor dx,dx ;clear it ;an000; dms;
1286 mov ax,[si].Dest_Handle ;get handle requested ;an000; dms;
1287 mov dx,Type H_LookUp_Struc ;handle lookup table ;an000; dms;
1288 mul dx ;obtain index position ;an000; dms;
1289 mov di,ax ;place index in di ;an000; dms;
1290 pop dx ;restore dx ;an000; dms;
1291
1292 cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms;
1293 je ER_Handle_Check_Error_Exit ;handle not allocated ;an000; dms;
1294
1295ER_Handle_Check_Good_Exit:
1296
1297 xor ah,ah ;signal no error ;an000; dms;
1298 jmp ER_Handle_Check_Exit ;exit program ;an000; dms;
1299
1300ER_Handle_Check_Error_Exit:
1301
1302 mov ah,EMS_Code83 ;signal error ;an000; dms;
1303
1304ER_Handle_Check_Exit:
1305
1306 pop di ;restore regs ;an000; dms;
1307 pop dx ; ;an000; dms;
1308
1309 ret ;return to caller ;an000; dms;
1310
1311ER_Handle_Check endp ;end proc ;an000; dms;
1312
1313
1314
1315;=========================================================================
1316; ER_Length_Check : This routine checks to see if the region length
1317; specified exceeds the page count of either the
1318; source or destination EMS handle pages allocated.
1319; It also checks to determine if the region length
1320; exceeds 1 Mb.
1321;
1322; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data
1323;
1324; Outputs : AH - Non-zero on error
1325; Possible error codes: 93h
1326; 96h
1327; 8Ah
1328;=========================================================================
1329
1330ER_Length_Check proc ;check region length ;an000; dms;
1331
1332 push bx ;save regs ;an000; dms;
1333 push cx ; ;an000; dms;
1334 push dx ; ;an000; dms;
1335 push di ; ;an000; dms;
1336
1337 mov cx,[si].Region_Length_High_Word ;get size of the region ;an000; dms;
1338 mov bx,[si].Region_Length_Low_Word ; in CX:BX ;an000; dms;
1339 cmp cx,ER_10H ;> 1Mb ;an000; dms;
1340 ja ER_Length_Check_Error96 ;exit with error ;an000; dms;
1341 cmp cx,ER_10H ;high word = 10h? ;an000; dms;
1342 jne ER_Length_Check_Cont ;no - continue ;an000; dms;
1343 cmp bx,0 ;low word other than 0? ;an000; dms;
1344 je ER_Length_Check_Cont ;no - good value ;an000; dms;
1345
1346ER_Length_Check_Error96:
1347
1348 mov ah,EMS_Code96 ;signal error ;an000; dms;
1349 jmp ER_Length_Check_Exit ;exit routine
1350
1351ER_Length_Check_Cont:
1352
1353 cmp [si].Source_Memory_Type,ER_Conv_Memory ;Conv memory for source?;an000; dms;
1354 je ER_Length_Check_Dest ;yes - ck dest. length ;an000; dms;
1355
1356 push dx ;save dx ;an000; dms;
1357 xor dx,dx ;clear it ;an000; dms;
1358 mov ax,[si].Source_Handle ;get handle requested ;an000; dms;
1359 mov dx,Type H_LookUp_Struc ;handle lookup table ;an000; dms;
1360 mul dx ;obtain index position ;an000; dms;
1361 mov di,ax ;place index in di ;an000; dms;
1362 pop dx ;restore dx ;an000; dms;
1363
1364 mov ax,Handle_LookUp_Table.H_Pages[di] ;get logical page count ;an000; dms;
1365 ; for source handle
1366 sub ax,[si].Source_Initial_Seg_Page ;pages in EMS to fill ;an000; dms;
1367 push ax ;save ax ;an000; dms;
1368 dec ax ;make it 0 based ;an000; dms;
1369 pop ax ;restore ax ;an000; dms;
1370 js ER_Length_Check_Error8A_Exit ;page out of range ;an000; dms;
1371
1372 xor dx,dx ;clear it ;an000; dms;
1373 mov dx,EMS_Page_Size_In_Bytes+1 ;page size in bytes ;an000; dms;
1374 mul dx ;get total bytes to trf ;an000; dms;
1375 sub ax,[si].Source_Initial_Offset ;get byte count in 1st ;an000; dms;
1376 sbb dx,0
1377
1378 mov bx,ax ;prepare for DWORD comp ;an000; dms;
1379 mov ax,dx ; ;an000; dms;
1380
1381 mov cx,[si].Region_Length_High_Word ;get size of the region ;an000; dms;
1382 mov dx,[si].Region_Length_Low_Word ; in CX:BX ;an000; dms;
1383
1384 call ER_Dword_Compare ;region > target? ;an000; dms;
1385 jc ER_Length_Check_Error93_Exit ;CY = region > target ;an000; dms;
1386
1387
1388ER_Length_Check_Dest:
1389
1390 cmp [si].Dest_Memory_Type,ER_Conv_Memory ;Conv memory for dest? ;an000; dms;
1391 je ER_Length_Check_Good_Exit ;yes - exit routine ;an000; dms;
1392
1393 push dx ;save dx ;an000; dms;
1394 xor dx,dx ;clear it ;an000; dms;
1395 mov ax,[si].Dest_Handle ;get handle requested ;an000; dms;
1396 mov dx,Type H_LookUp_Struc ;handle lookup table ;an000; dms;
1397 mul dx ;obtain index position ;an000; dms;
1398 mov di,ax ;place index in di ;an000; dms;
1399 pop dx ;restore dx ;an000; dms;
1400
1401 mov ax,Handle_LookUp_Table.H_Pages[di] ;get logical page count ;an000; dms;
1402
1403 sub ax,[si].Dest_Initial_Seg_Page ;pages in EMS to fill ;an000; dms;
1404 push ax ;save ax ;an000; dms;
1405 dec ax ;make it 0 based ;an000; dms;
1406 pop ax ;restore ax ;an000; dms;
1407 js ER_Length_Check_Error8A_Exit ;page out of range ;an000; dms;
1408
1409 xor dx,dx ;clear high word ;an000; dms;
1410 mov dx,EMS_Page_Size_In_Bytes+1 ;page size in bytes ;an000; dms;
1411 mul dx ;get total bytes to trf ;an000; dms;
1412 sub ax,[si].Dest_Initial_Offset ;get byte count in 1st ;an000; dms;
1413 sbb dx,0
1414
1415 mov bx,ax ;prepare for DWORD comp ;an000; dms;
1416 mov ax,dx ; ;an000; dms;
1417
1418 mov cx,[si].Region_Length_High_Word ;get size of the region ;an000; dms;
1419 mov dx,[si].Region_Length_Low_Word ; in CX:BX ;an000; dms;
1420
1421 call ER_Dword_Compare ;region > target? ;an000; dms;
1422 jc ER_Length_Check_Error93_Exit ;CY = region > target ;an000; dms;
1423
1424
1425ER_Length_Check_Good_Exit:
1426
1427 xor ah,ah ;signal no error ;an000; dms;
1428 jmp ER_Length_Check_Exit ;exit routine ;an000; dms;
1429
1430ER_Length_Check_Error93_Exit:
1431
1432 mov ah,EMS_Code93 ;signal error ;an000; dms;
1433 jmp ER_Length_Check_Exit ;exit routine ;an000; dms;
1434
1435ER_Length_Check_Error8A_Exit:
1436
1437 mov ah,EMS_Code8A ;signal error ;an000; dms;
1438
1439ER_Length_Check_Exit: ;main exit ;an000; dms;
1440
1441 pop di ;restore regs ;an000; dms;
1442 pop dx ; ;an000; dms;
1443 pop cx ; ;an000; dms;
1444 pop bx ; ;an000; dms;
1445
1446 ret ;return to caller ;an000; dms;
1447
1448ER_Length_Check endp ;end proc ;an000; dms;
1449
1450
1451;=========================================================================
1452; ER_Type_Check : This routine checks the source/destination type
1453; specified to determine if they are within the
1454; proper range.
1455;
1456; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data
1457;
1458; Outputs : AH - Non-zero on error
1459; Possible error codes: 98h
1460;=========================================================================
1461
1462ER_Type_Check proc ;check type ;an000; dms;
1463
1464 cmp [si].Source_Memory_Type,ER_Max_Type ;type within range? ;an000; dms;
1465 ja ER_Type_Check_Error_Exit ;no - error exit ;an000; dms;
1466
1467 cmp [si].Dest_Memory_Type,ER_Max_Type ;type within range? ;an000; dms;
1468 ja ER_Type_Check_Error_Exit ;no - error exit ;an000; dms;
1469
1470
1471ER_Type_Check_Good_Exit:
1472
1473 xor ah,ah ;signal no error ;an000; dms;
1474 jmp ER_Type_Check_Exit ;exit routine ;an000; dms;
1475
1476ER_Type_Check_Error_Exit:
1477
1478 mov ah,EMS_Code98 ;signal error ;an000; dms;
1479
1480ER_Type_Check_Exit:
1481
1482 ret ;return to caller ;an000; dms;
1483
1484ER_Type_Check endp ;end proc ;an000; dms;
1485
1486
1487;=========================================================================
1488; ER_Wrap_Check : This routine checks to determine if there will be
1489; a wrap of conventional memory beyond 1Mb.
1490;
1491; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data
1492;
1493; Outputs : AH - Non-zero on error
1494; Possible error codes: A2h
1495;=========================================================================
1496
1497ER_Wrap_Check proc ;cks. conv. mem. wrap ;an000; dms;
1498
1499 push dx ;save regs ;an000; dms;
1500 push bx ; ;an000; dms;
1501
1502 cmp [si].Source_Memory_Type,ER_Conv_Memory ;conv. memory? ;an000; dms;
1503 jne ER_Wrap_Check_Dest ;no -check dest. ;an000; dms;
1504
1505 mov ax,[si].Source_Initial_Seg_Page ;get segment ;an000; dms;
1506 xor dx,dx ;clear high word ;an000; dms;
1507 mov bx,ER_10H ;adjust segment to ;an000; dms;
1508 ; absolute address
1509 mul bx ; ;an000; dms;
1510 add ax,[si].Source_Initial_Offset ;add in offset ;an000; dms;
1511 adc dx,0 ;pick up carry if any ;an000; dms;
1512
1513 add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms;
1514 ; trf size
1515 adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms;
1516 ; trf size
1517 cmp dx,ER_10H ;> 1Mb? ;an000; dms;
1518 jae ER_Wrap_Check_Error_Exit ;yes - signal error ;an000; dms;
1519 jmp ER_Wrap_Check_Good_Exit ;no - signal no error ;an000; dms;
1520
1521ER_Wrap_Check_Dest:
1522
1523 cmp [si].Dest_Memory_Type,ER_Conv_Memory ;conv. memory? ;an000; dms;
1524 jne ER_Wrap_Check_Good_Exit ;no - exit routine ;an000; dms;
1525
1526 mov ax,[si].Dest_Initial_Seg_Page ;get segment ;an000; dms;
1527 xor dx,dx ;clear high word ;an000; dms;
1528 mov bx,ER_10H ;adjust segment to ;an000; dms;
1529 ; absolute address
1530 mul bx ; ;an000; dms;
1531 add ax,[si].Dest_Initial_Offset ;add in offset ;an000; dms;
1532 adc dx,0 ;pick up carry if any ;an000; dms;
1533
1534 add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms;
1535 ; trf size
1536 adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms;
1537 ; trf size
1538 cmp dx,ER_10H ;> 1Mb? ;an000; dms;
1539 jae ER_Wrap_Check_Error_Exit ;yes - signal error ;an000; dms;
1540
1541ER_Wrap_Check_Good_Exit:
1542
1543 xor ah,ah ;signal no error ;an000; dms;
1544 jmp ER_Wrap_Check_Exit ;exit routine ;an000; dms;
1545
1546ER_Wrap_Check_Error_Exit:
1547
1548 mov ah,EMS_CodeA2 ;signal error ;an000; dms;
1549
1550ER_Wrap_Check_Exit:
1551
1552 pop bx ;restore regs ;an000; dms;
1553 pop dx ; ;an000; dms;
1554
1555 ret ;return to caller ;an000; dms;
1556
1557ER_Wrap_Check endp ;end proc ;an000; dms;
1558
1559
1560;=========================================================================
1561; ER_Overlap_Check : This routine checks to determine if the conventional
1562; memory region and expanded memory region overlap.
1563; Specifically, does the conventional memory region
1564; overlap the physical page addresses used for
1565; expanded memory?
1566;
1567; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data
1568;
1569; Outputs : AH - Non-zero on error
1570; Possible error codes: 94h
1571;
1572; Algorithm :
1573;
1574; If Beg.Src.Add. < Beg.Dst.Add
1575; If (End.Src.Add - Beg.Dst.Add) > 0
1576; signal OVERLAP
1577; Else
1578; signal NO-OVERLAP
1579; EndIf
1580; Else
1581; If (End.Dst.Add - Beg.Src.Add) > 0
1582; signal OVERLAP
1583; Else
1584; signal NO-OVERLAP
1585; EndIf
1586; EndIf
1587;=========================================================================
1588
1589ER_Overlap_Check proc ;check for overlap ;an000; dms;
1590
1591 push dx ;save regs ;an000; dms;
1592 call ER_Save_Context ;save context ;an000; dms;
1593
1594 cmp [si].Source_Memory_Type,ER_Conv_Memory ;conventional memory? ;an000; dms;
1595 je ER_Overlap_Check_Source ;yes - check overlap ;an000; dms;
1596 ;no - see if dest is
1597 ; conv. memory
1598
1599 cmp [si].Dest_Memory_Type,ER_Conv_Memory ;conventional memory? ;an000; dms;
1600 jne ER_Overlap_Jump_Good ;no - exit routine ;an000; dms;
1601
1602ER_Overlap_Check_Dest:
1603
1604 mov di,offset cs:ER_Save_Context_Buffer ;get addressibility to ;an000; dms;
1605 ; the page frame save
1606 ;buffer
1607 add di,bp ;offset BP relative ;an000; dms;
1608 cli ;ints off ;an000; dms;
1609 cmp Map_Count,2 ;>= 2 page frames ;an000; dms;
1610 sti ;ints on ;an000; dms;
1611 jb ER_Overlap_Check_Dest_1_Frame ;no - use 1st. frame ;an000; dms;
1612 add di,Type Mappable_Phys_Page_Struct ;yes - adjust ptr to ;an000; dms;
1613 ; next frame for dest.
1614ER_Overlap_Check_Dest_1_Frame:
1615
1616 ;**** calc abs address of the bottom of EMS transfer area
1617
1618 mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms;
1619 xor dx,dx ;clear high word ;an000; dms;
1620 mov bx,ER_10H ;para size ;an000; dms;
1621 mul bx ;make abs address ;an000; dms;
1622 mov cs:[bp].ER_Src_Abs_Beg_Low,ax ;save abs. address of ;an000; dms;
1623 mov cs:[bp].ER_Src_Abs_Beg_High,dx ; phys page beg. ;an000; dms;
1624
1625 ;**** calc abs address of the top of EMS transfer area
1626
1627 add ax,EMS_Page_Size_In_Bytes ;make abs address ;an000; dms;
1628 adc dx,0 ; ;an000; dms;
1629 mov cs:[bp].ER_Src_Abs_End_Low,ax ;save abs. address ;an000; dms;
1630 mov cs:[bp].ER_Src_Abs_End_High,dx ; of phys page end ;an000; dms;
1631
1632 ;**** calc abs address of the bottom of CONV transfer area
1633
1634 mov ax,[si].Dest_Initial_Seg_Page ;get segment ;an000; dms;
1635 xor dx,dx ;clear high word ;an000; dms;
1636 mov bx,ER_10H ;para size ;an000; dms;
1637 mul bx ;make abs address ;an000; dms;
1638 add ax,[si].Dest_Initial_Offset ;get offset ;an000; dms;
1639 adc dx,0 ;pick up carry ;an000; dms;
1640 mov cs:[bp].ER_Dst_Abs_Beg_Low,ax ;save initial seg start ;an000; dms;
1641 mov cs:[bp].ER_Dst_Abs_Beg_High,dx ;save initial off start ;an000; dms;
1642
1643 ;**** calc abs address of the top of CONV transfer area
1644
1645 add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms;
1646 ; trf size
1647 adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms;
1648 mov cs:[bp].ER_Dst_Abs_End_Low,ax ;save initial seg start ;an000; dms;
1649 mov cs:[bp].ER_Dst_Abs_End_High,dx ;save initial off start ;an000; dms;
1650
1651 call ER_General_Overlap_Test ;test for overlap ;an000; dms;
1652
1653 jc ER_Overlap_Error_Exit ;exit with error ;an000; dms;
1654
1655ER_Overlap_Jump_Good:
1656
1657 jmp ER_Overlap_Good_Exit ;exit good ;an000; dms;
1658
1659ER_Overlap_Check_Source:
1660
1661 mov di,offset cs:ER_Save_Context_Buffer ;get addressibility to ;an000; dms;
1662 ; the page frame save
1663 ;buffer
1664 add di,bp ;offset BP relative ;an000; dms;
1665
1666 ;**** calc abs address of the bottom of EMS transfer area
1667
1668 mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms;
1669 xor dx,dx ;clear high word ;an000; dms;
1670 mov bx,ER_10H ;para size ;an000; dms;
1671 mul bx ;make abs address ;an000; dms;
1672 mov cs:[bp].ER_Src_Abs_Beg_Low,ax ;save abs. address of ;an000; dms;
1673 mov cs:[bp].ER_Src_Abs_Beg_High,dx ; phys page beg. ;an000; dms;
1674
1675 ;**** calc abs address of the top of EMS transfer area
1676
1677 mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms;
1678 mov dx,EMS_Page_Size_In_Bytes ;get end of phys page ;an000; dms;
1679 mov bx,ER_10H ;para size ;an000; dms;
1680 mul bx ;make abs address ;an000; dms;
1681 mov cs:[bp].ER_Src_Abs_End_Low,ax ;save abs. address ;an000; dms;
1682 mov cs:[bp].ER_Src_Abs_End_High,dx ; of phys page end ;an000; dms;
1683
1684 ;**** calc abs address of the bottom of CONV transfer area
1685
1686 mov ax,[si].Source_Initial_Seg_Page ;get segment ;an000; dms;
1687 xor dx,dx ;clear high word ;an000; dms;
1688 mov bx,ER_10H ;para size ;an000; dms;
1689 mul bx ;make abs address ;an000; dms;
1690 add ax,[si].Source_Initial_Offset ;get offset ;an000; dms;
1691 adc dx,0 ;pick up carry ;an000; dms;
1692 mov cs:[bp].ER_Dst_Abs_Beg_Low,ax ;save initial seg start ;an000; dms;
1693 mov cs:[bp].ER_Dst_Abs_Beg_High,dx ;save initial off start ;an000; dms;
1694
1695 ;**** calc abs address of the top of CONV transfer area
1696
1697 add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms;
1698 ; trf size
1699 adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms;
1700 mov cs:[bp].ER_Dst_Abs_End_Low,ax ;save initial seg start ;an000; dms;
1701 mov cs:[bp].ER_Dst_Abs_End_High,dx ;save initial off start ;an000; dms;
1702
1703 call ER_General_Overlap_Test ;test for overlap ;an000; dms;
1704
1705 jnc ER_Overlap_Good_Exit ;exit good ;an000; dms;
1706 jmp ER_Overlap_Error_Exit ;exit bad
1707
1708ER_Overlap_Good_Exit:
1709
1710 xor ah,ah ;signal no error ;an000; dms;
1711 jmp ER_Overlap_Exit ;exit ;an000; dms;
1712
1713ER_Overlap_Error_Exit:
1714
1715 mov ah,EMS_Code94 ;signal error ;an000; dms;
1716
1717ER_Overlap_Exit:
1718
1719 call ER_Restore_Context ;restore context ;an000; dms;
1720
1721 pop dx ;restore regs ;an000; dms;
1722
1723 ret ;return to caller ;an000; dms;
1724
1725ER_Overlap_Check endp ;end proc ;an000; dms;
1726
1727
1728;=========================================================================
1729; ER_EMS_Overlap_Check : This routine determines if the source and target
1730; EMS regions overlap when both the source and target
1731; reside in EMS.
1732;
1733; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data
1734;
1735; Outputs : AH - Non-zero on error
1736; Possible error codes: 92h
1737;
1738; Algorithm :
1739;
1740; If Beg.Src.Add. < Beg.Dst.Add
1741; If (End.Src.Add - Beg.Dst.Add) > 0
1742; signal OVERLAP
1743; Else
1744; signal NO-OVERLAP
1745; EndIf
1746; Else
1747; If (End.Dst.Add - Beg.Src.Add) > 0
1748; signal OVERLAP
1749; Else
1750; signal NO-OVERLAP
1751; EndIf
1752; EndIf
1753;=========================================================================
1754
1755ER_EMS_Overlap_Check proc ;check for overlap ;an000; dms;
1756
1757 push bx ;save regs ;an000; dms;
1758 push dx ; ;an000; dms;
1759
1760 cmp [si].Source_Memory_Type,ER_EMS_Memory ;Source EMS? ;an000; dms;
1761 jne ER_EMS_Overlap_Exit ;no - exit routine ;an000; dms;
1762
1763 cmp [si].Dest_Memory_Type,ER_EMS_Memory ;Dest. EMS? ;an000; dms;
1764 jne ER_EMS_Overlap_Exit ;no - exit routine ;an000; dms;
1765
1766 mov bx,[si].Source_Handle ;get source handle ;an000; dms;
1767 cmp bx,[si].Dest_Handle ;source = dest? ;an000; dms;
1768 jne ER_EMS_Overlap_Good_Exit ;no - exit routine ;an000; dms;
1769
1770ER_EMS_Overlap_Calc_N_Ck:
1771
1772 ;**** calc absolute beginning address of source page
1773
1774 mov ax,[si].Source_Initial_Seg_Page ;get start page ;an000; dms;
1775 xor dx,dx ;clear high word ;an000; dms;
1776 mov bx,EMS_Page_Size_In_Bytes ;get page size ;an000; dms;
1777 mul bx ;convert page to abs ;an000; dms;
1778 ; address
1779 add ax,[si].Source_Initial_Offset ;add in offset value ;an000; dms;
1780 adc dx,0 ;pick up carry ;an000; dms;
1781
1782 mov cs:[bp].ER_Src_Abs_Beg_Low,ax ;save low word of add
1783 mov cs:[bp].ER_Src_Abs_Beg_High,dx ;save high word of add ;an000; dms;
1784
1785 ;**** calc absolute ending address of source page
1786
1787 add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms;
1788 ; length
1789 adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms;
1790 ; length
1791 mov cs:[bp].ER_Src_Abs_End_Low,ax ;save low word of end ;an000; dms;
1792 mov cs:[bp].ER_Src_Abs_End_High,dx ;save high word of end ;an000; dms;
1793
1794 ;**** calc absolute beginning address of dest. page
1795
1796 mov ax,[si].Dest_Initial_Seg_Page ;get start page ;an000; dms;
1797 xor dx,dx ;clear high word ;an000; dms;
1798 mov bx,EMS_Page_Size_In_Bytes ;get page size ;an000; dms;
1799 mul bx ;convert page to abs ;an000; dms;
1800 ; address
1801 add ax,[si].Dest_Initial_Offset ;add in offset value ;an000; dms;
1802 adc dx,0 ;pick up carry ;an000; dms;
1803
1804 mov cs:[bp].ER_Dst_Abs_Beg_Low,ax ;save low word of add
1805 mov cs:[bp].ER_Dst_Abs_Beg_High,dx ;save high word of add ;an000; dms;
1806
1807 ;**** calc absolute ending address of dest. page
1808
1809 add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms;
1810 ; length
1811 adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms;
1812 ; length
1813 mov cs:[bp].ER_Dst_Abs_End_Low,ax ;save low word of end ;an000; dms;
1814 mov cs:[bp].ER_Dst_Abs_End_High,dx ;save high word of end ;an000; dms;
1815
1816 ;**** Actual test for overlap - corresponds to algorithm above
1817
1818 call ER_General_Overlap_Test ;test for overlap ;an000; dms;
1819 jnc ER_EMS_Overlap_Good_Exit ;no error ;an000; dms;
1820
1821ER_EMS_Overlap_Error_Exit:
1822
1823 mov ah,EMS_Code92 ;signal error ;an000; dms;
1824 jmp ER_EMS_Overlap_Exit ;exit ;an000; dms;
1825
1826ER_EMS_Overlap_Good_Exit:
1827
1828 xor ah,ah ;no error ;an000; dms;
1829
1830ER_EMS_Overlap_Exit:
1831
1832 pop dx ;restore regs ;an000; dms;
1833 pop bx ; ;an000; dms;
1834
1835 ret ;return to caller ;an000; dms;
1836
1837ER_EMS_Overlap_Check endp ;end proc ;an000; dms;
1838
1839
1840;=========================================================================
1841; ER_General_Overlap_Test:This routine determines if the source and target
1842; EMS regions overlap when both the source and target
1843; reside in EMS.
1844;
1845; Inputs : ER_Src_Abs_Beg_Low - Low word of beginning trf area of source
1846; ER_Src_Abs_Beg_High - High word of beginning trf area of source
1847;
1848; ER_Src_Abs_End_Low - Low word of ending trf area of source
1849; ER_Src_Abs_End_High - High word of ending trf area of source
1850;
1851; : ER_Dst_Abs_Beg_Low - Low word of beginning trf area of dest.
1852; ER_Dst_Abs_Beg_High - High word of beginning trf area of dest.
1853;
1854; ER_Dst_Abs_End_Low - Low word of ending trf area of dest.
1855; ER_Dst_Abs_End_High - High word of ending trf area of dest.
1856;
1857; Outputs : NC - no overlap
1858; CY - overlap
1859;
1860; Algorithm :
1861;
1862; If Beg.Src.Add. < Beg.Dst.Add
1863; If (End.Src.Add - Beg.Dst.Add) > 0
1864; signal OVERLAP
1865; Else
1866; signal NO-OVERLAP
1867; EndIf
1868; Else
1869; If (End.Dst.Add - Beg.Src.Add) > 0
1870; signal OVERLAP
1871; Else
1872; signal NO-OVERLAP
1873; EndIf
1874; EndIf
1875;=========================================================================
1876
1877ER_General_Overlap_Test proc ; ;an000; dms;
1878
1879 push ax ;save regs ;an000; dms;
1880 push bx ; ;an000; dms;
1881 push cx ; ;an000; dms;
1882 push dx ; ;an000; dms;
1883
1884 mov ax,cs:[bp].ER_Src_Abs_Beg_High ;get source beg. add. ;an000; dms;
1885 mov bx,cs:[bp].ER_Src_Abs_Beg_Low ; ;an000; dms;
1886 mov cx,cs:[bp].ER_Dst_Abs_Beg_High ;get dest. beg. add. ;an000; dms;
1887 mov dx,cs:[bp].ER_Dst_Abs_Beg_Low ; ;an000; dms;
1888 call ER_Dword_Compare ;
1889; $if c ;< dest. beg. add.? ;an000; dms;
1890 JNC ER_IF1
1891 mov ax,cs:[bp].ER_Src_Abs_End_Low ;get end address ;an000; dms;
1892 mov dx,cs:[bp].ER_Src_Abs_End_High ; ;an000; dms;
1893 sub ax,cs:[bp].ER_Dst_Abs_Beg_Low ;End.Src.Add-Beg.Dst.Add;an000; dms;
1894 sbb dx,cs:[bp].ER_Dst_Abs_Beg_High ; ;an000; dms;
1895; $if ns ;yes - overlap ;an000; dms;
1896 JS ER_IF2
1897 stc ;signal error ;an000; dms;
1898 mov cs:[bp].ER_Direction_Flag,ER_Down ;signal reverse move ;an000; dms;
1899; $else ;no - not sure yet ;an000; dms;
1900 JMP SHORT ER_EN2
1901ER_IF2:
1902 clc ;signal no overlap ;an000; dms;
1903 mov cs:[bp].ER_Direction_Flag,ER_Up ;forward move ;an000; dms;
1904; $endif ; ;an000; dms;
1905ER_EN2:
1906; $else ;not sure if src < dst ;an000; dms;
1907 JMP SHORT ER_EN1
1908ER_IF1:
1909 mov ax,cs:[bp].ER_Dst_Abs_End_Low ;get end address ;an000; dms;
1910 mov dx,cs:[bp].ER_Dst_Abs_End_High ; ;an000; dms;
1911 sub ax,cs:[bp].ER_Src_Abs_Beg_Low ;End.Dst.Add-Beg.Src.Add;an000; dms;
1912 sbb dx,cs:[bp].ER_Src_Abs_Beg_High ; ;an000; dms;
1913; $if ns ;yes - overlap ;an000; dms;
1914 JS ER_IF6
1915 stc ;signal error ;an000; dms;
1916 mov cs:[bp].ER_Direction_Flag,ER_Up ;forward move ;an000; dms;
1917; $else ;no - not sure yet ;an000; dms;
1918 JMP SHORT ER_EN6
1919ER_IF6:
1920 clc ;signal no overlap ;an000; dms;
1921 mov cs:[bp].ER_Direction_Flag,ER_Up ;forward move ;an000; dms;
1922; $endif ; ;an000; dms;
1923ER_EN6:
1924; $endif ; ;an000; dms;
1925ER_EN1:
1926
1927 pop dx ;restore regs ;an000; dms;
1928 pop cx ; ;an000; dms;
1929 pop bx ; ;an000; dms;
1930 pop ax ; ;an000; dms;
1931
1932 ret ;return to caller ;an000; dms;
1933
1934ER_General_Overlap_Test endp ;end proc ;an000; dms;
1935
1936
1937;=========================================================================
1938; ER_Dword_Compare : This routine determines whether or not a dword
1939; value is greater than another dword value.
1940;
1941; Inputs : AX - Source high word
1942; BX - Source low word
1943; CX - Destination high word
1944; DX - Destination low word
1945;
1946; Outputs : NC - source >= destination
1947; CY - source < destination
1948;=========================================================================
1949
1950ER_Dword_Compare proc ; ;an000; dms;
1951
1952 cmp ax,cx ;src high < dest high? ;an000; dms;
1953; $if b ;yes ;an000; dms;
1954 JNB ER_IF10
1955 stc ;signal less than ;an000; dms;
1956; $else ;no ;an000; dms;
1957 JMP SHORT ER_EN10
1958ER_IF10:
1959 cmp ax,cx ;src high > dest high? ;an000; dms;
1960; $if a ;yes ;an000; dms;
1961 JNA ER_IF12
1962 clc ;signal greater than ;an000; dms;
1963; $else ;no ;an000; dms;
1964 JMP SHORT ER_EN12
1965ER_IF12:
1966 cmp bx,dx ;src low < dest low? ;an000; dms;
1967; $if b ;yes ;an000; dms;
1968 JNB ER_IF14
1969 stc ;signal less than ;an000; dms;
1970; $else ;no ;an000; dms;
1971 JMP SHORT ER_EN14
1972ER_IF14:
1973 cmp bx,dx ;src low > dest low? ;an000; dms;
1974; $if a ;yes ;an000; dms;
1975 JNA ER_IF16
1976 clc ;signal greater than ;an000; dms;
1977; $else ;no ;an000; dms;
1978 JMP SHORT ER_EN16
1979ER_IF16:
1980 clc ; ;an000; dms;
1981; $endif ; ;an000; dms;
1982ER_EN16:
1983; $endif ; ;an000; dms;
1984ER_EN14:
1985; $endif ; ;an000; dms;
1986ER_EN12:
1987; $endif ; ;an000; dms;
1988ER_EN10:
1989
1990 ret ; ;an000; dms;
1991
1992ER_Dword_Compare endp ; ;an000; dms;
1993
1994
1995
1996;=========================================================================
1997; ER_Segment_Adjust : This routine adjusts the segment:offset to a value
1998; with an offset less than 16.
1999;
2000; Inputs : AX:DX - Segment:Offset to be adjusted
2001;
2002; Outputs : AX:DX - New Segment:Offset value
2003;=========================================================================
2004
2005ER_Segment_Adjust proc ;adjust segment value ;an000; dms;
2006
2007 push bx ;save bx ;an000; dms;
2008 push cx ; ;an000; dms;
2009
2010 mov bx,ax ;save segment value ;an000; dms;
2011 mov ax,dx ;get offset ;an000; dms;
2012 xor dx,dx ;clear high word ;an000; dms;
2013 mov cx,ER_10h ;divide by 10h ;an000; dms;
2014 div cx ;get seg adjustment ;an000; dms;
2015 ; factor
2016 add ax,bx ;adjust segment up ;an000; dms;
2017 ; dx contains new off. ;an000; dms;
2018 pop cx ;restore regs ;an000; dms;
2019 pop bx ;restore bx ;an000; dms;
2020
2021 ret ;return to caller ;an000; dms;
2022
2023ER_Segment_Adjust endp ;end proc ;an000; dms;
2024
2025
2026;=========================================================================
2027; ER_Log_Page_Test : This routine checks the offset specified for
2028; the logical page to determine if the offset is
2029; within the valid ranges for the page size.
2030;
2031; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data
2032;
2033; Outputs : AH - Non-zero on error
2034; Possible error codes: 95h
2035;=========================================================================
2036
2037ER_Log_Page_Test proc ; ;an000; dms;
2038
2039 mov ax,EMS_Page_Size_In_Bytes ;get page size ;an000; dms;
2040
2041 cmp [si].Source_Memory_Type,ER_EMS_Memory ;EMS memory specified? ;an000; dms;
2042 jne ER_Log_Dest_Test ;no - check dest. ;an000; dms;
2043
2044 cmp ax,[si].Source_Initial_Offset ;> EMS page size ;an000; dms;
2045 jae ER_Log_Good_Exit ;good exit ;an000; dms;
2046 jmp ER_Log_Error_Exit ;error - bad exit ;an000; dms;
2047
2048ER_Log_Dest_Test:
2049
2050 cmp [si].Dest_Memory_Type,ER_EMS_Memory ;EMS memory specified? ;an000; dms;
2051 jne ER_Log_Good_Exit ;good exit ;an000; dms;
2052
2053 cmp ax,[si].Dest_Initial_Offset ;> EMS page size ;an000; dms;
2054 jae ER_Log_Good_Exit ;good exit ;an000; dms;
2055
2056ER_Log_Error_Exit:
2057
2058 mov ah,EMS_Code95 ;signal error ;an000; dms;
2059 jmp ER_Log_Exit ;exit routine ;an000; dms;
2060
2061ER_Log_Good_Exit:
2062
2063 xor ah,ah ;signal no error ;an000; dms;
2064
2065ER_Log_Exit:
2066
2067 ret ;return to caller ;an000; dms;
2068
2069ER_Log_Page_Test endp ;end proc ;an000; dms;
2070
2071;=========================================================================
2072; ER_Save_Context : This routine saves the context for page frames
2073; needed for the move/exchange.
2074;
2075; Inputs : none
2076;
2077; Outputs : ER_Save_Context_Buffer - save context for the needed page frames
2078;=========================================================================
2079
2080ER_Save_Context proc ;save contexts ;an000; dms;
2081
2082 push ax ;save regs ;an000; dms;
2083 push cx ; ;an000; dms;
2084 push di ; ;an000; dms;
2085 push si ; ;an000; dms;
2086 push ds ; ;an000; dms;
2087 push es ; ;an000; dms;
2088
2089 mov ax,cs ;make ds/es = cs ;an000; dms;
2090 mov ds,ax ; ;an000; dms;
2091 mov es,ax ; ;an000; dms;
2092
2093 mov si,offset cs:Map_Table ;ptr to page frame table;an000; dms;
2094 mov di,offset cs:ER_Save_Context_Buffer ;get dest. offset
2095 add di,bp ;offset BP relative ;an000; dms;
2096
2097 mov cx,2 ;default frame save ;an000; dms;
2098 cli ;ints off ;an000; dms;
2099 cmp Map_Count,2 ;2 page frames? ;an000; dms;
2100 jae ER_Save_Context_Loop ;< = 2 - continue ;an000; dms;
2101 mov cx,Map_Count ;max frame count to save;an000; dms;
2102
2103ER_Save_Context_Loop:
2104
2105 sti ;ints on ;an000; dms;
2106 push cx ;save cx ;an000; dms;
2107 mov cx,Type Mappable_Phys_Page_Struct ;get byte count to trf ;an000; dms;
2108 cli ;ints off ;an000; dms;
2109 rep movsb ;perform save ;an000; dms;
2110 sti ;ints on ;an000; dms;
2111 pop cx ;restore cx ;an000; dms;
2112 loop ER_Save_Context_Loop ;continue ;an000; dms;
2113
2114ER_Save_Exit:
2115
2116 pop es ;restore regs ;an000; dms;
2117 pop ds ; ;an000; dms;
2118 pop si ; ;an000; dms;
2119 pop di ; ;an000; dms;
2120 pop cx ; ;an000; dms;
2121 pop ax ; ;an000; dms;
2122
2123 ret ;return to caller ;an000; dms;
2124
2125ER_Save_Context endp ;end proc ;an000; dms;
2126
2127
2128;=========================================================================
2129; ER_Restore_Context : This routine restores the context for page frames
2130; saved. These pages were used for the
2131; move/exchange requested.
2132;
2133; Inputs : ER_Save_Context_Buffer - contains saved context
2134;
2135; Outputs : restored context for the saved page frames
2136;=========================================================================
2137
2138ER_Restore_Context proc ;restore contexts ;an000; dms;
2139
2140 push ax ;save regs ;an000; dms;
2141 push cx ; ;an000; dms;
2142 push di ; ;an000; dms;
2143 push si ; ;an000; dms;
2144 push ds ; ;an000; dms;
2145 push es ; ;an000; dms;
2146
2147 mov ax,cs ;make ds/es = cs ;an000; dms;
2148 mov ds,ax ; ;an000; dms;
2149 mov es,ax ; ;an000; dms;
2150
2151 mov di,offset cs:Map_Table ;ptr to page frame table;an000; dms;
2152 mov si,offset cs:ER_Save_Context_Buffer ;get dest. offset
2153 add si,bp ;offset BP relative ;an000; dms;
2154
2155 mov cx,2 ;default frame restore ;an000; dms;
2156 cli ;ints off ;an000; dms;
2157 cmp Map_Count,2 ;2 page frames? ;an000; dms;
2158 jae ER_Restore_Context_Loop ;< = 2 - continue ;an000; dms;
2159 mov cx,Map_Count ;max frame count to rest;an000; dms;
2160
2161ER_Restore_Context_Loop:
2162
2163 sti ;ints on ;an000; dms;
2164 mov al,byte ptr ds:[si].Phys_Page_Number ;get physical page num. ;an000; dms;
2165 mov bx,word ptr ds:[si].PPM_Log_Page ;get logical page num. ;an000; dms;
2166 mov dx,word ptr ds:[si].PPM_Handle ;get handle number ;an000; dms;
2167 call Map_L_To_P ;map in orig. page ;an000; dms;
2168
2169 push cx ;save cx ;an000; dms;
2170 mov cx,Type Mappable_Phys_Page_Struct ;get byte count to trf ;an000; dms;
2171 cli ;ints off ;an000; dms;
2172 rep movsb ;perform save ;an000; dms;
2173 sti ;ints on ;an000; dms;
2174 pop cx ;restore cx ;an000; dms;
2175 loop ER_Restore_Context_Loop ;continue ;an000; dms;
2176
2177ER_Restore_Exit:
2178
2179 pop es ;restore regs ;an000; dms;
2180 pop ds ; ;an000; dms;
2181 pop si ; ;an000; dms;
2182 pop di ; ;an000; dms;
2183 pop cx ; ;an000; dms;
2184 pop ax ; ;an000; dms;
2185
2186 ret ;return to caller ;an000; dms;
2187
2188ER_Restore_Context endp ;end proc ;an000; dms;
2189
2190
2191
2192;=========================================================================
2193; ER_Det_Src_Dest_Seg : This routine determines the applicable segment,
2194; offset, and page to be used for the move/exchange.
2195; This routine sets the pages/addresses to the end
2196; of the area to be moved/exchanged, if the move
2197; is to be a reverse move. If the move is to be
2198; a forward move, the pages/addresses are set to
2199; the beginning of the area to be moved/exchanged.
2200; In this way an overlapping move can be
2201; performed without overlaying data it is to move.
2202;
2203; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data
2204;
2205; Outputs : ER_Source_Seg - Segment value of source
2206; ER_Dest_Seg - Segment value of destination
2207;
2208; ER_Source_Off - Offset value of source
2209; ER_Dest_Off - Offset value of destination
2210;
2211; ER_Source_Page - Source EMS page
2212; ER_Dest_Page - Destination EMS page
2213;
2214; ER_Source_Handle - Source handle
2215; ER_Dest_Handle - Destination handle
2216;
2217; ER_Source_Phys_Page - Physical page number
2218; ER_Dest_Phys_Page - Physical page number
2219;=========================================================================
2220
2221ER_Det_Src_Dest_Seg proc ; ;an000; dms;
2222
2223 push ax ;save regs ;an000; dms;
2224 push bx ; ;an000; dms;
2225 push cx ; ;an000; dms;
2226 push dx ; ;an000; dms;
2227 push di ; ;an000; dms;
2228 push ds ; ;an000; dms;
2229 push es ; ;an000; dms;
2230
2231
2232 cmp [si].Source_Memory_Type,ER_EMS_Memory ;EMS? ;an000; dms;
2233 jne ER_Det_Source_Conv ;no - conventional mem. ;an000; dms;
2234
2235 mov di,offset cs:ER_Save_Context_Buffer ;get addressibility to ;an000; dms;
2236 ; the page frame save
2237 ;buffer
2238 add di,bp ;offset BP relative
2239 mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms;
2240 mov cs:[bp].ER_Source_Seg,ax ;save it in variable ;an000; dms;
2241
2242 mov ax,[si].Source_Handle ;get source handle ;an000; dms;
2243 mov cs:[bp].ER_Source_Handle,ax ;save handle ;an000; dms;
2244
2245 cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms;
2246; $if e ;yes ;an000; dms;
2247 JNE ER_IF22
2248 mov ax,[si].Region_Length_Low_Word ;get low word of move ;an000; dms;
2249 mov dx,[si].Region_Length_High_Word ;get high word ;an000; dms;
2250 add ax,[si].Source_Initial_Offset ;pick up offset value ;an000; dms;
2251 adc dx,0 ;pick up carry ;an000; dms;
2252 mov bx,4000h ;get page size ;an000; dms;
2253 div bx ;get end logical page ;an000; dms;
2254 add ax,[si].Source_Initial_Seg_Page ;adjust it for 1st. ;an000; dms;
2255 mov cs:[bp].ER_Source_Page,ax ;save log. page ;an000; dms;
2256 dec dx ;adjust to end point ;an000; dms;
2257 mov cs:[bp].ER_Source_Off,dx ;save offset in last pg ;an000; dms;
2258
2259; $else ;forward move ;an000; dms;
2260 JMP SHORT ER_EN22
2261ER_IF22:
2262 mov ax,[si].Source_Initial_Seg_Page ;get page ;an000; dms;
2263 mov dx,[si].Source_Initial_Offset ;get offset ;an000; dms;
2264 mov cs:[bp].ER_Source_Page,ax ;save page ;an000; dms;
2265 mov cs:[bp].ER_Source_Off,dx ;save offset ;an000; dms;
2266; $endif ; ;an000; dms;
2267ER_EN22:
2268 mov ax,cs:[di].Phys_Page_Number ;get phys. page ;an000; dms;
2269 mov cs:[bp].ER_Source_Phys_Page,ax ;save it ;an000; dms;
2270 jmp ER_Det_Dest_Check ;jump to dest check ;an000; dms;
2271
2272ER_Det_Source_Conv:
2273
2274 cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms;
2275; $if e ;yes ;an000; dms;
2276 JNE ER_IF25
2277 mov ax,[si].Region_Length_Low_Word ;get low word of move ;an000; dms;
2278 mov dx,[si].Region_Length_High_Word ;get high word ;an000; dms;
2279 mov bx,ER_10h ;get bytes/para ;an000; dms;
2280 div bx ;get para count ;an000; dms;
2281 ; AX = para's
2282 ; DX = offset
2283 mov bx,ax ;save across adjust call;an000; dms;
2284 mov cx,dx ; ;an000; dms;
2285 mov ax,[si].Source_Initial_Seg_Page ;get seg value ;an000; dms;
2286 mov dx,[si].Source_Initial_Offset ;get off value ;an000; dms;
2287 dec dx ;adjust to end byte
2288 call ER_Segment_Adjust ;adjust it downward ;an000; dms;
2289 add ax,bx ;new segment value ;an000; dms;
2290 add dx,cx ;new offset value ;an000; dms;
2291
2292 mov cs:[bp].ER_Source_Seg,ax ;save it in variable ;an000; dms;
2293 mov cs:[bp].ER_Source_Off,dx ;save offset in var ;an000; dms;
2294; $else ;forward move ;an000; dms;
2295 JMP SHORT ER_EN25
2296ER_IF25:
2297 mov ax,[si].Source_Initial_Seg_Page ;get seg value ;an000; dms;
2298 mov dx,[si].Source_Initial_Offset ;get off value ;an000; dms;
2299 mov cs:[bp].ER_Source_Seg,ax ;save it in variable ;an000; dms;
2300 mov cs:[bp].ER_Source_Off,dx ;save offset in var ;an000; dms;
2301; $endif ; ;an000; dms;
2302ER_EN25:
2303
2304
2305ER_Det_Dest_Check:
2306
2307 cmp [si].Dest_Memory_Type,ER_EMS_Memory ;Dest. EMS? ;an000; dms;
2308 jne ER_Det_Dest_Conv ;no - conventional mem. ;an000; dms;
2309
2310 mov di,offset cs:ER_Save_Context_Buffer ;save frame buffer ;an000; dms;
2311 add di,bp ;offset BP relative ;an000; dms;
2312 cli ;ints off ;an000; dms;
2313 cmp Map_Count,1 ;> 1 page frame? ;an000; dms;
2314 sti ;ints on ;an000; dms;
2315 jb ER_Det_Dest_Check1 ;don't adjust pointer ;an000; dms;
2316 add di,Type Mappable_Phys_Page_Struct ;next entry in save buf ;an000; dms;
2317
2318ER_Det_Dest_Check1:
2319
2320 mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms;
2321 mov cs:[bp].ER_Dest_Seg,ax ;save it in variable ;an000; dms;
2322
2323 mov ax,[si].Dest_Handle ;get dest. handle ;an000; dms;
2324 mov cs:[bp].ER_Dest_Handle,ax ;save handle ;an000; dms;
2325
2326 cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms;
2327; $if e ;yes ;an000; dms;
2328 JNE ER_IF28
2329 mov ax,[si].Region_Length_Low_Word ;get low word of move ;an000; dms;
2330 mov dx,[si].Region_Length_High_Word ;get high word ;an000; dms;
2331 add ax,[si].Dest_Initial_Offset ;pick up offset value ;an000; dms;
2332 adc dx,0 ;pick up carry ;an000; dms;
2333
2334 mov bx,4000h ;get page size ;an000; dms;
2335 div bx ;get end logical page ;an000; dms;
2336 add ax,[si].Dest_Initial_Seg_Page ;adjust it for 1st. ;an000; dms;
2337 mov cs:[bp].ER_Dest_Page,ax ;save log. page ;an000; dms;
2338 dec dx ;adjust to end point ;an000; dms;
2339 mov cs:[bp].ER_Dest_Off,dx ;save off. in last page ;an000; dms;
2340
2341; $else ;forward move ;an000; dms;
2342 JMP SHORT ER_EN28
2343ER_IF28:
2344 mov ax,[si].Dest_Initial_Seg_Page ;get page ;an000; dms;
2345 mov dx,[si].Dest_Initial_Offset ;get offset ;an000; dms;
2346 mov cs:[bp].ER_Dest_Page,ax ;save log. page ;an000; dms;
2347 mov cs:[bp].ER_Dest_Off,dx ;save off. in last page ;an000; dms;
2348; $endif ; ;an000; dms;
2349ER_EN28:
2350 mov ax,cs:[di].Phys_Page_Number ;get phys page number ;an000; dms;
2351 mov cs:[bp].ER_Dest_Phys_Page,ax ;save it ;an000; dms;
2352 jmp ER_Det_Exit ;exit routine ;an000; dms;
2353
2354ER_Det_Dest_Conv:
2355
2356 cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms;
2357; $if e ;yes ;an000; dms;
2358 JNE ER_IF31
2359 mov ax,[si].Region_Length_Low_Word ;get low word of move ;an000; dms;
2360 mov dx,[si].Region_Length_High_Word ;get high word ;an000; dms;
2361 mov bx,ER_10H ;get bytes/para ;an000; dms;
2362 div bx ;get para count ;an000; dms;
2363 ; AX = para's
2364 ; DX = offset
2365 mov bx,ax ;save across adjust call;an000; dms;
2366 mov cx,dx ; ;an000; dms;
2367 mov ax,[si].Dest_Initial_Seg_Page ;get seg value ;an000; dms;
2368 mov dx,[si].Dest_Initial_Offset ;get off value ;an000; dms;
2369 dec dx ;adjust to end byte ;an000; dms;
2370 call ER_Segment_Adjust ;adjust it downward ;an000; dms;
2371 add ax,bx ;new segment value ;an000; dms;
2372 add dx,cx ;new offset value ;an000; dms;
2373
2374 mov cs:[bp].ER_Dest_Seg,ax ;save it in variable ;an000; dms;
2375 mov cs:[bp].ER_Dest_Off,dx ;save offset in var ;an000; dms;
2376; $else ;forward move ;an000; dms;
2377 JMP SHORT ER_EN31
2378ER_IF31:
2379 mov ax,[si].Dest_Initial_Seg_Page ;get seg value ;an000; dms;
2380 mov dx,[si].Dest_Initial_Offset ;get off value ;an000; dms;
2381 mov cs:[bp].ER_Dest_Seg,ax ;save it in variable ;an000; dms;
2382 mov cs:[bp].ER_Dest_Off,dx ;save offset in var ;an000; dms;
2383; $endif ; ;an000; dms;
2384ER_EN31:
2385
2386
2387ER_Det_Exit:
2388
2389 pop es ;restore regs ;an000; dms;
2390 pop ds ; ;an000; dms;
2391 pop di ; ;an000; dms;
2392 pop dx ; ;an000; dms;
2393 pop cx ; ;an000; dms;
2394 pop bx ; ;an000; dms;
2395 pop ax ; ;an000; dms;
2396
2397 ret ;return to caller ;an000; dms;
2398
2399ER_Det_Src_Dest_Seg endp ;end proc ;an000; dms;
2400
2401
2402;=========================================================================
2403; ER_Det_Move_Count : This initializes the count variables for the
2404; loop iteration counter of the move/exchange.
2405;
2406; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data
2407;
2408; Outputs : ER_Move_Count_Low - low word value of move count
2409; ER_Move_Count_High - high word value of move count
2410;=========================================================================
2411
2412
2413ER_Det_Move_Count proc ; ;an000; dms;
2414
2415 push ax ;save regs ;an000; dms;
2416 push dx ; ;an000; dms;
2417
2418 mov ax,[si].Region_Length_Low_Word ;get low word count ;an000; dms;
2419 mov dx,[si].Region_Length_High_Word ;get high word count ;an000; dms;
2420 mov cs:[bp].ER_Move_Count_Low,ax ;save low word ;an000; dms;
2421 mov cs:[bp].ER_Move_Count_High,dx ;save high word ;an000; dms;
2422
2423 pop dx ;restore regs ;an000; dms;
2424 pop ax ; ;an000; dms;
2425
2426 ret ;return to caller ;an000; dms;
2427
2428ER_Det_Move_Count endp ;end proc ;an000; dms;
2429
2430;=========================================================================
2431; ER_Move_Source_To_Buffer : This routine moves the source data to
2432; the buffer before it is transferred to
2433; its final destination.
2434;
2435; Inputs : BP - carries type of memory for source/dest
2436; Bit 0 - Destination (EMS if set)
2437; Bit 1 - Source (EMS if set)
2438;
2439; Outputs : ER_Move_Xchg_Buffer1 - Source data
2440;=========================================================================
2441
2442ER_Move_Source_To_Buffer proc ; ;an000; dms;
2443
2444 push ax ;save regs ;an000; dms;
2445 push bx ; ;an000; dms;
2446 push dx ; ;an000; dms;
2447 push di ; ;an000; dms;
2448 push es ; ;an000; dms;
2449
2450 test cs:[bp].ER_Mem_Type,ER_Source_EMS_Memory;Source EMS? ;an000; dms;
2451 jz ER_Move_Source_Conv_Mem ;no - adjust seg:off ;an000; dms;
2452 jmp ER_Move_Source_EMS_Mem ;yes- continue move ;an000; dms;
2453
2454ER_Move_Source_Conv_Mem:
2455
2456 cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms;
2457; $if e ;yes ;an000; dms;
2458 JNE ER_IF34
2459 mov ax,ds ;adjust segment:off ;an000; dms;
2460 dec ax ;segment - 1 para ;an000; dms;
2461 mov ds,ax ; ;an000; dms;
2462 add si,ER_10H ;adjust offset for 1 ;an000; dms;
2463; $else ;forward move ;an000; dms;
2464 JMP SHORT ER_EN34
2465ER_IF34:
2466 mov ax,ds ;get segment value ;an000; dms;
2467 mov dx,si ;get offset value ;an000; dms;
2468 call ER_Segment_Adjust ;adjust the seg:off ;an000; dms;
2469 mov ds,ax ;restore ds ;an000; dms;
2470 mov si,dx ;restore offset ;an000; dms;
2471; $endif ; ;an000; dms;
2472ER_EN34:
2473 jmp ER_Move_Source_Count ;determine count ;an000; dms;
2474
2475ER_Move_Source_EMS_Mem:
2476
2477
2478 cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms;
2479; $if e ;yes ;an000; dms;
2480 JNE ER_IF37
2481 cmp si,0ffffh ;beginning of log page ;an000; dms;
2482; $if e ;yes ;an000; dms;
2483 JNE ER_IF38
2484 dec cs:[bp].ER_Source_Page ;adjust page ptr ;an000; dms;
2485 mov si,EMS_Page_Size_In_Bytes;get page size ;an000; dms;
2486; $endif ; ;an000; dms;
2487ER_IF38:
2488; $else ;forward move ;an000; dms;
2489 JMP SHORT ER_EN37
2490ER_IF37:
2491 cmp si,4000h ;wrap beyond page ;an000; dms;
2492; $if e ;yes ;an000; dms;
2493 JNE ER_IF41
2494 inc cs:[bp].ER_Source_Page ;adjust page ptr ;an000; dms;
2495 xor si,si ;clear si ;an000; dms;
2496; $endif ; ;an000; dms;
2497ER_IF41:
2498; $endif ; ;an000; dms;
2499ER_EN37:
2500 mov bx,cs:[bp].ER_Source_Page ;pass page to map ;an000; dms;
2501 call ER_Map_Next_Src_Page ;no - map in current pg;an000; dms;
2502
2503ER_Move_Source_Count:
2504
2505 mov cx,ER_10H ;default count ;an000; dms;
2506 cmp cs:[bp].ER_Move_Count_High,0 ;high word set ;an000; dms;
2507 jne ER_Move_Source_High_Set ;yes - use default ;an000; dms;
2508 cmp cs:[bp].ER_Move_Count_Low,cx ;>= 10h bytes ;an000; dms;
2509 jae ER_Move_Source_High_Set ;yes - use default ;an000; dms;
2510 mov cx,cs:[bp].ER_Move_Count_Low ;no - use last few bytes;an000; dms;
2511
2512ER_Move_Source_High_Set:
2513
2514 cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms;
2515; $if e ;yes ;an000; dms;
2516 JNE ER_IF44
2517 cmp si,di ;source >= dest? ;an000; dms;
2518; $if b ;no ;an000; dms;
2519 JNB ER_IF45
2520 cmp si,ER_10H ;source >= 10h? ;an000; dms;
2521; $if b ;no ;an000; dms;
2522 JNB ER_IF46
2523 mov cx,si ;get move count ;an000; dms;
2524 inc cx ;always 1 byte off ;an000; dms;
2525; $endif ; ;an000; dms;
2526ER_IF46:
2527; $else ;source >= dest ;an000; dms;
2528 JMP SHORT ER_EN45
2529ER_IF45:
2530 cmp di,ER_10H ;dest >= 10h? ;an000; dms;
2531; $if b ;no ;an000; dms;
2532 JNB ER_IF49
2533 mov cx,di ;get move count ;an000; dms;
2534 inc cx ;always 1 byte off ;an000; dms;
2535; $endif ; ;an000; dms;
2536ER_IF49:
2537; $endif ; ;an000; dms;
2538ER_EN45:
2539; $else ;forward move ;an000; dms;
2540 JMP SHORT ER_EN44
2541ER_IF44:
2542 cmp si,di ;source >= dest? ;an000; dms;
2543; $if a ;yes ;an000; dms;
2544 JNA ER_IF53
2545 mov ax,4000h ;get end of page ;an000; dms;
2546 sub ax,si ;get bytes remaining ;an000; dms;
2547 cmp ax,ER_10H ;source >= 10h ;an000; dms;
2548; $if b ;no ;an000; dms;
2549 JNB ER_IF54
2550 mov cx,ax ;get remaining count ;an000; dms;
2551; $endif ; ;an000; dms;
2552ER_IF54:
2553; $else ;source >= dest ;an000; dms;
2554 JMP SHORT ER_EN53
2555ER_IF53:
2556 mov ax,4000h ;get end of page ;an000; dms;
2557 sub ax,di ;get bytes remaining ;an000; dms;
2558 cmp ax,ER_10H ;dest >= 10h ;an000; dms;
2559; $if b ;no ;an000; dms;
2560 JNB ER_IF57
2561 mov cx,ax ;get remaining count ;an000; dms;
2562; $endif ; ;an000; dms;
2563ER_IF57:
2564; $endif ; ;an000; dms;
2565ER_EN53:
2566; $endif ; ;an000; dms;
2567ER_EN44:
2568
2569 jmp ER_Move_Source_Default_Count ;continue routine ;an000; dms;
2570
2571ER_Move_Source_Default_Count:
2572
2573 mov cs:[bp].ER_Current_Move_Count,cx ;save current move cnt ;an000; dms;
2574
2575 sub cs:[bp].ER_Move_Count_Low,cx ;get new count ;an000; dms;
2576 sbb cs:[bp].ER_Move_Count_High,0 ;pick up borrow ;an000; dms;
2577
2578 mov ax,cs ;get seg for buffer ;an000; dms;
2579 mov es,ax ;put into es ;an000; dms;
2580 mov di,offset cs:ER_Move_Xchg_Buffer1 ;offset of buffer ;an000; dms;
2581 add di,bp ;offset BP relative ;an000; dms;
2582
2583 cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms;
2584; $if e ;yes ;an000; dms;
2585 JNE ER_IF61
2586 add di,ER_10H ;end of buffer + 1 ;an000; dms;
2587 dec di ;end of buffer ;an000; dms;
2588; $endif ; ;an000; dms;
2589ER_IF61:
2590
2591
2592 cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms;
2593; $if e ;yes ;an000; dms;
2594 JNE ER_IF63
2595 std ;reverse move ;an000; dms;
2596; $else ;forward move ;an000; dms;
2597 JMP SHORT ER_EN63
2598ER_IF63:
2599 cld ; ;an000; dms;
2600; $endif ; ;an000; dms;
2601ER_EN63:
2602 cli ;ints off ;an000; dms;
2603 rep movsb ;move the data ;an000; dms;
2604 sti ;ints on ;an000; dms;
2605
2606ER_Move_Source_Exit:
2607
2608 pop es ;restore regs ;an000; dms;
2609 pop di ; ;an000; dms;
2610 pop dx ; ;an000; dms;
2611 pop bx ; ;an000; dms;
2612 pop ax ; ;an000; dms;
2613
2614 ret ;return to caller ;an000; dms;
2615
2616ER_Move_Source_To_Buffer endp ;end proc ;an000; dms;
2617
2618
2619;=========================================================================
2620; ER_Move_Buffer_To_Dest : This routine moves the data in the buffer
2621; to the destination specified by the user.
2622;
2623; Inputs : BP - carries type of memory for source/dest
2624; Bit 0 - Destination (EMS if set)
2625; Bit 1 - Source (EMS if set)
2626; ER_Move_Xchg_Buffer1 - Source data
2627;
2628; Outputs : Adjusted segment:offset or page/offset
2629;=========================================================================
2630
2631ER_Move_Buffer_To_Dest proc ; ;an000; dms;
2632
2633 push ax ;save regs ;an000; dms;
2634 push bx ; ;an000; dms;
2635 push dx ; ;an000; dms;
2636 push si ; ;an000; dms;
2637 push ds ; ;an000; dms;
2638
2639 test cs:[bp].ER_Mem_Type,ER_Dest_EMS_Memory ;Source EMS? ;an000; dms;
2640 jz ER_Move_Buffer_Conv_Mem ;no - adjust seg:off ;an000; dms;
2641 jmp ER_Move_Buffer_EMS_Mem ;yes- continue move ;an000; dms;
2642
2643ER_Move_Buffer_Conv_Mem:
2644
2645 cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms;
2646; $if e ;yes ;an000; dms;
2647 JNE ER_IF66
2648 mov ax,es ;adjust segment:off ;an000; dms;
2649 dec ax ;segment - 1 para ;an000; dms;
2650 mov es,ax ; ;an000; dms;
2651 add di,ER_10H ;adjust offset for 1 ;an000; dms;
2652; $else ;forward move? ;an000; dms;
2653 JMP SHORT ER_EN66
2654ER_IF66:
2655 mov ax,es ;adjust seg:off ;an000; dms;
2656 mov dx,di ; ;an000; dms;
2657 call ER_Segment_Adjust ; ;an000; dms;
2658 mov es,ax ;new seg:off ;an000; dms;
2659 mov di,dx ; ;an000; dms;
2660; $endif ; ;an000; dms;
2661ER_EN66:
2662 ; para
2663 jmp ER_Move_Buffer_Count ;determine count ;an000; dms;
2664
2665ER_Move_Buffer_EMS_Mem:
2666
2667 cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms;
2668; $if e ;yes ;an000; dms;
2669 JNE ER_IF69
2670 cmp di,0ffffh ;beginning of log page ;an000; dms;
2671; $if e ;yes ;an000; dms;
2672 JNE ER_IF70
2673 dec cs:[bp].ER_Dest_Page ;next page ;an000; dms;
2674 mov di,EMS_Page_Size_In_Bytes;end of page ;an000; dms;
2675; $endif ; ;an000; dms;
2676ER_IF70:
2677; $else ;forward move ;an000; dms;
2678 JMP SHORT ER_EN69
2679ER_IF69:
2680 cmp di,4000h ;end of page? ;an000; dms;
2681; $if e ;yes ;an000; dms;
2682 JNE ER_IF73
2683 inc cs:[bp].ER_Dest_Page ;next page ;an000; dms;
2684 xor di,di ;clear di ;an000; dms;
2685; $endif ; ;an000; dms;
2686ER_IF73:
2687; $endif ; ;an000; dms;
2688ER_EN69:
2689 mov bx,cs:[bp].ER_Dest_Page ;pass page to map ;an000; dms;
2690 call ER_Map_Next_Dest_Page ;map in the page ;an000; dms;
2691
2692ER_Move_Buffer_Count:
2693
2694 mov cx,cs:[bp].ER_Current_Move_Count ;get move from source ;an000; dms;
2695
2696 mov ax,cs ;get seg for buffer ;an000; dms;
2697 mov ds,ax ;put into es ;an000; dms;
2698 mov si,offset cs:ER_Move_Xchg_Buffer1 ;offset of buffer ;an000; dms;
2699 add si,bp ;offset BP relative ;an000; dms;
2700 cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms;
2701; $if e ;yes ;an000; dms;
2702 JNE ER_IF76
2703 add si,ER_10H ;end of buffer + 1 ;an000; dms;
2704 dec si ;end of buffer ;an000; dms;
2705; $endif ; ;an000; dms;
2706ER_IF76:
2707
2708 cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms;
2709; $if e ;yes ;an000; dms;
2710 JNE ER_IF78
2711 std ;reverse move ;an000; dms;
2712; $else ;forward move ;an000; dms;
2713 JMP SHORT ER_EN78
2714ER_IF78:
2715 cld ; ;an000; dms;
2716; $endif ; ;an000; dms;
2717ER_EN78:
2718 cli ;ints off ;an000; dms;
2719 rep movsb ;move the data ;an000; dms;
2720 sti ;ints on ;an000; dms;
2721
2722ER_Move_Dest_Exit:
2723
2724 pop ds ;restore regs ;an000; dms;
2725 pop si ; ;an000; dms;
2726 pop dx ; ;an000; dms;
2727 pop bx ; ;an000; dms;
2728 pop ax ; ;an000; dms;
2729
2730 ret ;return to caller ;an000; dms;
2731
2732ER_Move_Buffer_To_Dest endp ;end proc ;an000; dms;
2733
2734
2735;=========================================================================
2736; ER_Xchg_Source_To_Buffer : This routine moves the source data to
2737; the buffer before it is exchanged with
2738; the destination data.
2739;
2740; Inputs : BP - carries type of memory for source/dest
2741; Bit 0 - Destination (EMS if set)
2742; Bit 1 - Source (EMS if set)
2743;
2744; Outputs : ER_Move_Xchg_Buffer1 - Source data
2745;=========================================================================
2746
2747ER_Xchg_Source_To_Buffer proc ; ;an000; dms;
2748
2749 push ax ;save regs ;an000; dms;
2750 push bx ; ;an000; dms;
2751 push dx ; ;an000; dms;
2752 push di ; ;an000; dms;
2753 push si ; ;an000; dms;
2754 push ds ; ;an000; dms;
2755 push es ; ;an000; dms;
2756
2757 test cs:[bp].ER_Mem_Type,ER_Source_EMS_Memory;Source EMS? ;an000; dms;
2758 jz ER_Xchg_Source_Conv_Mem ;no - adjust seg:off ;an000; dms;
2759 jmp ER_Xchg_Source_EMS_Mem ;yes- continue move ;an000; dms;
2760
2761ER_Xchg_Source_Conv_Mem:
2762
2763 mov ax,ds ;adjust segment:off ;an000; dms;
2764 mov dx,si ; ;an000; dms;
2765 call ER_Segment_Adjust ; ;an000; dms;
2766 mov ds,ax ;new segment:off ;an000; dms;
2767 mov si,dx ; ;an000; dms;
2768 jmp ER_Xchg_Source_Count ;determine count ;an000; dms;
2769
2770ER_Xchg_Source_EMS_Mem:
2771
2772 cmp si,4000h ;beginning of log page ;an000; dms;
2773 je ER_Xchg_Source_EMS_Next ;yes - get next page ;an000; dms;
2774 mov bx,cs:[bp].ER_Source_Page ;pass log. page to call ;an000; dms;
2775 call ER_Map_Next_Src_Page ;no - map in current pg;an000; dms;
2776 jmp ER_Xchg_Source_Count ;get count for move ;an000; dms;
2777
2778ER_Xchg_Source_EMS_Next:
2779
2780 mov bx,cs:[bp].ER_Source_Page ;pass log. page to call ;an000; dms;
2781 inc bx ; adjusted upward ;an000; dms;
2782 call ER_Map_Next_Src_Page ;map in the page ;an000; dms;
2783 xor si,si ;reinit pointer ;an000; dms;
2784
2785ER_Xchg_Source_Count:
2786
2787 mov cx,ER_10H ;default count ;an000; dms;
2788 cmp cs:[bp].ER_Move_Count_High,0 ;high word set ;an000; dms;
2789 jne ER_Xchg_Source_High_Set ;yes - use default ;an000; dms;
2790 cmp cs:[bp].ER_Move_Count_Low,cx ;>= 10h bytes ;an000; dms;
2791 jae ER_Xchg_Source_High_Set ;yes - use default ;an000; dms;
2792 mov cx,cs:[bp].ER_Move_Count_Low ;no - use last few bytes;an000; dms;
2793
2794ER_Xchg_Source_High_Set:
2795
2796 cmp si,di ;source >= dest? ;an000; dms;
2797; $if b ;no ;an000; dms;
2798 JNB ER_IF81
2799 mov ax,4000h ;get end of page ;an000; dms;
2800 sub ax,si ;get bytes remaining ;an000; dms;
2801 cmp ax,ER_10H ;source >= 10h ;an000; dms;
2802; $if b ;no ;an000; dms;
2803 JNB ER_IF82
2804 mov cx,ax ;get remaining count ;an000; dms;
2805; $endif ; ;an000; dms;
2806ER_IF82:
2807; $else ;source >= dest ;an000; dms;
2808 JMP SHORT ER_EN81
2809ER_IF81:
2810 mov ax,4000h ;get end of page ;an000; dms;
2811 sub ax,di ;get bytes remaining ;an000; dms;
2812 cmp ax,ER_10H ;dest >= 10h ;an000; dms;
2813; $if b ;no ;an000; dms;
2814 JNB ER_IF85
2815 mov cx,ax ;get remaining count ;an000; dms;
2816; $endif ; ;an000; dms;
2817ER_IF85:
2818; $endif ; ;an000; dms;
2819ER_EN81:
2820
2821ER_Xchg_Source_Default_Count:
2822
2823 mov cs:[bp].ER_Current_Move_Count,cx ;save current move cnt ;an000; dms;
2824
2825 sub cs:[bp].ER_Move_Count_Low,cx ;get new count ;an000; dms;
2826 sbb cs:[bp].ER_Move_Count_High,0 ;pick up borrow ;an000; dms;
2827
2828 mov ax,cs ;get seg for buffer ;an000; dms;
2829 mov es,ax ;put into es ;an000; dms;
2830 mov di,offset cs:ER_Move_Xchg_Buffer1 ;offset of buffer ;an000; dms;
2831 add di,bp ;offset BP relative ;an000; dms;
2832
2833 cld ;forward move ;an000; dms;
2834 cli ;ints off ;an000; dms;
2835 rep movsb ;move the data ;an000; dms;
2836 sti ;ints on ;an000; dms;
2837
2838ER_Xchg_Source_Exit:
2839
2840 pop es ;restore regs ;an000; dms;
2841 pop ds ; ;an000; dms;
2842 pop si ; ;an000; dms;
2843 pop di ; ;an000; dms;
2844 pop dx ; ;an000; dms;
2845 pop bx ; ;an000; dms;
2846 pop ax ; ;an000; dms;
2847
2848 ret ;return to caller ;an000; dms;
2849
2850ER_Xchg_Source_To_Buffer endp ;end proc ;an000; dms;
2851
2852
2853;=========================================================================
2854; ER_Xchg_Dest_To_Buffer : This routine moves the destination data to
2855; the buffer before it is exchanged with
2856; the source data.
2857;
2858; Inputs : BP - carries type of memory for source/dest
2859; Bit 0 - Destination (EMS if set)
2860; Bit 1 - Source (EMS if set)
2861;
2862; Outputs : ER_Move_Xchg_Buffer2 - Destination data
2863;=========================================================================
2864
2865ER_Xchg_Dest_To_Buffer proc ; ;an000; dms;
2866
2867 push ax ;save regs ;an000; dms;
2868 push bx ; ;an000; dms;
2869 push dx ; ;an000; dms;
2870 push di ; ;an000; dms;
2871 push si ; ;an000; dms;
2872 push ds ; ;an000; dms;
2873 push es ; ;an000; dms;
2874
2875 test cs:[bp].ER_Mem_Type,ER_Dest_EMS_Memory ;Dest EMS? ;an000; dms;
2876 jz ER_Xchg_Dest_Conv_Mem ;no - adjust seg:off ;an000; dms;
2877 jmp ER_Xchg_Dest_EMS_Mem ;yes- continue move ;an000; dms;
2878
2879ER_Xchg_Dest_Conv_Mem:
2880
2881 mov ax,es ;adjust segment:off ;an000; dms;
2882 mov dx,di ; ;an000; dms;
2883 call ER_Segment_Adjust ; ;an000; dms;
2884 mov es,ax ;new segment:off ;an000; dms;
2885 mov di,dx ; ;an000; dms;
2886 jmp ER_Xchg_Dest_Count ;determine count ;an000; dms;
2887
2888ER_Xchg_Dest_EMS_Mem:
2889
2890 cmp di,4000h ;beginning of log page ;an000; dms;
2891 je ER_Xchg_Dest_EMS_Next ;yes - get next page ;an000; dms;
2892 mov bx,cs:[bp].ER_Dest_Page ;pass log. page to call ;an000; dms;
2893 call ER_Map_Next_Dest_Page ;no - map in current pg;an000; dms;
2894 jmp ER_Xchg_Dest_Count ;get count for move ;an000; dms;
2895
2896ER_Xchg_Dest_EMS_Next:
2897
2898 mov bx,cs:[bp].ER_Dest_Page ;pass log. page to call ;an000; dms;
2899 inc bx ; adjusted upward ;an000; dms;
2900 call ER_Map_Next_Dest_Page ;map in the page ;an000; dms;
2901 xor di,di ;reinit pointer ;an000; dms;
2902
2903ER_Xchg_Dest_Count:
2904
2905 mov cx,cs:[bp].ER_Current_Move_Count ;get move count ;an000; dms;
2906 mov ax,es ;get destination seg ;an000; dms;
2907 mov ds,ax ;put into ds for buffer ;an000; dms;
2908 ; transfer
2909 mov si,di ;get destination off ;an000; dms;
2910 mov ax,cs ;get seg for buffer ;an000; dms;
2911 mov es,ax ;put into es ;an000; dms;
2912 mov di,offset cs:ER_Move_Xchg_Buffer2 ;offset of buffer ;an000; dms;
2913 add di,bp ;offset BP relative ;an000; dms;
2914
2915 cld ;forward move ;an000; dms;
2916 cli ;ints off ;an000; dms;
2917 rep movsb ;move the data ;an000; dms;
2918 sti ;ints on ;an000; dms;
2919
2920ER_Xchg_Dest_Exit:
2921
2922 pop es ;restore regs ;an000; dms;
2923 pop ds ; ;an000; dms;
2924 pop si ; ;an000; dms;
2925 pop di ; ;an000; dms;
2926 pop dx ; ;an000; dms;
2927 pop bx ; ;an000; dms;
2928 pop ax ; ;an000; dms;
2929
2930 ret ;return to caller ;an000; dms;
2931
2932ER_Xchg_Dest_To_Buffer endp ;end proc ;an000; dms;
2933
2934
2935
2936
2937;=========================================================================
2938; ER_Xchg_Buffer_To_Source ; This routine performs the actual exchange
2939; from the destination buffer to the source
2940; buffer.
2941;
2942; Inputs : BP - carries type of memory for source/dest
2943; Bit 0 - Destination (EMS if set)
2944; Bit 1 - Source (EMS if set)
2945; ER_Move_Xchg_Buffer2 - Destination data
2946;
2947; Outputs : Adjusted segment:offset or page/offset
2948;=========================================================================
2949
2950ER_Xchg_Buffer_To_Source proc ; ;an000; dms;
2951
2952 push ax ;save regs ;an000; dms;
2953 push bx ; ;an000; dms;
2954 push dx ; ;an000; dms;
2955 push di ; ;an000; dms;
2956 push es ; ;an000; dms;
2957
2958 test cs:[bp].ER_Mem_Type,ER_Source_EMS_Memory;Source EMS? ;an000; dms;
2959 jz ER_Xchg_Buf2_Conv_Mem ;no - adjust seg:off ;an000; dms;
2960 jmp ER_Xchg_Buf2_EMS_Mem ;yes- continue move ;an000; dms;
2961
2962ER_Xchg_Buf2_Conv_Mem:
2963
2964 mov ax,ds ;adjust segment:off ;an000; dms;
2965 mov dx,si ; ;an000; dms;
2966 call ER_Segment_Adjust ; ;an000; dms;
2967 mov ds,ax ;new segment:off ;an000; dms;
2968 mov si,dx ; ;an000; dms;
2969 jmp ER_Xchg_Buf2_Count ;determine count ;an000; dms;
2970
2971ER_Xchg_Buf2_EMS_Mem:
2972
2973 cmp si,4000h ;beginning of log page ;an000; dms;
2974 je ER_Xchg_Buf2_EMS_Next ;yes - get next page ;an000; dms;
2975 mov bx,cs:[bp].ER_Source_Page ;pass log. page to call ;an000; dms;
2976 call ER_Map_Next_Src_Page ;no - map in current pg;an000; dms;
2977 jmp ER_Xchg_Buf2_Count ;get count for move ;an000; dms;
2978
2979ER_Xchg_Buf2_EMS_Next:
2980
2981 inc cs:[bp].ER_Source_Page ;adjust log page ;an000; dms;
2982 mov bx,cs:[bp].ER_Source_Page ;pass log. page to call ;an000; dms;
2983 call ER_Map_Next_Src_Page ;map in the page ;an000; dms;
2984 xor si,si ;reinit pointer ;an000; dms;
2985
2986ER_Xchg_Buf2_Count:
2987
2988 mov cx,cs:[bp].ER_Current_Move_Count ;get move count ;an000; dms;
2989
2990 mov ax,ds ;get destination seg ;an000; dms;
2991 mov es,ax ;put into ds for buffer ;an000; dms;
2992 ; transfer
2993 mov di,si ;get destination off ;an000; dms;
2994 add si,cx ;adjust source ptr ;an000; dms;
2995 push si ;save across xchg ;an000; dms;
2996 push ds ; ;an000; dms;
2997
2998 mov ax,cs ;get seg for buffer ;an000; dms;
2999 mov ds,ax ;put into es ;an000; dms;
3000 mov si,offset cs:ER_Move_Xchg_Buffer2 ;offset of buffer ;an000; dms;
3001 add si,bp ;offset BP relative ;an000; dms;
3002
3003 cld ;forward move ;an000; dms;
3004 cli ;ints off ;an000; dms;
3005 rep movsb ;move the data ;an000; dms;
3006 sti ;ints on ;an000; dms;
3007
3008 pop ds ;restore ptr ;an000; dms;
3009 pop si ; ;an000; dms;
3010
3011ER_Xchg_Buf2_Exit:
3012
3013 pop es ;restore regs ;an000; dms;
3014 pop di ; ;an000; dms;
3015 pop dx ; ;an000; dms;
3016 pop bx ; ;an000; dms;
3017 pop ax ; ;an000; dms;
3018
3019 ret ;return to caller ;an000; dms;
3020
3021ER_Xchg_Buffer_To_Source endp ;end proc ;an000; dms;
3022
3023
3024
3025;=========================================================================
3026; ER_Xchg_Buffer_To_Dest ; This routine performs the actual exchange
3027; from the source buffer to the destination.
3028;
3029; Inputs : BP - carries type of memory for source/dest
3030; Bit 0 - Destination (EMS if set)
3031; Bit 1 - Source (EMS if set)
3032; ER_Move_Xchg_Buffer1 - Source data
3033;
3034; Outputs : Adjusted segment:offset or page/offset
3035;=========================================================================
3036
3037ER_Xchg_Buffer_To_Dest proc ; ;an000; dms;
3038
3039 push ax ;save regs ;an000; dms;
3040 push bx ; ;an000; dms;
3041 push dx ; ;an000; dms;
3042 push si ; ;an000; dms;
3043 push ds ; ;an000; dms;
3044
3045 test cs:[bp].ER_Mem_Type,ER_Dest_EMS_Memory ;Dest EMS? ;an000; dms;
3046 jz ER_Xchg_Buf1_Conv_Mem ;no - adjust seg:off ;an000; dms;
3047 jmp ER_Xchg_Buf1_EMS_Mem ;yes- continue move ;an000; dms;
3048
3049ER_Xchg_Buf1_Conv_Mem:
3050
3051 mov ax,es ;adjust segment:off ;an000; dms;
3052 mov dx,di ; ;an000; dms;
3053 call ER_Segment_Adjust ; ;an000; dms;
3054 mov es,ax ;new segment:off ;an000; dms;
3055 mov di,dx ; ;an000; dms;
3056 jmp ER_Xchg_Buf1_Count ;determine count ;an000; dms;
3057
3058ER_Xchg_Buf1_EMS_Mem:
3059
3060 cmp di,4000h ;beginning of log page ;an000; dms;
3061 je ER_Xchg_Buf1_EMS_Next ;yes - get next page ;an000; dms;
3062 mov bx,cs:[bp].ER_Dest_Page ;pass log. page to call ;an000; dms;
3063 call ER_Map_Next_Dest_Page ;no - map in current pg;an000; dms;
3064 jmp ER_Xchg_Buf1_Count ;get count for move ;an000; dms;
3065
3066ER_Xchg_Buf1_EMS_Next:
3067
3068 inc cs:[bp].ER_Dest_Page ;adjust log page ;an000; dms;
3069 mov bx,cs:[bp].ER_Dest_Page ;pass log. page to call ;an000; dms;
3070 call ER_Map_Next_Dest_Page ;map in the page ;an000; dms;
3071 mov di,EMS_Page_Size_In_Bytes ;reinit pointer ;an000; dms;
3072
3073ER_Xchg_Buf1_Count:
3074
3075 mov cx,cs:[bp].ER_Current_Move_Count ;get move count ;an000; dms;
3076 mov ax,cs ;get seg for buffer ;an000; dms;
3077 mov ds,ax ;put into es ;an000; dms;
3078 mov si,offset cs:ER_Move_Xchg_Buffer1 ;offset of buffer ;an000; dms;
3079 add si,bp ;offset BP relative ;an000; dms;
3080
3081 cld ;forward move ;an000; dms;
3082 cli ;ints off ;an000; dms;
3083 rep movsb ;move the data ;an000; dms;
3084 sti ;ints on ;an000; dms;
3085
3086ER_Xchg_Buf1_Exit:
3087
3088 pop ds ;restore regs ;an000; dms;
3089 pop si ; ;an000; dms;
3090 pop dx ; ;an000; dms;
3091 pop bx ; ;an000; dms;
3092 pop ax ; ;an000; dms;
3093
3094 ret ;return to caller ;an000; dms;
3095
3096ER_Xchg_Buffer_To_Dest endp ;end proc ;an000; dms;
3097
3098
3099
3100;=========================================================================
3101; ER_Map_Next_Src_Page : This routine maps in the page needed by
3102; the source of the move/exchange.
3103;
3104; Inputs : ER_Source_Phys_Page - Physical page of source
3105; ER_Source_Handle - Handle of source
3106; BX - logical page
3107;
3108; Outputs : newly mapped page
3109;=========================================================================
3110
3111ER_Map_Next_Src_Page proc ;map next src. page ;an000; dms;
3112
3113 mov ax,cs:[bp].ER_Source_Phys_Page ;map the source page ;an000; dms;
3114 mov dx,cs:[bp].ER_Source_Handle ;handle to use ;an000; dms;
3115 call Map_L_To_P ;map the page ;an000; dms;
3116
3117 ret ;return to caller ;an000; dms;
3118
3119ER_Map_Next_Src_Page endp ;end proc ;an000; dms;
3120
3121;=========================================================================
3122; ER_Map_Next_Dest_Page : This routine maps in the page needed by
3123; the destination of the move/exchange.
3124;
3125; Inputs : ER_Dest_Phys_Page - Physical page of source
3126; ER_Dest_Handle - Handle of source
3127; BX - logical page to map
3128;
3129; Outputs : newly mapped page
3130;=========================================================================
3131
3132ER_Map_Next_Dest_Page proc ;map next dest. page ;an000; dms;
3133
3134 mov ax,cs:[bp].ER_Dest_Phys_Page ;map the dest. page ;an000; dms;
3135 mov dx,cs:[bp].ER_Dest_Handle ;handle to use ;an000; dms;
3136 call Map_L_To_P ;map the page ;an000; dms;
3137
3138 ret ;return to caller ;an000; dms;
3139
3140ER_Map_Next_Dest_Page endp ;end proc ;an000; dms;
3141
3142;=========================================================================
3143; ER_Move_Data : This routine will perform the actual move of the
3144; data for the function 5700h.
3145;
3146; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data
3147;
3148; Outputs : AH - Non-zero on error
3149;=========================================================================
3150
3151ER_Move_Data proc ;move the data ;an000; dms;
3152
3153 push bx ;save regs ;an000; dms;
3154 push cx ; ;an000; dms;
3155 push dx ; ;an000; dms;
3156 push di ; ;an000; dms;
3157 push si ; ;an000; dms;
3158 push ds ; ;an000; dms;
3159 push es ; ;an000; dms;
3160
3161 call ER_Save_Context ;save off max of 2 pages;an000; dms;
3162 call ER_Det_Src_Dest_Seg ;determine segs ;an000; dms;
3163 call ER_Det_Move_Count ;ER_10h_Move_Count = ;an000; dms;
3164 ; # of 10h moves
3165 ;ER_10h_Move_Remainder =
3166 ; # of bytes remaining
3167
3168ER_Move_Data_Now:
3169
3170 ;set the flags to signal
3171 ;the memory type in use
3172 ;for Source/Destination.
3173
3174 xor al,al ;al signals type of mem ;an000; dms;
3175 or al,[si].Source_Memory_Type ;get source memory type ;an000; dms;
3176 shl al,1 ;put into bit 1 ;an000; dms;
3177 or al,[si].Dest_Memory_Type ;get dest. memory type ;an000; dms;
3178 cbw ;make it a word value ;an000; dms;
3179 mov cs:[bp].ER_Mem_Type,ax ;put flags in var ;an000; dms;
3180 ;bp = bit 0 - dest mem
3181 ; bit 1 - src mem
3182
3183 mov di,cs:[bp].ER_Dest_Off ;get dest. offset ;an000; dms;
3184 mov es,cs:[bp].ER_Dest_Seg ;get dest. seg ;an000; dms;
3185
3186 mov si,cs:[bp].ER_Source_Off ;get src. offset ;an000; dms;
3187 mov ds,cs:[bp].ER_Source_Seg ;get src. seg ;an000; dms;
3188
3189ER_Move_Data_Loop:
3190
3191 call ER_Move_Source_To_Buffer ;move data to buffer ;an000; dms;
3192 call ER_Move_Buffer_To_Dest ;move buffer to dest. ;an000; dms;
3193
3194 cmp cs:[bp].ER_Move_Count_High,0 ;end of move? ;an000; dms;
3195 jne ER_Move_Data_Loop ;no - continue loop ;an000; dms;
3196 cmp cs:[bp].ER_Move_Count_Low,0 ;end of move? ;an000; dms;
3197 jne ER_Move_Data_Loop ;no - continue loop ;an000; dms;
3198 ;yes - end of loop ;an000; dms;
3199
3200ER_Move_Data_Error_Exit:
3201
3202 call ER_Restore_Context ;restore the context ;an000; dms;
3203
3204 pop es ;restore regs ;an000; dms;
3205 pop ds ; ;an000; dms;
3206 pop si ; ;an000; dms;
3207 pop di ; ;an000; dms;
3208 pop dx ; ;an000; dms;
3209 pop cx ; ;an000; dms;
3210 pop bx ; ;an000; dms;
3211
3212 ret ;return to caller ;an000; dms;
3213
3214ER_Move_Data endp ;end proc ;an000; dms;
3215
3216
3217
3218;=========================================================================
3219; ER_Exchange_Data : This routine will perform the actual exchange of
3220; data for the function 5701h.
3221;
3222; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data
3223;
3224; Outputs : AH - Non-zero on error
3225;=========================================================================
3226
3227ER_Exchange_Data proc ;xchg the data ;an000; dms;
3228
3229 push bx ;save regs ;an000; dms;
3230 push cx ; ;an000; dms;
3231 push dx ; ;an000; dms;
3232 push di ; ;an000; dms;
3233 push si ; ;an000; dms;
3234 push ds ; ;an000; dms;
3235 push es ; ;an000; dms;
3236
3237 call ER_Save_Context ;save off max of 2 pages;an000; dms;
3238 call ER_Det_Src_Dest_Seg ;determine segs ;an000; dms;
3239 call ER_Det_Move_Count ;ER_10h_Move_Count = ;an000; dms;
3240 ; # of 10h moves
3241 ;ER_10h_Move_Remainder =
3242 ; # of bytes remaining
3243
3244ER_Xchg_Data_Now:
3245
3246 ;set the flags to signal
3247 ;the memory type in use
3248 ;for Source/Destination.
3249
3250 xor al,al ;al signals type of mem ;an000; dms;
3251 or al,[si].Source_Memory_Type ;get source memory type ;an000; dms;
3252 shl al,1 ;put into bit 1 ;an000; dms;
3253 or al,[si].Dest_Memory_Type ;get dest. memory type ;an000; dms;
3254 cbw ;make it a word value ;an000; dms;
3255 mov cs:[bp].ER_Mem_Type,ax ;put flags in var ;an000; dms;
3256 ;bp = bit 0 - dest mem
3257 ; bit 1 - src mem
3258
3259 mov di,cs:[bp].ER_Dest_Off ;get dest. offset ;an000; dms;
3260 mov es,cs:[bp].ER_Dest_Seg ;get dest. seg ;an000; dms;
3261
3262 mov si,cs:[bp].ER_Source_Off ;get src. offset ;an000; dms;
3263 mov ds,cs:[bp].ER_Source_Seg ;get src. seg ;an000; dms;
3264
3265ER_Xchg_Data_Loop:
3266
3267 call ER_Xchg_Source_To_Buffer ;move source to buf 1 ;an000; dms;
3268 call ER_Xchg_Dest_To_Buffer ;move dest. to buf 2 ;an000; dms;
3269 call ER_Xchg_Buffer_To_Source ;move buf2 to source ;an000; dms;
3270 call ER_Xchg_Buffer_To_Dest ;move buf1 to dest. ;an000; dms;
3271
3272 cmp cs:[bp].ER_Move_Count_High,0 ;end of move? ;an000; dms;
3273 jne ER_Xchg_Data_Loop ;no - continue loop ;an000; dms;
3274 cmp cs:[bp].ER_Move_Count_Low,0 ;end of move? ;an000; dms;
3275 jne ER_Xchg_Data_Loop ;no - continue loop ;an000; dms;
3276 ;yes - end of loop ;an000; dms;
3277
3278ER_Xchg_Data_Error_Exit:
3279
3280 call ER_Restore_Context ;restore the context ;an000; dms;
3281
3282 pop es ;restore regs ;an000; dms;
3283 pop ds ; ;an000; dms;
3284 pop si ; ;an000; dms;
3285 pop di ; ;an000; dms;
3286 pop dx ; ;an000; dms;
3287 pop cx ; ;an000; dms;
3288 pop bx ; ;an000; dms;
3289
3290 ret ;return to caller ;an000; dms;
3291
3292ER_Exchange_Data endp ;end proc ;an000; dms;
3293
3294
3295
3296 page
3297
3298;=========================================================================
3299;=============== Function 5Ah Logic - Allocate Raw Pages =============
3300;=========================================================================
3301
3302
3303;=========================================================================
3304; Alloc_Raw - This routine allocates raw EMS pages, pages
3305; less than the standard 16k page. These pages
3306; are a sub-multiple of 16k. In the IBM version
3307; of this implementation the raw page is defined
3308; as 16k, thus we do not need to do anything
3309; special here. We map this call to the proc
3310; GET_HANDLE (function 43h) to allocate a handle.
3311;
3312; Inputs : AH - 5Ah (Allocate Raw Pages)
3313; BX - Number of raw pages to allocate
3314;
3315; Outputs : AH - Non-zero if error (Determined by Get_Handle proc)
3316; DX - Handle if no error
3317;=========================================================================
3318
3319Alloc_Raw proc ;Allocate raw pages ;an000; dms;
3320
3321 PUSH BX
3322 PUSH CX
3323 PUSH DI
3324 PUSH SI
3325 PUSH DS ;save these registers
3326
3327 PUSH CS ;get cs
3328 POP DS ;into ds
3329
3330 ;Remove test for BX = 0. This is @RH4
3331 ; valid under LIM 4.0
3332
3333 cmp al,AR_Sub_Max ;sub function out of range? ;an000; dms;
3334 jna AR_OKSub ;no ;an000; dms;
3335 mov ah,EMS_Code8F ;yes-signal error ;an000; dms;
3336 jmp AR_Exit ;exit routine ;an000; dms;
3337
3338AR_OKSub:
3339
3340 CMP BX,TOTAL_EMS_PAGES ;Enough total EMS pages?
3341 JNA AR_OKTOTAL
3342 MOV AH,EMS_CODE87
3343 JMP AR_EXIT
3344
3345AR_OKTOTAL:
3346 cli ;ints off ;an000; dms;
3347 CMP BX,FREE_PAGES ;Enough unallocated pages?
3348 sti ;ints on ;an000; dms;
3349 JNA AR_OKFREE
3350 MOV AH,EMS_CODE88
3351 JMP AR_EXIT
3352 ;-----------------------------------------------------
3353 ; Search for a free handle @RH1 º
3354 ;-----------------------------------------------------
3355AR_OKFREE:
3356 MOV CX,NUM_HANDLES ;loop counter is #handles
3357 DEC CX ;handle 0 reserved for op. sys. @RH1
3358 MOV DX,1 ;handle assignment set to 1 @RH1
3359 MOV DI,TYPE H_LOOKUP_STRUC ;init table index to 1st entry @RH1
3360;--------------------------------
3361 CLI ;interrupts OFF during allocation
3362;--------------------------------
3363AR_FREEHSRCH:
3364 CMP HANDLE_LOOKUP_TABLE.H_PAGES[DI],REUSABLE_HANDLE
3365 ;Is this handle available? @RH1
3366 JE AR_HFREE ;yes end search dx=handle id @RH1
3367 INC DX ;next handle assignment
3368 ADD DI,TYPE H_LOOKUP_STRUC ;next entry in handle lookup @RH1
3369 ;repeat for all table entries
3370 LOOP AR_FREEHSRCH
3371 MOV AH,EMS_CODE85 ;no available handles
3372 JMP AR_EXIT ;go to exit ;GGA
3373
3374 ;-----------------------------------------------------
3375 ; If here then there's enough pages for request. @RH1 º
3376 ; DX = handle #, DI = ptr to hndl lookup entry @RH1 º
3377AR_HFREE:
3378
3379 MOV CX,NUM_HANDLES ;loop counter
3380 DEC CX ;handle 0 reserved for op. sys. @RH1
3381 ;si = index to hndl lookup tbl @RH1
3382 MOV SI,TYPE H_LOOKUP_STRUC ; for adding pages (skip 0 entry) @RH1
3383 XOR AX,AX ;clear page counter
3384 CLC ;clear carry for addition
3385AR_PAGESUM:
3386 CMP HANDLE_LOOKUP_TABLE.H_PAGES[SI],REUSABLE_HANDLE
3387 JE AR_PGSUM_BOT ;If handle is free don't add @RH4
3388 ADD AX,HANDLE_LOOKUP_TABLE.H_PAGES[SI]
3389 ;add lengths (pages) of PALs @RH1
3390 ADD SI,TYPE H_LOOKUP_STRUC ; next entry in handle lookup @RH1
3391AR_PGSUM_BOT:
3392 LOOP AR_PAGESUM
3393 CMP AX,TOTAL_EMS_PAGES ;pages in handle lookup > total? @RH1
3394 JNA AR_CALCHLUP ;no OK @RH1
3395 MOV AH,EMS_CODE80 ;software error..we screwed up @RH1
3396 JMP AR_EXIT ;go to exit @RH1 ;GGA
3397
3398AR_CALCHLUP: ;calculate entry in hndl lkup tbl @RH1
3399 cmp bx,0 ;page request? ;an000; dms;
3400 jne AR_Alloc_Cont ;yes continue ;an000; dms;
3401 cli ;ints off ;an001; dms;
3402 mov Handle_LookUp_Table.H_Pages[di],bx ;new page count ;an001; dms;
3403 sti ;ints on ;an001; dms;
3404 xor ah,ah ;clear flag ;an000; dms;
3405 jmp AR_Exit ;exit routine ;an000; dms;
3406
3407AR_Alloc_Cont:
3408
3409 cli ;ints off ;an001; dms;
3410 mov cx,bx ;alloc count ;an000; dms;
3411 call EMS_Page_Contig_Chk ;do we have contig pgs. ;an001; dms;
3412 jnc AR_Alloc ;yes continue process ;an001; dms;
3413 mov ah,EMS_Code88 ;no signal error ;an001; dms;
3414 sti ;ints on ;an001; dms;
3415 jmp AR_Exit ;exit routine ;an001; dms;
3416
3417AR_Alloc:
3418
3419 call EMS_Link_Set ;set up links ;an001; dms;
3420
3421
3422 sub Free_Pages,bx ;free = free - requested pages
3423 mov Handle_LookUp_Table.H_Pages[di],bx ;page count ;an000; dms;
3424 mov Handle_LookUp_Table.H_Pal_Ptr[di],si ;initialize to ptr for ;ac001; dms;
3425 ; pages
3426 sti ;ints on ;an001; dms;
3427 xor ah,ah ;clear flag ;an000; dms;
3428
3429
3430AR_EXIT: ;GGA
3431
3432 POP DS
3433 POP SI
3434 POP DI
3435 POP CX
3436 POP BX
3437
3438 ret ;return to caller ;an000; dms;
3439
3440Alloc_Raw endp ;end proc ;an000; dms;
3441
3442 page
3443;=========================================================================
3444;=============== Function 5Ch Logic - Prepare for Warm Boot =============
3445;=========================================================================
3446
3447
3448;=========================================================================
3449; Prepare_Boot - This routine prepares the hardware for a
3450; warm boot. Since we have no special hardware
3451; requirements at this time, this routine sets
3452; a good error level and returns to the caller.
3453;
3454; Inputs : AH - 5Ch (Prepare for Warm Boot)
3455;
3456; Outputs : AH - Non-zero if error (Determined by Get_Handle proc)
3457;=========================================================================
3458
3459Prepare_Boot proc ;prepare for warm boot ;an000; dms;
3460
3461 xor ah,ah ;signal no error ;an000; dms;
3462
3463 ret ;return to caller ;an000; dms;
3464
3465Prepare_Boot endp ;end proc ;an000; dms;
3466
3467
3468
diff --git a/v4.0/src/DEV/XMA2EMS/MAKEFILE b/v4.0/src/DEV/XMA2EMS/MAKEFILE
new file mode 100644
index 0000000..c739b08
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/MAKEFILE
@@ -0,0 +1,24 @@
1#************************ makefile for dev\xma2ems************************
2
3msg =..\..\messages
4dos =..\..\dos
5inc =..\..\inc
6hinc =..\..\h
7
8#
9####################### dependencies begin here. #########################
10#
11
12all: xma2ems.sys
13
14xma2ems.ctl: xma2ems.skl $(MSG)\$(country).MSG makefile
15
16xma2ems.obj: xma2ems.asm xma1diag.inc xma2ems.cl1 $(inc)\COPYRIGH.INC \
17 parmpars.inc lim40.inc ps2_5060.inc makefile \
18 emsinit.inc genioctl.inc xma2emsp.inc lim40b.inc romscan.inc \
19 $(inc)\psdata.inc
20
21xma2ems.sys: xma2ems.obj makefile
22 link xma2ems;
23 exe2bin xma2ems.exe xma2ems.sys
24 del xma2ems.exe
diff --git a/v4.0/src/DEV/XMA2EMS/PARMPARS.INC b/v4.0/src/DEV/XMA2EMS/PARMPARS.INC
new file mode 100644
index 0000000..42ea6e8
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/PARMPARS.INC
@@ -0,0 +1,530 @@
1 PAGE
2;-----------------------------------------------------------------------;
3; GET_PARMS extracts parameters from the command line buffer ;
4; ;
5; On entry: all letters after 'Device=' have been changed ;
6; to upper case ;
7; ;
8; On exit: (zf)=0 if syntax error ;
9; if (zf)=1 then... ;
10; ;
11; EMM_START_BLOCK has been updated ;
12; ;
13; AX,BX,CX,DX,DI,SI,DS are destroyed ;
14;-----------------------------------------------------------------------;
15
16include xma2emsp.inc ; include parser things
17include parse.asm
18
19GET_PARMS PROC
20 LDS BX,CS:RH_PTRA ;make ds:bx point to request header
21
22 LDS SI,RH.RH0_BPBA ;make ds:si point to bios paramter buffer
23 CLD
24 mov cs:EMS_Pgs_Parm,E_Parm_Def ;default to all of memory ;an000; dms;
25
26;-------------------------------------------------------------------
27; parser support added by GGA
28;-------------------------------------------------------------------
29 push cs ; make ES:DI point to parm block
30 pop es
31 lea di,p_block
32
33 xor cx,cx ; cx = 0, ordinal
34 xor dx,dx ; dx = 0, reserved
35
36 push ds ; save ds
37
38get_args:
39 pop ds ; restore ds
40 call SysParse ; call the parser
41 cmp ax,0 ; end of line?
42 je check_frame ; no, find out what we got this time
43 cmp ax,-1 ; end of parse?
44 je end_of_input_line1 ; yes
45 cmp ax,-1 ; flag an error
46 ret ; return to caller
47
48end_of_input_line1:
49
50 jmp end_of_input_line ;
51
52; find out which arg was processed this time
53
54check_frame:
55
56; make ds point to data area for these comparisons, must restore before
57; calling parser again
58
59 push ds ; save ds
60 push es ; make ds point to save areas
61 pop ds
62
63 cmp frame_result.$P_Type,2 ; was there a FRAME= in this pass?
64 jne check_p0 ; no, look for a P0
65
66 mov parse_flag,1 ; set parse flag
67
68 mov byte ptr frame_ctl+9,0 ; turn this off so we don't allow another
69 mov frame_result.$P_Type,0 ; clear this so we don't get fooled later
70
71 mov byte ptr p0_ctl+9,0 ; turn these off so we don't allow any
72 mov byte ptr p1_ctl+9,0 ; others that would conflict
73 mov byte ptr p2_ctl+9,0
74 mov byte ptr p3_ctl+9,0
75
76 push si ;save regs
77
78 mov si,word ptr frame_result.$P_Picked_Val[+0]
79
80 mov word ptr ds:[si+0],0 ;clear the
81 mov word ptr ds:[si+4],0 ; pages
82 mov word ptr ds:[si+8],0
83 mov word ptr ds:[si+12],0
84
85 pop si ;restore regs
86
87
88; set flags for later code to fill in map_table
89
90 or page_flags,frame_flag ; set frame flag
91
92 jmp get_args ; go get another argument
93
94check_p0:
95 cmp p0_result.$P_Type,2 ; was there a P0= in this pass?
96 jne check_p1 ; no, look for a P0
97
98 mov parse_flag,1 ; set parse flag
99
100 mov byte ptr p0_ctl+9,0 ; turn this off so we don't allow another
101 mov p0_result.$P_Type,0 ; clear this so we don't get fooled later
102
103 mov byte ptr frame_ctl+9,0 ; turn this off so we don't allow another
104
105 push si ;save regs
106
107 mov si,word ptr p0_result.$P_Picked_Val[+0]
108
109 mov word ptr ds:[si+0],0
110
111 pop si ;restore regs
112; set flags for later code to fill in map_table
113
114 or page_flags,p0_flag ; set p0 flag
115
116 jmp get_args ; go get another argument
117
118check_p1:
119 cmp p1_result.$P_Type,2 ; was there a p1= in this pass?
120 jne check_p2 ; no, look for a P2
121
122 mov parse_flag,1 ; set parse flag
123
124 mov byte ptr p1_ctl+9,0 ; turn this off so we don't allow another
125 mov p1_result.$P_Type,0 ; clear this so we don't get fooled later
126
127 mov byte ptr frame_ctl+9,0 ; turn this off so we don't allow another
128
129 push si ;save regs
130
131 mov si,word ptr p1_result.$P_Picked_Val[+0]
132
133 mov word ptr ds:[si+0],0
134
135 pop si ;restore regs
136; set flags for later code to fill in map_table
137
138 or page_flags,p1_flag ; set p1 flag
139
140 jmp get_args ; go get another argument
141
142check_p2:
143 cmp p2_result.$P_Type,2 ; was there a p2= in this pass?
144 jne check_p3 ; no, look for a p3
145
146 mov parse_flag,1 ; set parse flag
147
148 mov byte ptr p2_ctl+9,0 ; turn this off so we don't allow another
149 mov p2_result.$P_Type,0 ; clear this so we don't get fooled later
150
151 mov byte ptr frame_ctl+9,0 ; turn this off so we don't allow another
152
153 push si ;save regs
154
155 mov si,word ptr p2_result.$P_Picked_Val[+0]
156
157 mov word ptr ds:[si+0],0
158
159 pop si ;restore regs
160; set flags for later code to fill in map_table
161
162 or page_flags,p2_flag ; set p2 flag
163
164 jmp get_args ; go get another argument
165
166check_p3:
167 cmp p3_result.$P_Type,2 ; was there a p3= in this pass?
168 jne check_p254 ; no, look for a P254
169
170 mov parse_flag,1 ; set parse flag
171
172 mov byte ptr p3_ctl+9,0 ; turn this off so we don't allow another
173 mov p3_result.$P_Type,0 ; clear this so we don't get fooled later
174
175 mov byte ptr frame_ctl+9,0 ; turn this off so we don't allow another
176
177 push si ;save regs
178
179 mov si,word ptr p3_result.$P_Picked_Val[+0]
180
181 mov word ptr ds:[si+0],0
182
183 pop si ;restore regs
184; set flags for later code to fill in map_table
185
186 or page_flags,p3_flag ; set p3 flag
187
188 jmp get_args ; go get another argument
189
190check_p254:
191 cmp p254_result.$P_Type,2 ; was there a p254= in this pass?
192 jne check_p255 ; no, look for a P255
193
194 mov parse_flag,1 ; set parse flag
195
196 mov byte ptr p254_ctl+9,0 ; turn this off so we don't allow another
197 mov p254_result.$P_Type,0 ; clear this so we don't get fooled later
198
199 push si ;save regs
200
201 mov si,word ptr p254_result.$P_Picked_Val[+0]
202
203 mov word ptr ds:[si+0],0
204
205 pop si ;restore regs
206; set flags for later code to fill in map_table
207
208 or page_flags,p254_flag ; set p254 flag
209
210 jmp get_args ; go get another argument
211
212check_p255:
213 cmp p255_result.$P_Type,2 ; was there a P255= in this pass?
214 je do_p255 ; yes, process it
215 jmp Check_X ; no, find out if /X was included
216
217do_p255:
218 mov parse_flag,1 ; set parse flag
219
220 mov byte ptr p255_ctl+9,0 ; turn this off so we don't allow another
221 mov p255_result.$P_Type,0 ; clear this so we don't get fooled later
222
223 push si ;save regs
224
225 mov si,word ptr p255_result.$P_Picked_Val[+0]
226
227 mov word ptr ds:[si+0],0
228
229 pop si ;restore regs
230; set flags for later code to fill in map_table
231
232 or page_flags,p255_flag ; set p255 flag
233
234 jmp get_args ; go get another argument
235
236Check_X:
237 cmp es:X_Result.$P_SYNONYM_Ptr,offset es:X_Switch.$P_KeyorSW ; switch Ptr ;an000; dms;
238 je Do_X ; yes, process it
239 jmp get_args ; no, must have been the positional, ignore it and go on
240
241Do_X:
242
243 push ax ; save regs
244 mov ax,es:word ptr X_Result.$P_Picked_Val ;get low word of result ;an000; dms;
245 mov cs:EMS_Pgs_Parm,ax ; pass to program ;an000; dms;
246 pop ax ; restore regs
247
248 jmp get_args ; go get another argument
249
250
251
252
253; getting here means invalid argument, figure out what to do later
254
255end_of_input_line:
256
257 cmp parse_flag,null ; were there command line args?
258 jne cmd_line_args ; yes, process them
259 jmp null_cmd_line ; no, skip processing
260
261cmd_line_args:
262
263; put the stuff into map_table, this is done by looking at flags set
264; by the above code and putting the addresses into map_table
265
266 push ax ; save some regs
267 push bx
268 push cx
269 push dx
270 push di
271
272 xor di,di ; clear index pointer
273
274 mov map_count,null ; clear map count default
275
276 test page_flags,frame_flag ; was FRAME= included?
277 jz chk_p0 ; no, try p0
278
279; yes, fix up page count and fill in map_table
280
281 mov map_count,4 ; FRAME= takes up 4 map entries
282
283; convert the item tag into a segment address
284
285 xor ah,ah ; make 0
286 mov al,frame_result.$P_Item_Tag ; get item tag
287 mov cx,8 ; need to shift left eight bits
288 shl ax,cl ; to convert to a segment address
289
290; do some math with di
291
292 xor di,di ; clear index pointer
293
294; save the segment addresses in map_table
295
296 mov map_table.phys_page_segment[di],ax ; store p0 segment
297 mov map_table.phys_page_number[di],0 ; p0 page number
298 mov cs:Page_Frame_Sta,ax ;save our page for XMA1 ;an000; dms;
299 ; diags.
300
301 add ax,400h ; increase segment ID by 16K
302 add di,type mappable_phys_page_struct
303
304 mov map_table.phys_page_segment[di],ax ; store p1 segment
305 mov map_table.phys_page_number[di],1 ; p1 page number
306
307 add ax,400h ; increase segment ID by 16K
308 add di,type mappable_phys_page_struct
309
310 mov map_table.phys_page_segment[di],ax ; store p2 segment
311 mov map_table.phys_page_number[di],2 ; p2 page number
312
313 add ax,400h ; increase segment ID by 16K
314 add di,type mappable_phys_page_struct
315
316 mov map_table.phys_page_segment[di],ax ; store p3 segment
317 mov map_table.phys_page_number[di],3 ; p3 page number
318
319; do some math with di, this will be used as a pointer into map_table
320
321 add di,type mappable_phys_page_struct
322
323 jmp chk_p254 ; FRAME= implies that p0 - p3 were not present,
324 ; skip ahead and look for p254 and p255
325
326; check for p0
327
328chk_p0:
329
330 test page_flags,p0_flag ; was p0= included?
331 jz chk_p1 ; no, try p1
332
333; yes, fix up page count and fill in map_table
334
335 add map_count,1 ; one extra map entry
336
337; convert the item tag into a segment address
338
339 xor ah,ah ; make 0
340 mov al,p0_result.$P_Item_Tag; get item tag
341 mov cx,8 ; need to shift left eight bits
342 shl ax,cl ; to convert to a segment address
343
344
345; save the segment addresses in map_table
346
347 mov map_table.phys_page_segment[di],ax ; store p0 segment
348 mov map_table.phys_page_number[di],0 ; p0 page number
349 mov cs:Page_Frame_Sta,ax ;save our page for XMA1 ;an000; dms;
350 ; diags.
351
352; do some math with di, this will be used as a pointer into map_table
353
354 add di,type mappable_phys_page_struct
355
356;------------------------
357; check for p1
358;------------------------
359
360chk_p1:
361
362 test page_flags,p1_flag ; was p1= included?
363 jz chk_p2 ; no, try p2
364
365; yes, fix up page count and fill in map_table
366
367 add map_count,1 ; one extra map entry
368
369; convert the item tag into a segment address
370
371 xor ah,ah ; make 0
372 mov al,p1_result.$P_Item_Tag; get item tag
373 mov cx,8 ; need to shift left eight bits
374 shl ax,cl ; to convert to a segment address
375
376
377; save the segment addresses in map_table
378
379 mov map_table.phys_page_segment[di],ax ; store p1 segment
380 mov map_table.phys_page_number[di],1 ; p0 page number
381 mov cs:Page_Frame_Sta,ax ;save our page for XMA1 ;an000; dms;
382 ; diags.
383
384; do some math with di, this will be used as a pointer into map_table
385
386 add di,type mappable_phys_page_struct
387
388;------------------------
389; check for p2
390;------------------------
391
392chk_p2:
393
394 test page_flags,p2_flag ; was p2= included?
395 jz chk_p3 ; no, try p3
396
397; yes, fix up page count and fill in map_table
398
399 add map_count,1 ; one extra map entry
400
401; convert the item tag into a segment address
402
403 xor ah,ah ; make 0
404 mov al,p2_result.$P_Item_Tag; get item tag
405 mov cx,8 ; need to shift left eight bits
406 shl ax,cl ; to convert to a segment address
407
408
409; save the segment addresses in map_table
410
411 mov map_table.phys_page_segment[di],ax ; store p2 segment
412 mov map_table.phys_page_number[di],2 ; p2 page number
413 mov cs:Page_Frame_Sta,ax ;save our page for XMA1 ;an000; dms;
414 ; diags.
415
416; do some math with di, this will be used as a pointer into map_table
417
418 add di,type mappable_phys_page_struct
419
420;------------------------
421; check for p3
422;------------------------
423
424chk_p3:
425
426 test page_flags,p3_flag ; was p3= included?
427 jz chk_p254 ; no, try p254
428
429; yes, fix up page count and fill in map_table
430
431 add map_count,1 ; one extra map entry
432
433; convert the item tag into a segment address
434
435 xor ah,ah ; make 0
436 mov al,p3_result.$P_Item_Tag; get item tag
437 mov cx,8 ; need to shift left eight bits
438 shl ax,cl ; to convert to a segment address
439
440
441; save the segment addresses in map_table
442
443 mov map_table.phys_page_segment[di],ax ; store p3 segment
444 mov map_table.phys_page_number[di],3 ; p3 page number
445 mov cs:Page_Frame_Sta,ax ;save our page for XMA1 ;an000; dms;
446 ; diags.
447
448; do some math with di, this will be used as a pointer into map_table
449
450 add di,type mappable_phys_page_struct
451
452;------------------------
453; check for p254
454;------------------------
455
456chk_p254:
457
458 test page_flags,p254_flag ; was p254= included?
459 jz chk_p255 ; no, try p255
460
461; yes, fix up page count and fill in map_table
462
463 add map_count,1 ; one extra map entry
464
465; convert the item tag into a segment address
466
467 xor ah,ah ; make 0
468 mov al,p254_result.$P_Item_Tag; get item tag
469 mov cx,8 ; need to shift left eight bits
470 shl ax,cl ; to convert to a segment address
471
472
473; save the segment addresses in map_table
474
475 mov map_table.phys_page_segment[di],ax ; store p254 segment
476 mov map_table.phys_page_number[di],0feh ; p254 page number
477 mov cs:Page_Frame_Sta,ax ;save our page for XMA1 ;an000; dms;
478 ; diags.
479
480; do some math with di, this will be used as a pointer into map_table
481
482 add di,type mappable_phys_page_struct
483
484;------------------------
485; check for p255
486;------------------------
487
488chk_p255:
489
490 test page_flags,p255_flag ; was p255= included?
491 jz Chk_X ; no, /X switch
492
493; yes, fix up page count and fill in map_table
494
495 add map_count,1 ; one extra map entry
496
497; convert the item tag into a segment address
498
499 xor ah,ah ; make 0
500 mov al,p255_result.$P_Item_Tag; get item tag
501 mov cx,8 ; need to shift left eight bits
502 shl ax,cl ; to convert to a segment address
503
504
505; save the segment addresses in map_table
506
507 mov map_table.phys_page_segment[di],ax ; store p255 segment
508 mov map_table.phys_page_number[di],0ffh ; p255 page number
509 mov cs:Page_Frame_Sta,ax ;save our page for XMA1 ;an000; dms;
510 ; diags.
511
512; do some math with di, this will be used as a pointer into map_table
513
514 add di,type mappable_phys_page_struct
515
516Chk_X:
517
518 pop di ; restore some regs
519 pop dx
520 pop cx
521 pop bx
522 pop ax
523
524
525null_cmd_line:
526 CMP AL,AL ; else set zf to indicate no error
527 ret ; return to calling routine
528
529
530GET_PARMS ENDP
diff --git a/v4.0/src/DEV/XMA2EMS/PS2_5060.INC b/v4.0/src/DEV/XMA2EMS/PS2_5060.INC
new file mode 100644
index 0000000..96425f5
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/PS2_5060.INC
@@ -0,0 +1,735 @@
1;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
2;³ Include File: PS2_5060.INC ³
3;³ ³
4;³ Purpose: Initialization code for the Personal Systems/2 ³
5;³ models 50 and 60. ³
6;³ ³
7;³ Returns: INIT_ERR ³
8;³ Flag indicating if an error was detected. ³
9;³ DX = ptr to error message string if error. ³
10;³ ³
11;³ This procedure is called to initialize the XMO and/or XMA/A ³
12;³ card(s) on a PS/2 mod 50 or 60. Any mix of multiple XMA and ³
13;³ XMO cards are supported. The XMA cards will be used in ³
14;³ 'real' mode, meaning the virtual mode ports providing bank ³
15;³ swapping are not used (since this only works on 1 XMA card). ³
16;³ This procedure is not called if WSP's XMA/A device driver ³
17;³ (INDXMAA.SYS) is installed. In this case only the single XMA ³
18;³ card is used for EMS, and it is spoken to in 'virtual' mode. ³
19;³ The procedure searches each adapter slot for the presence of ³
20;³ an XMA or a XMO card by checking the card ID. It checks ³
21;³ the configuration registers on the cards to determine the amount ³
22;³ of memory they contain. ³
23;³ The procedure will then calculate for the /E parameter. This ³
24;³ states how much of the extended memory the user wants for EMS. ³
25;³ Extended memory will come from the top of the address range, ³
26;³ and EMS will come off the bottom (i.e. starting at 1M+384K). ³
27;³ Memory kept as extended has to be marked unusable in the Page ³
28;³ Allocation List. Translate table entries in extended memory ³
29;³ are disabled for memory used for EMS. ³
30;³ Note that the /E parameter is only valid within this ³
31;³ procedure, i.e. for PS/2 mod 50 and 60's. On family 1 machines, ³
32;³ only the XMA 1 card is supported, and it doesn't come up as ³
33;³ extended memory. On mod 50 or 60 with the XMA/A driver, the ³
34;³ driver takes all of the (uppermost) XMA card and resets CMOS. ³
35;³ On the mod 80 with the XMA emulator, this XMA/extended split ³
36;³ must be specified on the Emulator's parm line. ³
37;³ ³
38;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
39
40include SYSVAR.INC ;system variables structure ;an007; dms;
41
42
43 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
44 ;³ XMA/A declares ³
45 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
46HI6BIT_MASK EQU 00000011b ;Mask for 2 bit bank descriptor
47LO2BIT_FLIP EQU 00000011b ;Reverses bottom 2 bits in bank des
48 ; gives # of 1/2M in that bank
49NUM_CONFR_BANKS EQU 3 ;Number of memory banks described
50 ; by the XMA/A config register
51 ; Bank 4 is on the control reg.
52X_CONF_REG_VAL DB ? ;temporary holder for XMAA's
53 ; config (memory size) register
54X_CTRL_REG_VAL DB ? ;temporary holder for XMAA's
55 ; control (mem size bank 4) reg.
56X_BLKS_PER_HALFM DB 128 ;4K blocks per half meg of memory
57XMAA_NUM_BLOCKS DW ? ;temp for # of 4K blocks on xmaa @RH2
58 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
59 ;³ Expanded Memory Option (XMO) declares ³
60 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
61NUM_CINFO_BANKS EQU 3 ;# of complete memory banks (4-2)
62 ; described by the XMO card info reg
63 ; Bank 1 - hi 1/2 bit - info, lo CC/P
64H_CARD_INFO_VAL DB ? ;temporary holder for XMO card's
65 ; info (memory size) register
66H_BLKS_PER_HALFM DB 32 ;16K XMO card blocks per 1/2M of mem
67HLST_NUM_BLOCKS DW ? ;temp for # of 16K blocks on hlstr @RH3
68 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
69 ;³ /E option declares ³
70 ;³ (used to set extended memory) ³
71 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
72ems_pgs_parm dw 0 ;temp value for /E parameter
73e_parm_def equ 0FFFFh ;default...take all for ems
74MIN_EXTMEM_H EQU (1024+384)/16 ;Translate table pointer for the lowest
75MIN_EXTMEM_X EQU (1024+384)/4 ; addr extended memory can start at on
76BASE_MEM EQU 1024 ;Base planer memory ;an007; dms;
77 ; a PS/2 (16K XMO and 4K XMA)
78PREV_EXT_PGS DW 0 ;Extended memory claimed by previous
79 ; drivers
80NEEDED_EMS_PGS DW ? ;Pages that will go for EMS use
81CARDS_PGS DW ? ;Number of pages on card being checked
82CARD_EXT_S16K DW ? ; and where its extended memory starts
83 ; expressed in 16K blocks
84
85INIT_MOD_50_60 PROC
86
87 PUSH AX
88 PUSH BX
89 PUSH CX
90 PUSH SI
91 PUSH DI
92
93 MOV INIT_ERR,NO_ERROR ;Initialize error flag @RH4
94 MOV TOTAL_SYS_PAGES,0 ;Init total number of pages in the @RH2
95 MOV NUM_MEM_CARDS,0 ; system & # of memory cards found @RH2
96 XOR DI,DI ;Clear offset into mem card table @RH2
97
98 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
99 ;³ Search for XMO cards ³
100 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
101 XOR CX,CX ;Check all system slots starting @RH2
102 ; at slot 0 RH2
103H_SLOT_SCAN:
104 MOV AL,CL ;Enable the specific slot by ORing @RH2
105 OR AL,SLOT_SETUP ; the slot (bits 0-2) with the @RH2
106 OUT 96h,AL ; setup flag (bit 3). @RH2
107
108 MOV DX,CARD_ID_LO ;Read the signature ID of the card @RH2
109 IN AL,DX ; @RH2
110 XCHG AL,AH ; @RH2
111 MOV DX,CARD_ID_HI ; @RH2
112 IN AL,DX ; @RH2
113HLST_CHECK:
114 CMP AX,HLST_CARD_ID ;If it's a XMO card then @RH3
115 JNE H_NEXT_SLOT ; calculate the amount of memory @RH3
116 CALL HLST_MEM_ADD ; on the card @RH3
117 MOV WTT_CARD_SLOT,CL ;Set default slot # and card type @RH5
118 MOV MEMCARD_MODE,HOLS_REAL ; for single card support @RH5
119
120 MOV BX,HLST_NUM_BLOCKS ;1 XMO card block = an EMS page
121
122 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
123 ;³ Save info in the memory card table ³
124 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
125 MOV MEM_CARD_TABLE.CARD_ID[DI],AX ;Save the card ID and @RH5
126 MOV MEM_CARD_TABLE.CARD_SLOT[DI],CL ; slot # of this card @RH5
127 MOV AX,TOTAL_SYS_PAGES ;Set # of the 1st EMS @RH5
128 MOV MEM_CARD_TABLE.START_PG_NUM[DI],AX ; page this card maps @RH5
129 ADD AX,BX ;Last page mapped = @RH5
130 DEC AX ; 1st pg + pages on @RH5
131 MOV MEM_CARD_TABLE.END_PG_NUM[DI],AX ; this card - 1. @RH5
132
133 ADD TOTAL_SYS_PAGES,BX ;Add card's pgs to tot. @RH5
134 INC NUM_MEM_CARDS ;Inc # of cards found @RH5
135 ADD DI,TYPE MEM_CARD_STRUC ;Next entry in card @RH5
136 ; descriptor table RH5
137
138H_NEXT_SLOT:
139 INC CL ;Check next adapter slot @RH2
140 CMP CL,NUM_OF_SLOTS ;Is it <= system slots? @RH2
141 JB H_SLOT_SCAN ;Yes..check next slot ;ac000; dms;
142 ;No fall through loop RH2
143
144 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
145 ;³ Search for XMA/A cards ³
146 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
147 XOR CX,CX ;Check all slots starting at 0 @RH2
148X_SLOT_SCAN:
149 MOV AL,CL ;Enable the specific slot by ORing @RH2
150 OR AL,SLOT_SETUP ; the slot (bits 0-2) with the @RH2
151 OUT 96h,AL ; setup flag (bit 3). @RH2
152
153 MOV DX,CARD_ID_LO ;Read the signature ID of the card @RH2
154 IN AL,DX ; @RH2
155 XCHG AL,AH ; @RH2
156 MOV DX,CARD_ID_HI ; @RH2
157 IN AL,DX ; @RH2
158XMAA_CHECK:
159 CMP AX,XMAA_CARD_ID ;If it's an XMA/A card then @RH2
160 JNE X_NEXT_SLOT ; calculate the amount of memory @RH2
161 CALL XMAA_MEM_ADD ; on the card @RH2
162 MOV WTT_CARD_SLOT,CL ;Set default slot # and card type @RH5
163 MOV MEMCARD_MODE,XMAA_REAL ; for single card support @RH5
164
165 MOV BX,XMAA_NUM_BLOCKS ;Divide the # of 4K XMA/A blocks @RH2
166 SHR BX,1 ; by 4 to get number or 16K EMS @RH2
167 SHR BX,1 ; pages on this card @RH2
168
169 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
170 ;³ Save info in the memory card table ³
171 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
172 MOV MEM_CARD_TABLE.CARD_ID[DI],AX ;Save the card ID and @RH5
173 MOV MEM_CARD_TABLE.CARD_SLOT[DI],CL ; slot # of this card @RH5
174 MOV AX,TOTAL_SYS_PAGES ;Set # of the 1st EMS @RH5
175 MOV MEM_CARD_TABLE.START_PG_NUM[DI],AX ; page this card maps @RH5
176 ADD AX,BX ;Last page mapped = @RH5
177 DEC AX ; 1st pg + pages on @RH5
178 MOV MEM_CARD_TABLE.END_PG_NUM[DI],AX ; this card - 1. @RH5
179
180 ADD TOTAL_SYS_PAGES,BX ;Add card's pgs to tot. @RH5
181 INC NUM_MEM_CARDS ;Inc # of cards found @RH5
182 ADD DI,TYPE MEM_CARD_STRUC ;Next entry in card @RH5
183 ; descriptor table RH5
184
185X_NEXT_SLOT:
186 INC CL ;Check next adapter slot @RH2
187 CMP CL,NUM_OF_SLOTS ;Is it <= system slots? @RH2
188 JB X_SLOT_SCAN ;Yes..check next slot ;ac000; dms;
189 ;No fall through loop RH2
190
191 CMP TOTAL_SYS_PAGES,0 ;If one or more cards are found @RH4
192 JA CALC_EXTENDED ; then everythang's cool so far @RH4
193 MOV INIT_ERR,ERROR ;Else no card...set @RH4
194 MOV DX,OFFSET NOT_FOUND_MSG ; 1st part of error msg @RH4
195 JMP INIT_50_60_RET ; for no card found @RH4
196
197 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
198 ;³ Calculate /E parameter - amount of memory for EMS ³
199 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
200 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
201 ;³ Find ext mem addr of bottom card ³
202 ;³ in case card memory ever starts at ³
203 ;³ something other than 1M + 384K ³
204 ;³ (i.e. if more planar memory is ³
205 ;³ added or a new unsupported card ³
206 ;³ comes in below XMO card) ³
207 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
208CALC_EXTENDED:
209 push es ;this call kills these regs ;an007; dms;
210 push bx ; ;an007; dms;
211
212 mov ah,52h ;get the sysvars ptr ;an007; dms;
213 int 21h ; to get total ext. memory at boot ;an007; dms;
214 mov ax,word ptr es:[bx].SYSI_Ext_Mem ; ;an007; dms;
215
216 pop bx ;restore regs ;an007; dms;
217 pop es ; ;an007; dms;
218
219 add ax,Base_Mem ; + base memory ;an007; dms;
220 MOV CL,4 ; convert to 16Kb pages ;an007; dms;
221 SHR AX,CL ; ;an007; dms;
222 sub ax,cs:Total_Sys_Pages ;get page where card begins ;an007; dms;
223
224 xor di,di ;init. index value ;an008; dms
225 CMP MEM_CARD_TABLE.CARD_ID[DI],HLST_CARD_ID ;If 1st card holst @RH4
226 JE FIND_H_1ST_TT ; then get hlst TT @RH4
227FIND_X_1ST_TT: ;XMAA is 1st card (lowest ext mem) @RH4
228;;;;; MOV AX,MIN_EXTMEM_X ;Set XMAA TT ptr at 1.384M and @RH4
229 shl ax,1 ; ;an000; dms;
230 shl ax,1 ; ;an000; dms;
231FIND_X_1ST_LOOP: ; search for start of ext mem @RH4
232 CALL X_READ_TT ;Read trans tbl data at this addr @RH4
233 CMP BX,XMA_TT_INHIBIT ;If not inhibitted then mem here. @RH4
234 JE FIND_X_1ST_NEXT ;Divide the 4K translate table ptr @RH4
235 MOV CL,2 ; by 4 to convert it to 16K format @RH4
236 SHR AX,CL ; AX = start of ext mem (in 16K) @RH4
237 JMP FIRST_EXT_FOUND ; @RH4
238FIND_X_1ST_NEXT: ; @RH4
239 INC AX ;Else no mem...inc TT ptr and see @RH4
240 JMP FIND_X_1ST_LOOP ; if ext mem starts at next 4K @RH4
241
242FIND_H_1ST_TT: ;XMO is 1st card (lowest ext mem) @RH4
243;;;;; MOV AX,MIN_EXTMEM_H ;Set hlst TT ptr at 1.384M and @RH4
244FIND_H_1ST_LOOP: ; search for start of ext mem @RH4
245 CALL H_READ_TT ;Read trans tbl data at this addr @RH4
246 CMP BL,H_TT_INHIBIT ;If not inhibitted then mem here. @RH4
247 JNE FIRST_EXT_FOUND ; found start of card ext mem @RH4
248 INC AX ;Else no mem...inc TT ptr and see @RH4
249 JMP FIND_H_1ST_LOOP ; if ext mem starts at next 16K @RH4
250FIRST_EXT_FOUND:
251 MOV CARD_EXT_S16K,AX ;Save the start of ext mem ptr @RH4
252 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
253 ;³ Calc pages for extended memory ³
254 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
255 MOV AH,88H ;Go to BIOS and find amount of @RH4
256 INT 15H ; extended memory (assume previous @RH4
257 MOV CL,4 ; drivers have hooked INT 15h) @RH4
258 SHR AX,CL ;Get # of 16k pages @RH4
259
260 MOV BX,CARD_EXT_S16K ;Pages of extended memory used @RH4
261 ADD BX,TOTAL_SYS_PAGES ; by previous drivers = @RH4
262 SUB BX,1024/16 ; what we know is the # of ext @RH4
263 SUB BX,AX ; pages minus what BIOS tells us @RH4
264 MOV PREV_EXT_PGS,BX ; @RH4
265
266 CMP EMS_PGS_PARM,E_PARM_DEF ;If no /E parm specified then @RH4
267 JNE CHECK_E_PARM ; use the remaining pages for EMS @RH4
268 MOV AX,TOTAL_SYS_PAGES ; (total on cards minus previously @RH4
269 cmp Prev_Ext_Pgs,ax ;Previous ext pages >= avail on cards? ;an000; dms;
270 jae Default_Mem_Err_Exit ;yes - we have used the whole card ;an000; dms;
271 SUB AX,PREV_EXT_PGS ; used for extended memory) @RH4
272 MOV NEEDED_EMS_PGS,AX ;Set counter for marking PAL and TT@RH4
273 JMP SHORT MARK_EXT_IN_PAL
274
275Default_Mem_Err_Exit:
276
277 mov Init_Err,Error ;flag an error occurred ;an000; dms;
278 lea dx,No_EMS_Memory ;no memory on cards left ;an000; dms;
279 jmp Init_50_60_Ret ;exit routine ;an000; dms;
280
281CHECK_E_PARM: ;Else test user specified # EMS pgs@RH4
282 MOV BX,EMS_PGS_PARM ;Set counter for marking Page @RH4
283 MOV NEEDED_EMS_PGS,BX ; Allocation List and TT entries @RH4
284 MOV AX,TOTAL_SYS_PAGES ;If the requested EMS pages are @RH4
285 SUB AX,PREV_EXT_PGS ; more than what's left @RH4
286 CMP AX,EMS_PGS_PARM ; (total pages minus pages @RH4
287 JGE MARK_EXT_IN_PAL ; used by other drivers) then set @RH4
288 MOV INIT_ERR,ERROR ; an error condition flag @RH4
289 LEA DX,REQ_EMS_ERR_MSG ; Set first part of error message @RH4
290 JMP INIT_50_60_RET ; @RH4
291
292 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
293 ;³ Mark PAL for extended memory pages ³
294 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
295MARK_EXT_IN_PAL:
296 xor di,di ;start at bottom of PAL to init EXT ;an002; dms;
297MARK_NEW_IN_PAL:
298 MOV CX,TOTAL_SYS_PAGES ;Loop for the 'new' extended pages @RH4
299 SUB CX,NEEDED_EMS_PGS ; (left over from /E parm and not @RH4
300 SUB CX,PREV_EXT_PGS ; reserved by a previous driver) @RH4
301 MOV RESR_EXT_PGS,CX ; @RH4
302 CMP CX,0 ; This assumes that others anyone @RH4
303 JE MARK_PREV_IN_PAL ; using extended memory after us @RH4
304MARK_NEW_LP: ; will take it from the top @RH4
305 MOV PAGE_ALLOC_LIST[DI],RESR_EXT ;Place a 'RE' in the PAL @RH4
306 ADD DI,TYPE PAGE_ALLOC_LIST ; (Reserved Extended) for @RH4
307 LOOP MARK_NEW_LP ; these entries @RH4
308
309MARK_PREV_IN_PAL:
310 MOV AX,NEEDED_EMS_PGS ;Set offset into Page Alloc List @RH4
311 add ax,Resr_Ext_Pgs ;get end of area for EMS pages ;an002; dms;
312 MOV DX,TYPE PAGE_ALLOC_LIST ; for the page where extended mem @RH4
313 MUL DX ; starts. This is done by skipping@RH4
314 MOV DI,AX ; over the EMS pages on bottom @RH4
315 MOV CX,PREV_EXT_PGS ;Loop for the previous extended @RH4
316 CMP CX,0 ; memory pages (if any). This is @RH4
317 JE DIS_EMS_TT ; ext mem claimed before we load @RH4
318MARK_PREV_LP: ; @RH4
319 MOV PAGE_ALLOC_LIST[DI],PREV_EXT ;Place a 'PE' in the PAL @RH4
320 ADD DI,TYPE PAGE_ALLOC_LIST ; (Previous Extended) for @RH4
321 LOOP MARK_PREV_LP ; these entries @RH4
322 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
323 ;³ Disable translate table entries ³
324 ;³ in extended memory for memory ³
325 ;³ used as EMS ³
326 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
327
328DIS_EMS_TT:
329
330 mov cx,Resr_Ext_Pgs ;get extended page count ;ac008; dms;
331 ;1 based page count
332
333 xor di,di ;set mem card table ptr ;an002; dms;
334
335Card_Find_Chk:
336
337 cmp cx,Mem_Card_Table.End_Pg_Num[di];page > ending page on card? ;ac008; dms;
338 ja Card_Find_Loop ;yes - next card please ;an002; dms;
339 add Card_Ext_S16K,cx ;get 1st. avail page ;an008; dms;
340 mov cx,Mem_Card_Table.End_Pg_Num[di];Calc # pages remaining on card ;an002; dms;
341 sub cx,Resr_Ext_Pgs ; ;ac008; dms;
342 inc cx ; ;an002; dms;
343 jmp Calc_Cards_EMS ; ;an002; dms;
344
345Card_Find_Loop:
346
347 add di,Type Mem_Card_Struc ;next pointer ;an002; dms;
348 jmp Card_Find_Chk ;continue loop ;an002; dms;
349
350
351CALC_CARDS_EMS:
352
353 MOV CARDS_PGS,CX ; @RH4
354
355 ;Calc # of pages to inhibit for. @RH4
356 CMP CX,NEEDED_EMS_PGS ;If the card has less pgs than @RH4
357 JBE ADJUST_NEEDED_EMS ; # needed for EMS then just loop @RH4
358 MOV CX,NEEDED_EMS_PGS ; for card. Else loop for needed. @RH4
359
360ADJUST_NEEDED_EMS:
361 SUB NEEDED_EMS_PGS,CX ;Remaining EMS pages to inhibit @RH4
362 ; after this card is taken care of @RH4
363
364 MOV AL,MEM_CARD_TABLE.CARD_SLOT[DI] ;Activate the slot of @RH4
365 OR AL,SLOT_SETUP ; the card and set ptr @RH4
366 OUT 96h,AL ; to where it's ext mem @RH4
367 MOV AX,CARD_EXT_S16K ; starts @RH4
368
369 CMP MEM_CARD_TABLE.CARD_ID[DI],HLST_CARD_ID ;Test card type @RH4
370 JE H_INHIBIT_EMS ; @RH4
371X_INHIBIT_EMS: ;Inhibit TT on XMA/A for EMS @RH4
372 PUSH CX ;Save ctr for # EMS on this card @RH4
373 MOV CL,2 ;Convert 16K start of EMS ptr to @RH4
374 SHL AX,CL ; 4K XMA/A translate table format @RH4
375 POP CX ;Restore # EMS pages counter @RH4
376X_INH_EMS_PGS: ;----Loop for all XMA EMS pages----@RH4
377 PUSH CX ;Save # EMS pages ctr @RH4
378 MOV CX,BLOCKS_PER_PAGE ;Loop for all XMA blocks in a pg @RH4
379X_INH_ONE_PAGE: ;----Loop for one XMA EMS page-----@RH4
380 CALL X_INH_FOR_EMS ;Inhibit TT entry (AX = 4K ptr) @RH4
381 INC AX ;Next XMA block @RH4
382 LOOP X_INH_ONE_PAGE ; @RH4
383 POP CX ;Restore ctr for # EMS pgs on card @RH4
384 LOOP X_INH_EMS_PGS ;Loop for # EMS pgs on card @RH4
385 JMP short next_card_ems ;Now go fix that page alloc table @RH4
386
387H_INHIBIT_EMS: ;Inhibit TT on XMO for EMS @RH4
388 CALL H_INH_FOR_EMS ;Inhibit one TT entry per EMS page @RH4
389 INC AX ;Next 16K pointer @RH4
390 LOOP H_INHIBIT_EMS ; and do it again yahoooooo @RH4
391
392NEXT_CARD_EMS:
393 CMP NEEDED_EMS_PGS,0 ;If this card had the rest of the @RH4
394 JE INIT_50_60_RET ; EMS pages then done disabling TT @RH4
395 ;Else EMS on next card. Set ptr @RH4
396 MOV AX,CARDS_PGS ; to where next card's ext mem @RH4
397 ADD CARD_EXT_S16K,AX ; starts (in units of 16K) and save@RH4
398
399 ADD DI,TYPE MEM_CARD_STRUC ;Next entry in the memory card @RH4
400
401 mov cx,Mem_Card_Table.End_Pg_Num[di] ;calc pages on ;an002; dms;
402 sub cx,Mem_Card_Table.Start_Pg_Num[di] ;card ;an002; dms;
403 inc cx ; ;an002; dms;
404
405 JMP CALC_CARDS_EMS ; table. @RH4
406
407INIT_50_60_RET:
408
409 MOV AX,TOTAL_SYS_PAGES ;Total EMS pages in the system = @RH4
410 SUB AX,PREV_EXT_PGS ; pages on cards - amount used @RH4
411 SUB AX,RESR_EXT_PGS ; as extended memory @RH4
412 MOV TOTAL_SYS_PAGES,AX ;Initialize values for: @RH4
413 MOV TOTAL_EMS_PAGES,AX ; EMS pages - pages to back planar @RH4
414 MOV FREE_PAGES,AX ; EMS pages free for applications @RH4
415
416 MOV AL,0 ;Reset the slot ID @RH5
417 OUT 96h,AL ; @RH5
418
419 POP DI
420 POP SI
421 POP CX
422 POP BX
423 POP AX
424 RET
425INIT_MOD_50_60 ENDP
426
427;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
428;³ HLST_MEM_ADD subprocedure ³
429;³ Calculates the amount of memory on the XMO card ³
430;³ on entry: (CL) = card slot # ³
431;³ card is in setup mode ³
432;³ ³
433;³ The following describes how to read memory size, where the 2 bit ³
434;³ pattern indicates SIP size. There are 2 SIPs per bank. ³
435;³ ³
436;³ Reg: Card Info Channel Check, Presence ³
437;³ Port: 102h 105h ³
438;³ SIPS: bank 4 bank 3 bank 2 bank 1 bank 1 ³
439;³ Bit: 7 6 5 4 3 2 1 0 ³
440;³ -----------------------------------------------------------------³
441;³ 1 1 1 1 1 1 1 1 No memory,error ³
442;³ 1 0 1 0 1 0 1 0 256K ³
443;³ 0 1 0 1 0 1 0 1 512K ³
444;³ 0 0 0 0 0 0 0 0 1M ³
445;³ ³
446;³ Note that for bank 0, 102's bit 1 forms the upper bit and ³
447;³ 105's bit 0 forms the lower of the 2 bit presence pattern. ³
448;³ Therefore, if the pattern is '10'B, then the bank has 256K. ³
449;³ ³
450;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
451HLST_MEM_ADD PROC
452 PUSH DX ; @RH3
453 PUSH CX ; @RH3
454 PUSH AX ; @RH3
455
456 MOV HLST_NUM_BLOCKS,0 ;Init # of 16K blocks on card @RH3
457
458 MOV DX,H_CARD_INFO ;Read & store card info reg (102h) @RH3
459 IN AL,DX ; bits 7-2 describe banks 4-2 @RH3
460 AND AL,11111110B ; bit 1 upper half of bank 1 descr @RH3
461 MOV H_CARD_INFO_VAL,AL ; (don't care about sleep bit 0) @RH3
462 MOV DX,H_CC_PRES ;Read chan. check & presence (105) @RH3
463 IN AL,DX ; for bit 0 - lower half of bank 1 @RH3
464 AND AL,00000001B ; Turn off all other bits @RH3
465 OR AL,H_CARD_INFO_VAL ;Join 2 bits - bank 1 descriptor @RH3
466
467 XOR AL,LO2BIT_FLIP ;Flip these 2 to get # of 1/2 Megs @RH3
468 ; in bank 1 of XMO card @RH3
469 AND AL,HI6BIT_MASK ;Clear other bits @RH3
470 CMP AL,LO2BIT_FLIP ;Are both bits on (i.e. 1M sips)? @RH3
471 JNE H_B1_HMEG_OK ;No # of 1/2 M for bank OK (0,1,2)@RH3
472 INC AL ;Yes # of 1/2 M should be 4 not 3 @RH3
473H_B1_HMEG_OK:
474 MUL H_BLKS_PER_HALFM ;Multiply by # of 16k Blocks per @RH3
475 ; half meg to get bank's blocks @RH3
476 ADD HLST_NUM_BLOCKS,AX ;Add bank 1 to the total @RH3
477
478 SHR H_CARD_INFO_VAL,1 ;Shift bank 4-2 descriptors to @RH3
479 SHR H_CARD_INFO_VAL,1 ; bits 0-5 @RH3
480
481 MOV CX,NUM_CINFO_BANKS ; Loop for banks accounted for by @RH3
482 ; the XMO card info register @RH3
483HLST_MEM_LOOP:
484 MOV AL,H_CARD_INFO_VAL ;Get 2 bit bank descriptor & flip @RH3
485 XOR AL,LO2BIT_FLIP ; the 2 bits. Bits now indicate @RH3
486 ; the # of 1/2 meg in the bank @RH3
487 AND AL,HI6BIT_MASK ;Ignore other banks @RH3
488 CMP AL,LO2BIT_FLIP ;Are both bits on (i.e. 1M sips)? @RH3
489 JNE H_B42_HMEG_OK ;No # of 1/2 M for bank OK (0,1,2)@RH3
490 INC AL ;Yes # of 1/2 M should be 4 not 3 @RH3
491H_B42_HMEG_OK:
492 MUL H_BLKS_PER_HALFM ;Multiply by # of 4k blocks per @RH3
493 ; half meg to get bank's blocks @RH3
494 ADD HLST_NUM_BLOCKS,AX ;Add XMO banks 4-2 to total @RH3
495 SHR H_CARD_INFO_VAL,1 ;Get next bank @RH3
496 SHR H_CARD_INFO_VAL,1 ; @RH3
497 LOOP HLST_MEM_LOOP ; @RH3
498
499 POP AX ; @RH3
500 POP CX ; @RH3
501 POP DX ; @RH3
502
503 RET
504HLST_MEM_ADD ENDP
505
506;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
507;³ XMAA_MEM_ADD subprocedure ³
508;³ Calculates the amount of memory on the XMAA card ³
509;³ on entry: (CL) = card slot # ³
510;³ card is in setup mode ³
511;³ ³
512;³ The following describes how to read memory size, where the 2 bit ³
513;³ pattern indicates SIP size. There are 2 SIPs per bank. ³
514;³ ³
515;³ Reg: Control Reg Config, Channel Check reg ³
516;³ Port: 102h 105h ³
517;³ SIPS: bank 4 bank 3 bank 2 bank 1 ³
518;³ Bit: 7 6 5 4 3 2 1 0 ³
519;³ ------------------------------------------------- ³
520;³ 1 1 1 1 1 1 1 1 No memory or error ³
521;³ 1 0 1 0 1 0 1 0 256K ³
522;³ 0 1 0 1 0 1 0 1 512K ³
523;³ 0 0 0 0 0 0 0 0 1M ³
524;³ ³
525;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
526XMAA_MEM_ADD PROC
527 PUSH DX ; @RH2
528 PUSH CX ; @RH2
529 PUSH AX ; @RH2
530
531 ;Insure XMA/A init ROM is disabled @RH2
532 ;When the high byte of the TT data @RH2
533 MOV DX,X_CTRL_REG
534 IN AL,DX ; is read or written using port @RH2
535 MOV X_CTRL_REG_VAL,AL ; SAVE FOR MEM COUNT
536 AND AL,CR_ROMSLEEP_DIS ; 104h (real mode), the upper @RH2
537 OUT DX,AL ; nibble has info for setting the @RH2
538 ; initialization ROM addresses. To @RH2
539 ; insure this causes no problems, @RH2
540 ; disable XMA/A ROM by clearing @RH2
541 ; ROM sleep bit in the control reg @RH2
542
543 MOV XMAA_NUM_BLOCKS,0 ; @RH2
544
545 MOV AL,X_CTRL_REG_VAL ;Get bits 6&7 of control register @RH2
546 MOV CL,6 ; to get memory configuration of @RH2
547 SHR AL,CL ; bank 4 @RH2
548 XOR AL,LO2BIT_FLIP ;Flip these 2 to get # of 1/2M @RH2
549 ; in bank 4 of XMA/A card @RH2
550 AND AL,HI6BIT_MASK ;Clear other bits @RH2
551 CMP AL,LO2BIT_FLIP ;Are both bits on (i.e. 1M sips)? @RH2
552 JNE CTRL_HMEG_OK ;No # of 1/2 M for bank OK (0,1,2)@RH2
553 INC AL ;Yes # of 1/2 M should be 4 not 3 @RH2
554CTRL_HMEG_OK:
555 MUL X_BLKS_PER_HALFM ;Multiply by # of 4k blocks per @RH2
556 ; half meg to get bank's blocks @RH2
557 ADD XMAA_NUM_BLOCKS,AX
558
559
560 MOV DX,X_CONF_REG ;Read the config, channel check @RH2
561 IN AL,DX ; register to get mem size of @RH2
562 MOV X_CONF_REG_VAL,AL ; banks 1-3 @RH2
563
564 MOV CX,NUM_CONFR_BANKS ; Loop for banks accounted for by @RH2
565 ; the config register @RH2
566XMAA_MEM_LOOP:
567 MOV AL,X_CONF_REG_VAL ;Get 2 bit bank descriptor & flip @RH2
568 XOR AL,LO2BIT_FLIP ; the 2 bits. Bits now indicate @RH2
569 ; the # of 1/2 meg in the bank @RH2
570 AND AL,HI6BIT_MASK ;Ignore other banks @RH2
571 CMP AL,LO2BIT_FLIP ;Are both bits on (i.e. 1M sips)? @RH2
572 JNE CONF_HMEG_OK ;No # of 1/2 M for bank OK (0,1,2)@RH2
573 INC AL ;Yes # of 1/2 M should be 4 not 3 @RH2
574CONF_HMEG_OK:
575 MUL X_BLKS_PER_HALFM ;Multiply by # of 4k blocks per @RH2
576 ; half meg to get bank's blocks @RH2
577 ADD XMAA_NUM_BLOCKS,AX ; @RH2
578 SHR X_CONF_REG_VAL,1 ;Get next bank @RH2
579 SHR X_CONF_REG_VAL,1 ; @RH2
580 LOOP XMAA_MEM_LOOP ; @RH2
581
582 POP AX ; @RH2
583 POP CX ; @RH2
584 POP DX ; @RH2
585
586 RET
587XMAA_MEM_ADD ENDP
588
589;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
590;³ H_READ_TT subprocedure ³
591;³ Reads the contents of a translate table entry on a XMO card ³
592;³ on entry: (AX) = Translate table pointer ³
593;³ on exit: (BL) = Data (byte) at that entry ³
594;³ ³
595;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
596H_READ_TT PROC
597 PUSH AX ;Save the TT pointer @RH4
598 MOV DX,H_TTPTR_LO ;Set the low and high bytes of @RH4
599 OUT DX,AL ; the XMO translate table @RH4
600 XCHG AL,AH ; pointer, then read the value @RH4
601 MOV DX,H_TTPTR_HI ; of the data for that entry @RH4
602 OUT DX,AL ; @RH4
603 MOV DX,H_TTDATA ; @RH4
604 IN AL,DX ;Read the data into AL @RH4
605 MOV BL,AL ; and store it in BL @RH4
606 POP AX ;Restore TT pointer @RH4
607 RET ; @RH4
608H_READ_TT ENDP
609
610;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
611;³ X_READ_TT subprocedure ³
612;³ Reads the contents of a translate table entry on an XMA/A card ³
613;³ on entry: (AX) = Translate table pointer ³
614;³ on exit: (BX) = Data (12 bits) at that entry ³
615;³ ³
616;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
617X_READ_TT PROC
618 PUSH AX ;Save the TT pointer @RH4
619 MOV DX,RM_TTPTR_LO ;Set the low and high bytes of @RH4
620 OUT DX,AL ; the XMA/A translate table @RH4
621 XCHG AL,AH ; pointer, then read the value @RH4
622 MOV DX,RM_TTPTR_HI ; of the data for that entry @RH4
623 OUT DX,AL ; @RH4
624
625 MOV DX,RM_TTDATA_HI ;Read 12 bit TT data high byte @RH4
626 IN AL,DX ; first, then read low byte. @RH4
627 XCHG AL,AH ; @RH4
628 MOV DX,RM_TTDATA_LO ; @RH4
629 IN AL,DX ; @RH4
630 MOV BX,AX ;Store result in BX @RH4
631 AND BX,XMA_TT_MASK ;Turn off useless upper 4 bits @RH4
632 POP AX ;Restore TT pointer @RH4
633 RET ; @RH4
634X_READ_TT ENDP
635
636;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
637;³ H_INH_FOR_EMS subprocedure ³
638;³ Inhibits a single translate table entry of extended memory ³
639;³ on a XMO card. This entry (16K) is for use by EMS. ³
640;³ on entry: (AX) = XMO Translate table pointer (# of K / 16) ³
641;³ ³
642;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
643H_INH_FOR_EMS PROC
644 PUSH AX ;Save the TT pointer @RH4
645 MOV DX,H_TTPTR_LO ;Set the low and high bytes of @RH4
646 OUT DX,AL ; the XMO translate table @RH4
647 XCHG AL,AH ; pointer, @RH4
648 MOV DX,H_TTPTR_HI ; @RH4
649 OUT DX,AL ; @RH4
650
651 MOV AL,H_TT_INHIBIT ;AL = XMO TT inhibit data @RH4
652 MOV DX,H_TTDATA ;Inhibit this TT entry so that @RH4
653 OUT DX,AL ; it is no longer extended memory @RH4
654 POP AX ;Restore TT pointer @RH4
655 RET ; @RH4
656H_INH_FOR_EMS ENDP
657
658;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
659;³ X_INH_FOR_EMS subprocedure ³
660;³ Inhibits a single translate table entry of extended memory ³
661;³ on a XMA/A card. This entry (4K) is for use by EMS. ³
662;³ on entry: (AX) = XMA/A Translate table pointer (# of K / 4) ³
663;³ ³
664;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
665X_INH_FOR_EMS PROC
666 PUSH AX ;Save the TT pointer @RH4
667 MOV DX,RM_TTPTR_LO ;Set the low and high bytes of @RH4
668 OUT DX,AL ; the XMA/A translate table @RH4
669 XCHG AL,AH ; pointer, then read the value @RH4
670 MOV DX,RM_TTPTR_HI ; of the data for that entry @RH4
671 OUT DX,AL ; @RH4
672
673 MOV AX,XMA_TT_INHIBIT ;AX = XMA 12 bit TT inhibit data @RH4
674 MOV DX,RM_TTDATA_LO ;Write 12 bit TT data low byte @RH4
675 OUT DX,AL ; first, then write high byte. @RH4
676 XCHG AL,AH ; @RH4
677 MOV DX,RM_TTDATA_HI ; @RH4
678 OUT DX,AL ; @RH4
679 POP AX ;Restore TT pointer @RH4
680 RET ; @RH4
681X_INH_FOR_EMS ENDP
682
683;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
684;³ ADJUST_CMOS subprocedure ³
685;³ Reset the CMOS value for amount of extended memory. The ³
686;³ memory off the 'top' (upper addresses) is used by EMS. ³
687;³ on entry: ³
688;³ CARD_EXT_S16K = First 16K translate table pointer past the ³
689;³ top of the last card. Example - One 2M card ³
690;³ that started at 1M+384K, AX = 58h + 80H = D8h ³
691;³ ³
692;³ ³
693;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
694ADJUST_CMOS PROC
695CMOS_LO EQU 70h ;Port addrs of CMOS controller
696CMOS_HI EQU 71h
697
698 MOV BX,CARD_EXT_S16K ;Convert to 1st 16K TT ptr past @RH4
699 SUB BX,ems_pgs_parm ; entries reserved for ext mem @RH4
700 SUB BX,1024/16 ;Convert to # of 16K above 1M
701 MOV CL,4 ;Multiply by 16 to get # of K
702 SHL BX,CL ; above 1 Megabyte
703
704 MOV AX,8800h ;Get BIOS' current value for #
705 INT 15h ; of K extended (above 1M)
706
707 CMP AX,BX ;If already set below what we think
708 JBE CMOS_RET ; think then don't adjust it
709
710 PUSHF ;Else adjust CMOS...save state of
711 CLI ; interrupts and disable
712 MOV AL,0B5h ;Select NMI off byte 35
713 OUT CMOS_LO,AL ;Write to CMOS controller
714 JMP $+2 ; delay
715 MOV AL,BL ;Write low data byte to CMOS
716 OUT CMOS_HI,AL ;
717 JMP $+2 ;
718
719 MOV AL,0B6h ;Select NMI off byte 36
720 OUT CMOS_LO,AL ;Write to CMOS controller
721 JMP $+2 ; delay
722 MOV AL,BH ;Write high data byte to CMOS
723 OUT CMOS_HI,AL ;
724 JMP $+2 ;
725
726 MOV AL,0Fh ;Select NMI on byte 0f
727 OUT CMOS_LO,AL ;Write to CMOS controller
728 JMP $+2 ; delay
729 IN AL,CMOS_HI ;Reset CMOS like BIOS does
730 POPF ;Restore interrupt state
731CMOS_RET:
732 RET ; @RH4
733ADJUST_CMOS ENDP
734
735 \ No newline at end of file
diff --git a/v4.0/src/DEV/XMA2EMS/ROMSCAN.INC b/v4.0/src/DEV/XMA2EMS/ROMSCAN.INC
new file mode 100644
index 0000000..8eeb1b8
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/ROMSCAN.INC
@@ -0,0 +1,420 @@
1
2 page
3;-------------------------------------------------------------------
4;
5; This file contains the code to do a pseudo-rom scan looking
6; for possible EMS holes
7;
8;-------------------------------------------------------------------
9
10
11
12romscan proc near
13
14 push ax
15 push dx
16 push cx
17 push di
18
19 push cs ; make es and ds point to segment where messages are
20 pop es
21
22 push cs
23 pop ds
24
25; must do rom scan with interrupts disabled
26
27 cli
28
29;------------------------
30
31 cmp map_count,0 ; no segments specified, do rom scan
32 je no_pages_spec
33
34 mov cx,map_count ; number of segments to check
35 xor di,di ; use di as pointer into table
36
37check_segs:
38 mov ax,map_table.phys_page_segment[di]
39
40 call CHK_FREE_SEGMENT ; check a 16K block
41 jnc segment_ok
42
43; display the error
44
45 mov segment_error,1 ; set segment error flag
46
47
48; display conflict message
49
50 push ax ; save some regs
51 push dx
52 push di
53
54 MOV DI,OFFSET confl_address ; ascii string page frame
55 CALL CNVHEXAT
56
57 MOV DX,OFFSET conflict_msg ; start of message
58 MOV AH,9 ; dos prt string
59 INT 21H ;
60
61 pop di ; restore some regs
62 pop dx
63 pop ax
64
65segment_ok:
66 add di,type mappable_phys_page_struct
67 loop check_segs
68
69;------------------------
70; if there were no conflicts, then exit with no error
71
72 cmp segment_error,0
73 je rom_scan_no_error ; exit with no error (carry = 0)
74
75;------------------------
76
77 MOV DX,OFFSET CRLF ; skip a blank line
78 MOV AH,9 ; dos prt string
79 INT 21H ;
80
81 jmp rom_scan_code
82
83; display no pages message
84
85no_pages_spec:
86 MOV DX,OFFSET NO_PAGES_MSG ; skip a blank line
87 MOV AH,9 ; dos prt string
88 INT 21H
89
90 MOV DX,OFFSET CRLF ; skip a blank line
91 MOV AH,9 ; dos prt string
92 INT 21H ;
93
94;-------------------------------------------------------------------
95;
96; This routine scans the address range from c000 - FFFF looking
97; for 16 K gaps.
98;
99;-------------------------------------------------------------------
100
101rom_scan_code:
102
103 mov ax,0c000h ; start at c000
104 xor bx,bx ; bx holds count of contiguous pages
105 mov cx,15 ; loop counter
106 mov dx,ax ; dx holds start of frame
107
108fam2_loop:
109 call CHK_FREE_SEGMENT ; check a 16K block
110 jc bad_seg
111
112; good 16 segment
113
114 call FoundBlock
115
116 add bx,1 ; add another page to frame counter
117 cmp bx,4 ; 4 means frame is found
118 jne no_frame_yet
119
120; a frame has been found
121
122 mov bx,100 ; make sure we don't look for more frames
123
124no_frame_yet:
125 add ax,0400h ; point to next segment
126 jmp continue_loop
127
128; bad 16 segment
129
130bad_seg:
131 add ax,0400h ; point to next segment
132 cmp bx,100
133 jae continue_loop ; don't reset frame info if one has been found
134
135 xor bx,bx ; clear contiguous page counter
136 mov dx,ax ; make frame pointer point to next page
137
138continue_loop:
139
140 loop fam2_loop
141 jmp rom_scan_exit
142
143
144rom_scan_no_error:
145 clc
146 jmp clean_exit
147
148
149;-------------------------------------------------------------------
150
151rom_scan_exit:
152
153; display frame if found
154
155 cmp bx,100 ; >= 100 means frame was found
156 jb no_frame_exit
157
158 mov ax,dx ; get frame address in ax
159 call FoundFrame ; display frame address
160
161
162no_frame_exit:
163 STC ; carry = 1 means error
164
165clean_exit:
166 sti
167
168
169 pop di
170 pop dx
171 pop cx
172 pop ax
173
174 ret
175
176romscan endp
177
178
179
180;-------------------------------------------------------------------
181;
182; FoundBlock assumes AX = segment address of good 16 K block
183;
184;-------------------------------------------------------------------
185
186FoundBlock proc near
187
188 push ax
189 push dx
190 push es
191 push di
192
193 push cs
194 pop es
195
196 push cs
197 pop ds
198
199 MOV DI,OFFSET hole_address ; ascii string page frame
200 CALL CNVHEXAT
201
202 MOV DX,OFFSET hole_msg ; start of message
203 MOV AH,9 ; dos prt string
204 INT 21H ;
205
206
207 pop di
208 pop es
209 pop dx
210 pop ax
211
212 ret
213
214FoundBlock endp
215
216;-------------------------------------------------------------------
217;
218; FoundFrame assumes AX = segment address of good 64 K block
219;
220;-------------------------------------------------------------------
221
222FoundFrame proc near
223
224 push ax
225 push dx
226 push es
227 push di
228
229 push cs
230 pop es
231
232 push cs
233 pop ds
234
235 MOV DI,OFFSET frame_address ; ascii string page frame
236 CALL CNVHEXAT
237
238 MOV DX,OFFSET frame_msg ; start of message
239 MOV AH,9 ; dos prt string
240 INT 21H ;
241
242
243 pop di
244 pop es
245 pop dx
246 pop ax
247
248 ret
249
250FoundFrame endp
251
252
253
254
255
256
257;-------------------------------------------------------------------
258;-------------------------------------------------------------------
259;-------------------------------------------------------------------
260;-------------------------------------------------------------------
261;-------------------------------------------------------------------
262;-------------------------------------------------------------------
263;-------------------------------------------------------------------
264;-------------------------------------------------------------------
265;-------------------------------------------------------------------
266;-------------------------------------------------------------------
267;-------------------------------------------------------------------
268;-------------------------------------------------------------------
269;------------------------------------------------------------------------
270; 03/04/88 jwg:
271; PROCEDURE NAME: CHK_FREE_SEGMENT :
272; :
273; THIS PROCEDURE CHECKS EACH OF THE 2K BOUNDARIES IN THE 16K SEGMENT :
274; TO DETERMINE IF A ROM SEGMENT IS EMPTY. IT VERIFIES THAT NO ROM :
275; FROM A PRECEEDING ADDRESS EXTENDS INTO THIS 16K SEGMENT. ALSO THE :
276; 16K BLOCK IS CHECKED FOR THE PRESENCE OF ANY RESPONDING CARD. :
277; :
278; ENTRY: AX - CONTAINS 16K SEGMENT ADDRESS :
279; EXIT: CARRY FLAG = 0 - SEGMENT FREE :
280; CARRY FLAG = 1 - SEGMENT IN USE :
281; :
282;------------------------------------------------------------------------
283
284ROM_SCAN EQU 0AA55H
285CARD_SEL_PORT EQU 091h ; CARD SELECTED LATCH PORT
286
287
288CHK_FREE_SEGMENT PROC NEAR
289
290 PUSH AX ; Save work registers
291 PUSH BX
292 PUSH CX
293 PUSH DX
294 PUSH DI
295 PUSH ES ; Save data segment register
296 MOV BX,AX ; Save segment start address
297 MOV CX,AX ; Save in work register
298 ADD CX,0400h ; Determine End segment address of FIFE
299; MOV DX,0C000h-00100h ; Get address of start of ROM area
300 mov dx,ax ; gga
301 sub dx,0100h ; gga
302CHK_FREE_NEXT:
303 ADD DX,00100h ; Add offset to get next 2K segment
304 CMP DX,CX ; Check for past end of 16K ROM area
305 JAE CHK_FREE_OK ; IF (NC) then Exit, segment was free
306
307 ; CHECK FOR ROM BLOCK SIGNATURE
308 MOV ES,DX ; Change to new ROM segment
309 CMP ES:WORD PTR [0],ROM_SCAN; Check if a ROM module is present
310 JE CHK_FREE_SIZE ; Go check length if ROM SCAN signature
311
312 CMP BX,DX ; Check if into the target segment yet
313 JA CHK_FREE_NEXT ; Loop and check next 2K block in not
314
315 ; CHECK FOR CARD RESPONDING IN 2K
316 NOP ; Following sequence can not be traced..
317;;;;; CALL CARD_SEL_NOW ; Reset CARD SELECTED FEED BACK latch .
318 XOR DI,DI ; Clear source pointer .
319 MOV AX,0FFFFh ; Get expected floating bus pattern .
320 PUSH CX ; Save CX .
321 MOV CX,00400h ; Get count of 1 K words (2K bytes) .
322 REPE SCASW ; Check for all bits on in block ES:DI .
323 POP CX ; Recover end segment address .
324 JNE CHK_FREE_ERROR ; Exit if anything there .
325
326;;;;;; cmp rom_scan_type,family1 ; gga only do the card select check on PS2's
327;;;;;; je skip_ps2_check
328
329;;;;;; CALL CARD_SEL_NOW ; Check for a CARD SELECTED by scan .
330;;;;;; JC CHK_FREE_ERROR ; Exit (CY) if a card responded ........
331
332;;;;;;skip_ps2_check:
333 JMP CHK_FREE_NEXT ; ELSE check next 2K address
334
335CHK_FREE_SIZE: ; CHECK LENGTH INTO 16K SEGMENT
336 push cx ; gga
337 MOV AL,ES:BYTE PTR [2] ; Get ROM module length in 512 bytes
338 MOV AH,0 ; Clear high byte
339 mov cl,5 ; gga
340 SHL AX,cl ; gga convert to segment length (16 byte)
341 pop cx ; gga
342 ADD AX,DX ; Determine ending segment size
343 CMP BX,AX ; Does ROM extend into this 16K segment
344 JNB CHK_FREE_NEXT ; IF not then continue search
345
346CHK_FREE_ERROR:
347 STC ; ELSE (CY), Exit with segment not free
348CHK_FREE_OK:
349 POP ES ; restore segment register
350 POP DI
351 POP DX
352 POP CX ; restore all registers
353 POP BX
354 POP AX
355 RET ; EXIT (NC) if segment free to test
356
357CHK_FREE_SEGMENT ENDP
358
359
360;------------------------------------------------------------------------
361; 03/04/88 jwg:
362; PROCEDURE NAME: CARD_SEL_FBK :
363; :
364; THIS PROCEDURE CHECKS THE CARD SELECTED FEEDBACK LINE AND LATCH :
365; TO VERIFY THAT THIS LINE WAS ACTIVATED. METHOD IS TO CLEAR THE :
366; LATCH AND READ A LOCATION USING THE PASSED SEGMENT ADDRESS. IF :
367; ANY CARD RESPONDS THE LATCH WILL BE SET ON. :
368; :
369; NOTE: These routines can not be traced with a debug-er :
370; as VIDEO updates also set the card selected latch. :
371; :
372; ENTRY: AX - ADDRESS OF SELECTED SEGMENT :
373; :
374; EXIT: CARRY FLAG = 0 - CARD SELECTED LATCH WAS NOT SET (OFF) :
375; CARRY FLAG = 1 - CARD SELECTED LATCH WAS SET BY TEST :
376; :
377;------------------------------------------------------------------------
378
379;;;;;CARD_SEL_FBK PROC NEAR ; TEST CARD SELECTED FEED BACK
380
381;;;;; CLI ; Block interrupts during operation
382;;;;; CALL CARD_SEL_NOW ; Read current port value to clear
383;;;;; PUSH DS ; Save segment register
384;;;;; MOV DS,AX ; Set segment
385;;;;; CMP DS:BYTE PTR [0],AL ; Read first byte with dummy compare
386;;;;; POP DS ; Restore segment selector
387;;;;; CALL CARD_SEL_NOW ; Read current port value and clear
388;;;;; STI ; Enable interrupts
389;;;;; RET ; RETurn (CY)= 1 if latch set by read
390
391;;;;;CARD_SEL_FBK ENDP
392
393;------------------------------------------------------------------------
394; 03/04/88 jwg:
395; PROCEDURE NAME: CARD_SEL_NOW (CURRENT VALUE) :
396; :
397; THIS PROCEDURE READS AND RESETS THE CURRENT CARD SELECTED FEEDBACK :
398; LATCH AND RETURNS THE STATUS. :
399; :
400; NOTE: This routine can not be traced with a debug-er :
401; as VIDEO updates also set the card selected latch. :
402; :
403; ENTRY: NONE :
404; :
405; EXIT: CARRY FLAG = 0 - CARD SELECTED LATCH WAS NOT SET (OFF) :
406; CARRY FLAG = 1 - CARD SELECTED LATCH WAS SET ON WHEN READ :
407; :
408;------------------------------------------------------------------------
409
410;;;;;CARD_SEL_NOW PROC NEAR ; READ CARD SELECTED FEED BACK
411
412;;;;; PUSH AX ; Save segment address
413;;;;; IN AL,CARD_SEL_PORT ; Read current port value and clear
414;;;;; RCR AL,1 ; Move bit 0 into CY flag
415;;;;; POP AX ; Recover segment address
416;;;;; RET ; RETurn (CY)= 0 if latch set
417
418;;;;;CARD_SEL_NOW ENDP
419
420 \ No newline at end of file
diff --git a/v4.0/src/DEV/XMA2EMS/XMA1DIAG.INC b/v4.0/src/DEV/XMA2EMS/XMA1DIAG.INC
new file mode 100644
index 0000000..bbf3875
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/XMA1DIAG.INC
@@ -0,0 +1,1870 @@
1;-----------------------------------------------------------------------;
2; This section contains the prescence test and diagnostic ;
3; routines for the XMA 1 card. ;
4; ;
5;-----------------------------------------------------------------------;
6
7;-----------------------------------------------------------------------;
8; DATA THAT IS UNIQUE TO THE DIAGNOSTICS PORTION OF ;
9; THE DEVICE DRIVER. THIS AREA WILL NOT REMAIN PRESENT ;
10; AFTER INITIALIZATION. ;
11;-----------------------------------------------------------------------;
12
13MEM_INST DB '1'
14TEST_ID DB ? ;SAVE AREA FOR CURRENT TEST ID
15CTRLPARM DW ? ;SAVE AREA FOR CONTROL PARM
16PAGE_UNDER_TEST DW 0 ;SAVE AREA FOR PAGE UNDER TEST
17CUR_SAVE DW ? ;SAVE AREA FOR NEXT AVAILABLE LINE
18 ;FOR MESSAGES
19ACTIVE_PAGE DB ? ;ACTIVE DISPLAY PAGE
20TESTABLE_SEGMENTS DW ?
21
22
23PAGE
24;-----------------------------------------------------------------------;
25; EQUATES THAT ARE UNIQUE TO THE DIAGNOSTICS PORTION OF ;
26; THE DEVICE DRIVER. ;
27;-----------------------------------------------------------------------;
28BLK_ON EQU 11110111B ;MASK FOR ENABLING A BLOCK
29BLK_OFF EQU 00001000B ;MASK FOR INHIBITING A BLOCK
30VIRT_MODE EQU 00000010B ;MASK FOR VIRTUAL MODE
31REAL_MODE EQU 11111101B ;MASK FOR REAL MODE
32MAX_TASK_ID EQU 15 ;MAXIMIM TASK ID
33ENABLE EQU 01H ;INDICATES THAT BLOCK SHOULD BE ENABLED
34TABLEN EQU 1000H ;NUMBER OF ENTRIES IN XLAT TABLE
35DMAREQ1 EQU 0009H ;I/O ADDRESS OF DMA CTRL 1 REQ REG
36DMAREQ2 EQU 00D2H ;I/O ADDRESS OF DMA CTRL 2 REQ REG
37DMAMODE1 EQU 000BH ;I/O ADDRESS OF DMA CTRL 1 MODE REG
38DMAMODE2 EQU 00D6H ;I/O ADDRESS OF DMA CTRL 2 MODE REG
39AT_NMI_REG EQU 70H ;AT NMI REG
40AT_NMI_OFF EQU 80H ;AT NMI OFF MASK
41AT_NMI_ON EQU 00H ;AT NMI ON MASK
42AT_CHCHK_EN_REG EQU 61H ;AT CH CHK ENABLE REG
43AT_CHCHK_REG EQU 61H ;AT CH CHK REG
44AT_CHCHK_EN EQU 0F7H ;AT CH CHK ENABLE MASK
45AT_CHCHK_DIS EQU 08H ;AT CH CHK DISABLE MASK
46AT_CHCHK EQU 40H ;AT CH CHK MASK
47XT_NMI_REG EQU 0A0H ;XT NMI REG
48XT_NMI_OFF EQU 00H ;XT NMI OFF MASK
49XT_NMI_ON EQU 80H ;XT NMI ON MASK
50XT_CHCHK_EN_REG EQU 61H ;XT CH CHK ENABLE REG
51XT_CHCHK_REG EQU 62H ;XT CH CHK REG
52XT_CHCHK_EN EQU 0DFH ;XT CH CHK ENABLE MASK
53XT_CHCHK_DIS EQU 20H ;XT CH CHK DISABLE MASK
54XT_CHCHK EQU 40H ;XT CH CHK MASK
55CR EQU 0DH ;CARRIAGE RETURN
56LF EQU 0AH ;LINE FEED
57PRES_TEST EQU 01 ;PRESENCE TEST ID
58REG_TEST EQU 02 ;REG TEST ID
59AUTO_INC EQU 03 ;AUTO INC TEST ID
60XLAT_TABLE_TEST EQU 04 ;TT TEST ID
61LOMEM_TEST EQU 05 ;ABOVE 640K TEST ID
62DMA_CAPTURE EQU 06 ;DMA CAPTURE TEST ID
63PAGE_TEST EQU 07 ;PAGE TEST ID
64MEM_TEST EQU 10 ;MEMORY TEST ID
65
66;-------------------------------------------------------------------------
67;
68; PRESENCE TEST
69;
70; DESCRIPTION : This routine will determine if the XMA is in the system.
71; It will also determine the amount of memory installed
72; on the card in 1Meg increments (up to 4Meg).
73;
74; FUNCTION/ : See description
75; PURPOSE
76;
77; ENTRY POINT : PRESTST
78;
79; ENTRY : The assumption is that at least 1MB of memory is installed.
80; CONDITIONS If the 2nd, 3rd or 4th MB of memory is installed then the
81; TOTAL_SYS_PAGES, TOTAL_EMS_PAGES, FREE_PAGES and
82; MEM_INST words are Revised accordingly.
83;
84;
85;
86; EXIT : (zero flag) = 0 indicates that the XMA is not installed.
87; if (zero flag) <> 0 then
88; TOTAL_SYS_PAGES, TOTAL_EMS_PAGES, FREE_PAGES and
89; MEM_INST words are Revised accordingly.
90;
91; AX,BX,CX,DX ARE DESTROYED
92;-------------------------------------------------------------------------
93;
94PRESTST PROC
95;
96 MOV AL,PRES_TEST
97 MOV CS:TEST_ID,AL
98
99;SAVE CONTENTS OF MODE REG
100 MOV DX,MODE_REG
101 IN AL,DX
102 PUSH AX
103
104; TRANSLATE TABLE ADDRESS AND DATA REGISTERS
105;
106 MOV AX,0AA55H ;DATA PATTERN (IN REAL MODE)
107 ;BE CERTAIN MODE REG GETS
108 ;REAL MODE
109 MOV DX,MODE_REG ;I/O TO MODE REG
110 OUT DX,AL ;WRITE PATTERN
111 MOV DX,TTPOINTER + 1 ;I/O TO TT POINTER (ODD ADDR)
112 XCHG AL,AH ;CHRG BUS WITH INVERSE PATTERN
113 OUT DX,AL ;WRITE IT
114 MOV DX,MODE_REG
115 IN AL,DX ;READ BACK MODE REG
116 XOR AL,AH
117 AND AL,0FH ;MASK OFF UNUSED BITS
118 ;ZERO FLAG = 0 IF ERROR
119END_PRES:
120 POP AX
121 PUSHF ;SAVE FLAGS
122 MOV DX,MODE_REG
123 OUT DX,AL ;RESTORE MODE REG TO INITIAL STATE
124 POPF ;RESTORE FLAGS
125 RET ;BACK TO CALLER
126;
127PRESTST ENDP
128
129PAGE
130
131;------------------------------------------------------------------------;
132; Diagnostics...on exit if ZF=0 then error ;
133;------------------------------------------------------------------------;
134XMA1DIAGS PROC
135
136 MOV CS:TEST_ID,00H ;CLEAR TEST ID BYTE
137 MOV CS:CTRLPARM,0100H ;SAVE CONTROL PARM
138 CALL CUR_POS ;GET CURSOR READY FOR MESSAGES
139 CALL REGTST ;TEST XMA REGISTERS
140 JNE FOUND_ERROR ;JUMP IF ERROR
141 CALL INCTST
142 JNE FOUND_ERROR
143 CALL XLATST
144 JNE FOUND_ERROR
145 CALL LOMEMTST ;TEST FOR BELOW 640K
146 JNE FOUND_ERROR ;JUMP IF ERROR
147 CALL MEMARRAY ;TEST MEMORY ABOVE 640K
148 JNE FOUND_ERROR ;JUMP IF ERROR
149 CALL PAGETST
150 JNE FOUND_ERROR
151 CALL CAPTST ;TEST DMA CAPTURE
152 JNE FOUND_ERROR ;JUMP IF ERROR
153FOUND_ERROR:
154 RET
155XMA1DIAGS ENDP
156
157
158
159PAGE
160;-------------------------------------------------------------------------
161;-------------------------------------------------------------------------
162;
163; SAVES CURSOR POSITION
164;
165; DESCRIPTION : This routine simply saves the cursor location
166; in CS:CUR_SAVE. This cursor position
167; should be used by the KB_OK routine to insure proper
168; format of the screen.
169;
170; FUNCTION/ : See description
171; PURPOSE
172;
173;
174; ENTRY POINT : CUR_POS
175;
176; ENTRY :
177; CONDITIONS
178;
179;
180; EXIT : new cursor position is saved in CS:CUR_SAVE
181;
182; All registers are preserved
183;
184;-------------------------------------------------------------------------
185;
186CUR_POS PROC
187;
188 PUSH AX
189 PUSH BX
190 PUSH CX
191 PUSH DX
192 PUSH SI
193 PUSH DI
194 PUSH DS ;SAVE REGISTERS
195;
196 PUSH CS
197 POP DS ;GET DS TO THIS CODE SEGMENT
198 ;MOVE CURSOR TO NEXT AVAILABLE LINE
199;IF DOS
200; MOV AH,9 ;DOS PRINT STRING
201; MOV DX,OFFSET NEXT_LINE + 1 ;OFFSET OF NEXT LINE MSG
202; INT 21H ;DISPLAY MESSAGE
203;ELSE
204; MOV BX,OFFSET NEXT_LINE ;GET OFFSET OF NEXT LINE MSG
205; MOV AH,0 ;TELL DCP TO DISPLAY
206; INT 82H ;DISPLAY MESSAGE
207;ENDIF
208 ; rsh001 fix scroll problem
209 ; and remove IF DOS crap
210 ;READ CURRENT VIDEO PAGE ; rsh001
211 MOV AH,15 ;READ CURRENT Video Page
212 INT 10H ;VIDEO CALL
213 MOV ACTIVE_PAGE,BH ;SAVE ACTIVE PAGE
214
215 ;READ CURRENT CURSOR POSITION
216 MOV AH,3 ;READ CURRENT CURSOR POS
217 INT 10H ;VIDEO CALL
218 MOV CUR_SAVE,DX ;SAVE CURSOR POSITION
219
220 ;RESTORE ALL REGISTERS
221 POP DS
222 POP DI
223 POP SI
224 POP DX
225 POP CX
226 POP BX
227 POP AX ;RESTORE ALL REGISTERS
228
229 RET ;RETURN TO CALLER
230
231CUR_POS ENDP
232
233
234
235
236
237PAGE
238;-------------------------------------------------------------------------
239;-------------------------------------------------------------------------
240;
241; TEST FOR PRESENCE OF MORE THAN 1 MEGABYTE OF MEMORY
242;
243; DESCRIPTION : This routine will determine if the 2nd, 3rd or 4th MB is
244; installed. Since there are no switches or other indicators
245; to be tested, this test will make a "best guess" as to
246; the presence of this memory. This test will roll a 0
247; and a 1 through the 1st word of the next Meg and if
248; at least 1 bit is consistently good then it is assumed
249; that the optional memory is installed. If successful
250; then try next Meg.
251;
252; FUNCTION/ : See description
253; PURPOSE
254;
255; ENTRY POINT : TRY4MEG
256;
257; ENTRY : none
258; CONDITIONS
259;
260; EXIT :
261;
262; AX,BX,CX,DX ARE DESTROYED
263;-------------------------------------------------------------------------
264;
265TRY4MEG PROC
266
267;MEMORY TEST MUST RUN IN PAGE MODE
268;BEFORE CARD IS PUT INTO PAGE MODE...MUST SET UP XLAT TABLE TO PASSOVER
269;RESERVED MEMORY SPACES (IE.,BIOS, DISPLAY, DISTRIBUTED ROS, ETC)
270;
271 CALL VIRT2REAL
272
273 MOV DX,IDREG ;I/O TO ID REGISTER
274 MOV AL,0 ;ID = 0
275 OUT DX,AL ;SWITCH TO ID = 0
276;
277 ;DISABLE NMI AND ENABLE I/O CHANNEL CHECK
278 MOV AL,CS:MODEL_BYTE ;GET SAVED MODEL BYTE
279 CMP AL,PC1 ;IS IT A PC1?
280 JE TR2M1 ;IF NO THEN TRY FOR PC_XT
281 CMP AL,PC_XT ;IS IT AN XT?
282 JE TR2M1 ;IF NO THEN TRY FOR AQUARIUS
283 CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS?
284 JE TR2M1 ;IF NO THEN USE AT NMI REGS
285 ;USE PC-AT NMI REGISTER
286 MOV DX,AT_NMI_REG ;AT's NMI REGISTER
287 MOV AL,AT_NMI_OFF ;MASK OFF NMI
288 OUT DX,AL ;OUTPUT IT
289 MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG
290 IN AL,DX ;READ IT
291 OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
292 OUT DX,AL ;WRITE IT
293 AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
294 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
295 ;ENABLED
296 ;USE PC1, XT, AQUARIUS REGISTERS
297TR2M1:
298 MOV DX,XT_NMI_REG ;XT's NMI REGISTER
299 MOV AL,XT_NMI_OFF ;MASK OFF NMI
300 OUT DX,AL ;OUTPUT IT
301 MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG
302 IN AL,DX ;READ IT
303 OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
304 OUT DX,AL ;WRITE IT
305 AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
306 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
307 ;ENABLED
308;
309 ;MAP FIRST 64K OF 2ND MEG INTO PC SPACE BEGINNING AT 512K
310;***jnw MOV CX,3 ;LOOK FOR PRESENCE OF NEXT 3 MB IN 1MB STEPS
311 MOV CX,99*1024/16 ;***jnw ;LOOK FOR PRESENCE OF NEXT n MB IN 1MB STEPS
312 MOV AX,CS:PAGE_FRAME_STA ;SEGMENT AT PAGE FRAME
313;***jnw MOV DX,256 ;BEGINNING AT 2ND MEG OF XMA
314 MOV DX,256+3 ;***jnw ;AT end of 16k
315 MOV BH,0 ;ASSIGNED TO TASK ID 0
316 MOV BL,01H ;ENABLE THIS MEMORY
317TR2M1A:
318 PUSH AX
319 PUSH BX
320 PUSH CX
321 PUSH DX
322;***jnw MOV CX,16 ;16 * 4K = 64K BLOCK
323 MOV CX,1 ;***jnw ;1 * 4K = 4K BLOCK
324 CALL SETXLAT ;SET TRANSLATE TABLE
325;
326 MOV AX,CS:PAGE_FRAME_STA
327 MOV DS,AX ;SET SEGMENT AND
328 MOV SI,0 ;OFFSET TO TEST
329 MOV BX,0000000000000001B ;ROLL 1 THROUGH WORD
330 MOV DX,1111111111111110B ;ROLL 0 THROUGH WORD
331 MOV CX,16 ;16 BITS TO TEST
332TR2M2:
333 MOV [SI],BX ;WRITE ROLLING 1 PATTERN
334 LOCK MOV [SI+2],DX ;CHARGE BUS INVERSE PATTERN
335 LOCK MOV AX,[SI] ;READ BACK INITIAL PATTERN
336 AND AX,BX ;ISOLATE BIT UNDER TEST
337;***jnw JZ TR2M3 ;IF ZERO TRY ANOTHER BIT
338 JZ quit ;IF ZERO quit ***jnw
339 MOV [SI],DX ;WRITE ROLLING 0 PATTERN
340 LOCK MOV [SI+2],BX ;CHARGE BUS INVERSE PATTERN
341 LOCK MOV AX,[SI] ;READ BACK INITIAL PATTERN
342 AND AX,BX ;ISOLATE BIT UNDER TEST
343 AND AX,BX ;ISOLATE BIT UNDER TEST
344;***jnw JZ TR2M4 ;IF ZERO THEN FOUND GOOD BIT
345 Jnz quit ;IF nonzero then quit ***jnw
346TR2M3:
347 ROL BX,1 ;ROLL 1 TO NEXT POSITION
348 ROL DX,1 ;ROLL 0 TO NEXT POSITION
349 LOOP TR2M2 ;REPEAT FOR 16 BITS
350 jmp tr2m4 ;all 16 bits passed test ***jnw
351quit: ;***jnw
352;AT THIS POINT THERE ARE NO GOOD BITS SO END SEARCH FOR NEXT MB
353 POP DX ;RECOVER THESES REGISTERS
354 POP CX
355 POP BX
356 POP AX
357 JMP TR2M5 ;EXIT
358;AT THIS POINT WE KNOW THERE IS MEMORY IN THIS MEG THAT WAS JUST TESTED
359TR2M4:
360;***jnw ADD CS:MEM_INST,1 ;ADD 1 MB TO THIS FLAG
361;***jnw ADD CS:TOTAL_XMA_PAGES,1024/16 ;ADD 1 MB TO THIS FLAG
362;***jnw ADD CS:TOTAL_PAGES,1024/16 ;ADD 1 MB TO THIS FLAG
363;***jnw ADD CS:FREE_PAGES,1024/16 ;ADD 1 MB TO THIS FLAG
364 ADD CS:TOTAL_SYS_PAGES,1 ;Add 16k ***jnw
365 ADD CS:TOTAL_EMS_PAGES,1 ;Add 16k ***jnw
366 ADD CS:FREE_PAGES,1 ;Add 16k ***jnw
367 POP DX ;RECOVER THESE REGISTERS
368 POP CX
369 POP BX
370 POP AX
371;***jnw ADD DX,256 ;TRY NEXT MB
372 ADD DX,4 ;TRY NEXT 16k ***jnw
373 LOOP TR2M1A ;REPEAT LOOP
374TR2M5:
375;BEFORE NMI IS ENABLED, CLEAR PARITY CHECK LATCH ON XMA
376 MOV SI,0
377 MOV AX,[SI] ;READ 1ST WORD OF THIS SEG
378 MOV [SI],AX ;WRITE BACK SAME WORD
379 ;THE WRITE WILL CLEAR PCHK LTCH
380;PUT THE XMA CARD BACK INTO REAL MODE
381 MOV DX,MODE_REG ;READY FOR I/O TO MODE REG
382 IN AL,DX ;READ IT
383 AND AL,REAL_MODE ;TURN OFF VIRTUAL BIT
384 OUT DX,AL ;WRITE IT TO MODE REG
385;CLEAR I/O CHANNEL CHECK LATCHES AND ENABLE NMI
386 MOV AL,CS:MODEL_BYTE ;GET SAVED MODEL BYTE
387 CMP AL,PC1 ;IS IT A PC1?
388 JE TR2M6 ;USE XT REGISTERS
389 CMP AL,PC_XT ;IS IT AN XT?
390 JE TR2M6 ;USE XT REGISTERS
391 CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS?
392 JE TR2M6 ;USE XT REGISTERS
393;IF NONE OF THE ABOVE THEN...
394;USE AT NMI REGISTER
395 MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG
396 IN AL,DX ;READ IT
397 OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
398 OUT DX,AL ;WRITE IT
399 AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
400 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
401 ;ENABLED
402 MOV DX,AT_NMI_REG ;AT's NMI REGISTER
403 MOV AL,AT_NMI_ON ;MASK ON NMI
404 OUT DX,AL ;OUTPUT IT
405;USE XT/AQUARIUS NMI REGISTER
406TR2M6:
407 MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG
408 IN AL,DX ;READ IT
409 OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
410 OUT DX,AL ;WRITE IT
411 AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
412 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
413 ;ENABLED
414 MOV DX,XT_NMI_REG ;XT's NMI REGISTER
415 MOV AL,XT_NMI_ON ;MASK ON NMI
416 OUT DX,AL ;OUTPUT IT
417;
418 RET ;RETURN TO CALLER
419
420TRY4MEG ENDP
421
422
423PAGE
424;-------------------------------------------------------------------------
425;-------------------------------------------------------------------------
426;
427; REGISTER TESTS
428;
429; DESCRIPTION : This routine will test the following subset
430; of XMA registers:
431; 31A0...8 bits
432; 31A1...4 bits
433; 31A6...4 bits
434; 31A7...4 bits (BIT 1 IS HELD LOW TO DISABLE
435; THE VIRTUAL MODE)
436;
437; The test is performed by writing and reading
438; AA, 55, FF, 00 from each of the above locations.
439;
440; NOTE: Regs 31A6 and 31A7 should always return 0 in
441; the high nibble.
442;
443; The remainding registers will be tested in
444; subsequent routines.
445;
446;
447; FUNCTION/ : To ensure integrity of XMA registers that will be used
448; PURPOSE in subsequent routines.
449;
450; ENTRY POINT : REGTST
451;
452; ENTRY : none
453; CONDITIONS
454;
455; EXIT : XMA registers are set to zero
456;
457; (zero flag) = 0 indicates an error
458; (DX) failing register
459; (AL) expected data XOR'ed with actual data
460;
461;-------------------------------------------------------------------------
462;
463REGTST PROC
464;
465 MOV AL,REG_TEST
466 MOV CS:TEST_ID,AL
467
468;SAVE CONTENTS OF MODE REG
469 MOV DX,MODE_REG
470 IN AL,DX
471 PUSH AX
472
473; TRANSLATE TABLE ADDRESS AND DATA REGISTERS
474;
475 MOV BX,0AA55H ;SET UP INITIAL DATA PATTERN
476 MOV AX,BX
477 MOV CX,BX
478
479R1:
480 MOV DX,TTPOINTER ;FIRST REGISTER PAIR TO WRITE
481
482 OUT DX,AX ;WRITE PATTERN TO REGS
483 ADD DX,6 ;POINT TO NEXT REG PAIR
484 XCHG AL,AH ;SETUP INVERSE PATTERN
485 AND AH,11111101B ;MASK OFF BIT 1
486 OUT DX,AX ;BECAUSE AH -> 21B7
487R2:
488 SUB DX,6 ;POINT TO FIRST REGISTER PAIR
489 IN AX,DX ;READ REGISTER (21B1 -> AH)
490 XOR AX,BX ;DATA READ AS EXPECTED ?
491 AND AX,0FFFH ;MASK OFF UPPER NIBBLE OF 21B1
492 JNE R_ERROR ;MISMATCH - GO TO ERROR ROUTINE
493 XCHG BH,BL ;NEXT PATTERN TO TEST
494 AND BX,0F0FH ;REGS RETURN 0 IN HI NIBBLE
495 ADD DX,6 ;POINT TO NEXT REGISTER PAIR
496 IN AX,DX ;READ IT (21B7 -> AH)
497 XOR AX,BX ;DATA READ AS EXPECTED ?
498 AND AX,0DFFH ;MASK OFF BIT 1 IN REG 21B7
499 JNE R_ERROR ;MISMATCH - GO TO ERROR ROUTINE
500;
501 CMP CH,CL ;LAST PASS ?
502 JE R_EXIT ;YES - THEN EXIT REG TEST
503;
504 CMP CX,055AAH ;END OF AA55,55AA PATTERNS?
505 JNE R3 ;
506 MOV CX,000FFH ;SET UP NEXT VALUE TO WRITE
507 JMP R4
508R3:
509 CMP CX,00FFH ;END OF FF00,00FF PATTERNS?
510 JNE R4 ;
511 MOV CX,0 ;YES, THEN SET UP FOR LAST PASS
512R4:
513 XCHG CL,CH ;SET UP INVERSE PATTERN
514 MOV AX,CX ;SAVE IT
515 MOV BX,CX ;SAVE IT
516R5:
517 JMP R1 ;CONTINUE TILL ZERO PATTERN
518
519R_ERROR:
520R_EXIT:
521 POP AX
522 MOV DX,MODE_REG
523 OUT DX,AL ;restore mode reg
524 RET
525;
526REGTST ENDP
527
528
529
530
531PAGE
532;-------------------------------------------------------------------------
533;-------------------------------------------------------------------------
534;
535; MEMORY ARRAY TEST
536;
537; DESCRIPTION : This routine test all 1Meg (or 2Meg) of XMA memory
538; through a 64K window in PC space beginning at PF:0
539; (where PF is the Page Frame Segment)
540; This module looks at TOTAL_SYS_PAGES
541; to determine the memory size to be tested.
542;
543; (i) write the Translate Table for the 1st 64K block
544; of XMA memory to be mapped into PF:0 in PC space
545; (ii) test PF:0 to PF:FFFF
546; (iii) if good...write Translate Table to map next 64K block
547; into PF:0
548; (iv) repeat 'till all XMA memory is tested
549;
550; FUNCTION/ : See description
551; PURPOSE
552;
553;
554; ENTRY POINT : MEMARRAY
555;
556; ENTRY :
557; CONDITIONS
558;
559; EXIT : All SMAS memory is set to zero.
560;
561; (zero flag) = 0 if storage error
562; (AX) expected data XOR'ed with actual data
563; if AX = 0 and ZF = 0 then parity error
564; DS:SI point to failing location
565; CS:PAGE_UNDER_TEST point failing 64k block
566;
567; AX,BX,CX,DX,DS,ES,SI,DI ARE DESTROYED
568;
569;-------------------------------------------------------------------------
570
571MEMARRAY PROC
572
573 MOV AL,MEM_TEST
574 MOV CS:TEST_ID,AL
575
576;MEMORY TEST MUST RUN IN PAGE MODE
577
578 CALL VIRT2REAL
579
580;INDICATE 0 KB OK
581 MOV DX,(640-16)/4 ;CODE FOR 640 KB OK
582 CALL KB_OK
583;SETUP FOR TEST OF SMAS MEMORY ARRAY
584 MOV AX,CS:PAGE_FRAME_STA ;PAGE MEMORY FROM THIS SEGMENT
585 MOV ES,AX ;SET UP DEST SEG
586 MOV DS,AX ;SET UP SOURCE SEG
587 MOV BL,01H ;ENABLE THIS BLOCK OF MEMORY
588 MOV BH,0 ;USING ID 0
589 MOV DX,(640)/4 ;STARTING BLK IN SMAS ARRAY
590 ;DETERMINE HOW MUCH MEMORY TO TEST
591 MOV CX,CS:TOTAL_SYS_PAGES ;GET NUMBER OF 16K PAGES
592 SUB CX,640/16 ;SUBTRACT OFF 1ST 640K MEMORY ;an000; dms;
593;BEGIN TEST
594MA1:
595 MOV CS:PAGE_UNDER_TEST,DX ;INDICATE WHICH 64K BLOCK
596 PUSH AX ;IS UNDER TEST
597 PUSH BX
598 PUSH CX
599 PUSH DX ;SAVE ALL REGISTERS
600;
601 MOV CX,4 ;test 16k at one time ;an000; dms;
602 ;4 x 4K = 16K
603 CALL SETXLAT ;SET UP XLAT TABLE
604 CALL STGTST ;TEST 64K OF STORAGE
605 JNZ MA2 ;WAS THERE AN ERROR
606 POP DX
607 POP CX
608 POP BX
609 POP AX ;RESTORE REGISTERS
610;
611 PUSHF ;SAVE FLAGS FOR ADDITION
612
613 CALL KB_OK ;INDICATE HOW MUCH
614 ;MEMORY HAS BEEN TESTED
615
616
617 ADD DX,4 ;POINT TO NEXT 64K BLOCK
618 POPF ;RESTORE FLAGS
619 LOOP MA1 ;LOOP FOR NEXT 64K
620 JMP MA3 ;EXIT WHEN COMPLETE
621MA2:
622 POP DX
623 POP CX
624 POP BX ;BX IS POPPED TWICE
625 POP BX ;TO RESTORE STACK WHILE
626 ;MAINTAINING AX
627MA3:
628 PUSH AX
629 PUSH DX
630 PUSHF ;SAVE THESE REGS...THEY CONTAIN
631 ;USEFULL ERROR INFO
632;PUT THE SMAS CARD INTO REAL MODE
633 MOV DX,MODE_REG ;READY FOR I/O TO MODE REG
634 IN AL,DX ;READ IT
635 AND AL,REAL_MODE ;TURN OFF VIRTUAL BIT
636 OUT DX,AL ;WRITE IT TO MODE REG
637 POPF
638 POP DX
639 POP AX ;RESTORE THESE REGS
640 RET
641;
642MEMARRAY ENDP
643
644
645
646
647PAGE
648;---------------------------------------------------------------------
649;---------------------------------------------------------------------
650; LO MEMORY TEST
651;
652; DESCRIPTION : This routine tests the first 256K or 512K
653; of XMA memory depending on the starting
654; position of the starting address jumper on
655; the card. The memory that is used to
656; fill conventional memory space is not tested
657; it is tested during POST and may now contain
658; parts of COMMAND.COM.
659;
660; FUNCTION/ : See description
661; PURPOSE
662;
663; ENTRY POINT : LOMEMTST
664;
665; ENTRY :
666; CONDITIONS
667;
668; EXIT : All tested memory is set to zero
669;
670; (zero flag) = 0 if storage error
671; (AX) = expected data XOR'ed with actual data
672; if (AX)=0 and ZF=0 then parity error
673; DS:SI point to failing location
674; CS:PAGE_UNDER_TEST point to failing 64K block
675;
676; AX,BX,CX,DX,DI,SI,ES,DS ARE DESTROYED
677;
678;-----------------------------------------------------------------------
679LOMEMTST PROC
680
681 MOV AL,LOMEM_TEST
682 MOV CS:TEST_ID,AL
683
684;MEMORY TEST MUST RUN IN PAGE MODE
685 CALL VIRT2REAL
686
687;INDICATE 0 KB OK AT START OF TEST
688 MOV DX,03ffcH ;code for initial 0 kb ;an000; dms;
689 CALL KB_OK
690
691;DETERMINE HOW MUCH MEMORY TO TEST
692 MOV AX,CS:START_BACMEM_SEG ;get starting fill segment
693 XCHG AH,AL
694 MOV CL,2 ; ;an000; dms;
695 SHR AX,CL ;convert to 16k block number
696 MOV CS:TESTABLE_SEGMENTS,AX ;save...this is number of 64k blocks
697 ;that can be tested without
698 ;destroying DOS
699;SET UP FOR TEST OF XMA MEMORY
700 MOV AX,CS:PAGE_FRAME_STA ;test through page frame
701 MOV DS,AX ;set up ds
702 MOV ES,AX ;and es
703 MOV BL,01H ;enable this block of memory
704 MOV BH,0 ;using id=0
705 XOR DX,DX ;start at block 0 in xma
706 MOV CX,640/16 ;loop counter is # 16k blocks in
707 ;conventional memory
708LM1:
709 MOV CS:PAGE_UNDER_TEST,DX ;save page under test
710 PUSH AX
711 PUSH BX
712 PUSH CX
713 PUSH DX ;save these registers
714
715 MOV CX,4 ;test 16k at one time ;an000; dms;
716 ;4 * 4k = 16k
717 CALL SETXLAT ;set translate table
718 CMP CS:TESTABLE_SEGMENTS,0 ;if this segment under test is used for
719 ;fill then read only
720 JG LM2 ;else do storage test
721 CALL READ_ONLY
722 JMP LM3
723LM2:
724 CALL STGTST
725LM3:
726 JNZ LM4 ;jump if there was an error
727 POP DX
728 POP CX
729 POP BX
730 POP AX ;recover registers
731
732 PUSHF ;save flags for addition
733 CALL KB_OK
734 ;indicate kb ok
735 ADD DX,4 ;next 16k block ;an000; dms;
736 DEC CS:TESTABLE_SEGMENTS ;dec testable pages
737 POPF ;recover flags
738 LOOP LM1 ;repeat for next 64k block
739 JMP LM5 ;exit when complete
740LM4:
741 POP DX ;recover these registers
742 POP CX
743 POP BX ;bx is popped twice to restore
744 POP BX ;satck while maintaining ax
745LM5:
746 PUSH AX ;save these ... they contain
747 PUSH DX ;useful error information
748 PUSHF
749;PUT CARD BACK TO REAL MODE
750 MOV DX,MODE_REG ;read mode reg
751 IN AL,DX
752 AND AL,REAL_MODE ;turn off virtual bit
753 OUT DX,AL ;write it to mode reg
754 POPF
755 POP DX
756 POP AX ;restore these registers
757 RET
758
759
760READ_ONLY PROC ;INTERNAL PROC TO READ MEMORY WITHOUT DESTROYING CONTENTS
761 XOR SI,SI ;start of segment
762 XOR CX,CX ;test 64k
763
764 LODSW ;just read each byte
765 XOR AX,AX ;and set zf=1 for return
766 RET ;back to caller
767READ_ONLY ENDP
768
769LOMEMTST ENDP
770
771
772
773PAGE
774;-------------------------------------------------------------------------
775;-------------------------------------------------------------------------
776;
777; PAGE TEST
778;
779; DESCRIPTION : This routine tests that the TASK ID register is
780; actually paging in unique segments of memory.
781; The test is performed through the page frame segment.
782; The test assumes that the memory test has already
783; completed successfully. The page test procedes as
784; follows:
785; (i) 6-64K blocks of XMA memory are mapped into a
786; 64K segment of PC space (the page frame)
787; These XMA blocks are from 640k to 1024k of XMA memory.
788; (ii) Each of these blocks is assigned to a unique
789; task ID ranging from 0 to 5.
790; (iii) For each task ID, the page frame is filled with
791; a pattern that is the same as the task ID.
792; (iv) The page frame is then read for each task ID
793; and compared with the expected data.
794;
795; FUNCTION/ :
796; PURPOSE
797;
798; ENTRY POINT : PAGETST
799;
800; ENTRY : NONE
801; CONDITIONS
802;
803; EXIT : (zero flag) = 0 indicates an error
804; (AL) expected data XOR'ed with actual data
805;
806; AX,BX,CX,DX,ES,DS,SI,DI ARE DESTROYED
807;-------------------------------------------------------------------------
808;
809PAGETST PROC
810;
811 MOV AL,PAGE_TEST
812 MOV CS:TEST_ID,AL
813;MEMORY TEST MUST RUN IN PAGE MODE
814 CALL VIRT2REAL
815;INITIALIZE TRANSLATE TABLE FOR THIS TEST
816 MOV AX,CS:PAGE_FRAME_STA ;SEMENT OF PAGE FRAME
817 MOV BL,01H ;ENABLE CODE
818 MOV BH,0 ;START WITH TASK ID = 0
819 MOV DX,640/4 ;START WITH XMA BLOCK 160
820 MOV CX,6 ;LOOP COUNT...6 TASK ID's
821 ;EACH TASK ID IS ASSIGNED 16K
822 ;FROM 640K TO 1024K
823PT1:
824 PUSH AX
825 PUSH BX
826 PUSH CX
827 PUSH DX ;SAVE ALL REGISTERS
828;
829 MOV CX,4 ;4 -4K BLOCKS IN 16K ;an000; dms;
830 CALL SETXLAT ;SET TRANSLATE TABLE
831 POP DX
832 POP CX
833 POP BX
834 POP AX ;RECOVER ALL
835 INC BH ;POINT TO NEXT TASK ID
836 ADD DX,4 ;NEXT 64K IN XMA MEMORY ;an000; dms;
837 LOOP PT1 ;REPEAT FOR ALL TASK ID's
838;FILL MEMORY WITH A UNIQUE PATTERN FOR EACH TASK ID
839 MOV CX,6 ;6 TASK ID's
840 MOV DX,IDREG ;READY FOR I/O TO TASK ID REG
841 MOV AL,0 ;START WITH ID = 0
842PT2:
843 PUSH AX ;SAVE ID NUMBER
844 PUSH CX ;SAVE ID COUNT
845 OUT DX,AL ;SWITCH TASK ID
846 MOV BX,CS:PAGE_FRAME_STA
847 MOV ES,BX ;SEGMENT TO 1ST 64K 0F ID
848 SUB DI,DI ;POINT TO 1ST LOCATION
849 mov cx,4000h ;WRITE ALL 16K LOCATIONS ;an000; dms;
850PT2X:
851 STOSB
852 LOOP PT2X
853 POP CX ;RECOVER ID COUNT
854 POP AX ;RECOVER CURRENT ID
855 INC AL
856 LOOP PT2 ;REPEAT FOR ALL TASK ID's
857;NOW CHECK THAT THERE ARE 16 UNIQUE PATTERNS IN MEMORY
858 MOV CX,6 ;USE 6 TASK ID's
859 MOV AH,0 ;START WITH ID = 0
860PT3:
861 MOV AL,AH ;GET TASK ID IN AL
862 PUSH AX
863 PUSH CX ;SAVE ID COUNT
864 OUT DX,AL ;SWITCH TASK ID
865 MOV BX,CS:PAGE_FRAME_STA
866 MOV DS,BX
867 MOV ES,BX ;SEGMENT AT 1ST 64K
868 SUB DI,DI ;POINT TO 1ST LOCATION
869 SUB SI,SI ;POINT TO 1ST LOCATION
870 mov cx,4000h ;READ ALL 16K LOCATIONS
871PT3X:
872 LODSB
873 XOR AL,AH ;DATA AS EXPECTED ?
874 JNE PT4X ;NO - THEN EXIT
875 STOSB ;AL SHOULD CONTAIN 0...WRITE IT
876 LOOP PT3X
877
878 POP CX ;RECOVER ID COUNT
879 POP AX
880 INC AH ;NEXT TASK ID
881 LOOP PT3 ;REPEAT FOR ALL TASK ID's
882 XOR AL,AL ;IF WE GOT THIS FAR THEN
883 ;NO ERRORS...SET ZF TO
884 ;INDICATE SUCCESS
885PT4:
886 PUSH AX
887 PUSH DX
888 PUSHF ;SAVE THESE REGS...THEY CONTAIN
889 ;USEFULL ERROR INFO
890;PUT THE SMAS CARD INTO REAL MODE
891 MOV DX,MODE_REG ;READY FOR I/O TO MODE REG
892 IN AL,DX ;READ IT
893 AND AL,REAL_MODE ;TURN OFF VIRTUAL BIT
894 OUT DX,AL ;WRITE IT TO MODE REG
895;MAKE SURE WE EXIT WHILE IN TASK ID=0
896 MOV DX,IDREG
897 XOR AL,AL
898 OUT DX,AL
899
900 POPF
901 POP DX
902 POP AX ;RESTORE THESE REGS
903 RET ;RETURN TO CALLER
904PT4X:
905 POP CX ;ALTERNATE RETURN PATH
906 POP AX
907 JMP PT4 ;TO ADJUST STACK
908;
909PAGETST ENDP
910
911
912PAGE
913;-------------------------------------------------------------------------
914;-------------------------------------------------------------------------
915;
916; DMA CAPTURE TEST
917;
918; DESCRIPTION : This routine is a test of the DMA capture logic.
919; The test is as follows:
920; (i) A bit is rolled through the second entry in the
921; DMA cature register file. (The first entry is used
922; for refresh on a PC-XT).
923; (ii) A bit and address test is performed on the
924; remainder of the register file(s).
925; (iii) A test is made for the capture of both REQUEST and
926; MODE registers of the DMA controller.
927; (iv) DMA channel 0 is tested only on the PC-AT
928;
929;
930; FUNCTION/ : To verify the functionality of the DMA capture logic.
931; PURPOSE
932;
933; ENTRY POINT : CAPTST
934;
935; ENTRY : NONE
936; CONDITIONS
937;
938; EXIT : Each entry in the DMA capture register file is set to 0.
939;
940; (zero flag) = 0 indicates an error
941; '31A8'X points to failing DMA capture reg
942; (AL) expected data XOR'ed with actual data
943;
944; AX,BX,CX,DX,SI,DI ARE DESTROYED
945;-------------------------------------------------------------------------
946;
947;
948CAPTST PROC
949;
950 MOV AL,DMA_CAPTURE
951 MOV CS:TEST_ID,AL
952;
953;ROLL A BIT THROUGH THE SECOND ENTRY IN THE DMA CAPTURE REGISTER FILE
954;
955 MOV BL,01H ;SET UP INITIAL PATTERN
956 MOV BH,01H ;SET UP DMA CHANNEL 1
957 MOV DI,DMACAPT ;SAVE FOR I/O TO DMA CAPTURE REG
958 MOV SI,DMAREQ1 ;SAVE FOR I/O TO DMA CTRL 1 REQ REG
959 MOV CX,4 ;ROLL 4 BIT POSITIONS
960C1:
961 MOV DX,IDREG ;I/O TO ID REG
962 MOV AL,BL ;PATTERN TO WRITE
963 OUT DX,AX ;SETUP ID REG WITH DATA PATTERN
964 MOV DX,SI ;DMA CTRL 1
965 MOV AL,BH ;CHANNEL 1
966 OUT DX,AL ;SETUP DMA CH 1...CAPT ID IN 2nd ENTRY
967 MOV DX,DI ;DMA CAPTURE REG
968 OUT DX,AL ;POINT TO 2nd ENTRY
969 IN AL,DX ;READ IT
970 XOR AL,BL ;DATA READ AS EXPECTED ?
971 JNE CAPT_ERROR ;NO - THEN ERROR
972 SHL BL,1 ;SHIFT BIT TO NEXT POSITION
973 LOOP C1 ;REPEAT
974;
975 MOV DI,DMAREQ2 ;SETUP FOR I/O TO DMA CTRL 2 REQ REG
976 MOV AL,05H ;DATA PATTERN TO CAPTURE
977 CALL CAPT_FILL ;FILL CAPTURE REGS WITH VALUE
978;
979 MOV AH,05H ;SETUP INITIAL PATTERN
980 MOV BX,0F0AH ;OTHER PATTERNS TO USE
981C2:
982 CALL CAPT_RMW
983 JNZ CAPT_ERROR ;ERROR - THEN EXIT
984 CMP AH,BL ;ZERO PATTERN ?
985 JE CAPT_EXIT ;EXIT IF YES
986 MOV AH,BL ;SET UP
987 MOV BL,BH ; NEXT
988 MOV BH,0 ; PATTERN
989 JMP C2 ;REPEAT
990
991;NOW REPEAT TEST FOR CATPURE OF DMA MODE REGISTERS
992 MOV SI,DMAMODE1 ;SETUP FOR I/O TO DMA CTRL 1 MODE REG
993 MOV DI,DMAMODE2 ;SETUP FOR I/O TO DMA CTRL 2 MODE REG
994 MOV AL,05H ;DATA PATTERN TO CAPTURE
995 CALL CAPT_FILL ;FILL CAPTURE REGS WITH VALUE
996;
997 MOV AH,05H ;SETUP INITIAL PATTERN
998 MOV BX,0F0AH ;OTHER PATTERNS TO USE
999C3:
1000 CALL CAPT_RMW
1001 JNZ CAPT_ERROR ;ERROR - THEN EXIT
1002 CMP AH,BL ;ZERO PATTERN ?
1003 JE CAPT_EXIT ;EXIT IF YES
1004 MOV AH,BL ;SET UP
1005 MOV BL,BH ; NEXT
1006 MOV BH,0 ; PATTERN
1007 JMP C3 ;REPEAT
1008CAPT_ERROR:
1009CAPT_EXIT:
1010 RET
1011
1012CAPTST ENDP
1013
1014
1015
1016PAGE
1017
1018;-------------------------------------------------------------------------
1019;-------------------------------------------------------------------------
1020;
1021; FILL DMA CAPTURE REG
1022;
1023; DESCRIPTION : This routine will fill the entire DMA capture register
1024; file with the pattern that is passed in AL
1025;
1026; FUNCTION/ : See Description.
1027; PURPOSE
1028;
1029; ENTRY POINT : CAPT_FILL
1030;
1031; ENTRY : AL contains the value to be captured into
1032; CONDITIONS the register file.
1033; SI contains the address of DMA controller 1
1034; DI contains the address of DMA controller 2
1035;
1036; EXIT : Each entry in the DMA capture register file is set to
1037; the value specified in AL.
1038;-------------------------------------------------------------------------
1039;
1040CAPT_FILL PROC NEAR
1041;
1042 MOV DX,IDREG
1043 OUT DX,AL ;LOAD ID REG WITH PAT TO BE CAPTURED
1044 MOV DX,DI ;GET ADDRESS OF CTRL 2
1045 MOV CX,3 ;REP FOR CHANNELS 7,6,5
1046CF1:
1047 MOV AL,CL ;CL CONTAINS WHICH DMA CHANNEL
1048 OUT DX,AL ;SETUP & CAPTURE DMA CHANNEL
1049 LOOP CF1 ;REPEAT
1050;
1051 MOV DX,SI ;GET ADDRESS OF CTRL 1
1052 MOV CX,3 ;REP FOR CHANNELS 3,2,1
1053CF2:
1054 MOV AL,CL ;CL CONTAINS WHICH DMA CHANNEL
1055 OUT DX,AL ;SETUP & CAPTURE DMA CHANNEL
1056 LOOP CF2 ;REPEAT
1057 ;DO CHANNEL 0 IF NOT PC1, XT, AQUARIUS
1058 CMP CS:MODEL_BYTE,PC1 ;IS THIS A PC1 ?
1059 JE CF3 ;YES - THEN EXIT ELSE TRY PC_XT
1060 CMP CS:MODEL_BYTE,PC_XT ;IS THIS AN XT ?
1061 JE CF3 ;YES - THEN EXIT ELSE TRY AQUARIUS
1062 CMP CS:MODEL_BYTE,XT_AQUARIUS ;IS THIS AN AQUARIUS?
1063 JE CF3 ;YES - THEN EXIT ELSE FILL CH 0 CAPT
1064 MOV AL,0 ;INDICATE CHANNEL 0
1065 OUT DX,AL ;SETUP & CAPTURE DMA CHANNEL
1066CF3:
1067 RET ;RETURN TO CALLER
1068;
1069CAPT_FILL ENDP
1070
1071
1072
1073
1074PAGE
1075;-------------------------------------------------------------------------
1076;-------------------------------------------------------------------------
1077;
1078; READ-MODIFY-WRITE DMA CAPTURE REG
1079;
1080; DESCRIPTION : This routine will read the a DMA capture register
1081; and if the correct value is found will cause a capture
1082; of a new value. The next DMA capture reg is read and
1083; the process repeated.
1084;
1085; FUNCTION/ : See Description.
1086; PURPOSE
1087;
1088; ENTRY POINT : CAPT_RMW
1089;
1090; ENTRY : AH contains the value to be compared
1091; CONDITIONS BL contains the new value to be written
1092; SI contains the address of DMA controller 1
1093; DI contains the address of DMA controller 2
1094;
1095; EXIT : Each entry in the DMA capture register file is set to
1096; the value specified in BL.
1097;
1098; AL,CX,DX,ARE DESTROYED
1099;-------------------------------------------------------------------------
1100;
1101CAPT_RMW PROC NEAR
1102;
1103 MOV CX,3 ;REP FOR CHANNELS 7,6,5
1104RMW1:
1105 MOV DX,DMACAPT ;I/O ADDRESS OF DMA CAPTURE REG
1106 MOV AL,CL ;GET LOW BYTE OF COUNT
1107 ADD AL,4 ;ADD 4 TO POINT TO DMA CAPTURE
1108 CALL RMW
1109 JNZ RMW4 ;EXIT IF ERROR
1110 LOOP RMW1 ;REPEAT FOR CHANNEL 6,5
1111;
1112 MOV CX,3 ;REP FOR CHANNELS 3,2,1
1113 PUSH DI ;SAVE DMA CTRL 2
1114 MOV DI,SI ;GET DMA CTRL 1 INTO DI FOR PROC RMW
1115RMW2:
1116 MOV DX,DMACAPT ;I/O ADDRESS OF DMA CAPTURE REG
1117 MOV AL,CL ;GET LOW BYTE OF COUNT
1118 CALL RMW
1119 JNZ RMW3 ;EXIT IF ERROR
1120 LOOP RMW2 ;REPEAT FOR DMA CHANNELS 2,1
1121 ;DO CHANNEL 0 IF NOT PC1, XT, AQUARIUS
1122 CMP CS:MODEL_BYTE,PC1 ;IS THIS A PC1 ?
1123 JE RMW3 ;YES - THEN EXIT ELSE TEST FOR PC_XT
1124 CMP CS:MODEL_BYTE,PC_XT ;IS THIS AN XT ?
1125 JE RMW3 ;YES - THEN EXIT ELSE TEST FOR AQUARIUS
1126 CMP CS:MODEL_BYTE,XT_AQUARIUS ;IS THIS AN AQUARIUS?
1127 JE RMW3 ;YES - THEN EXIT ELSE TEST CH 0
1128 MOV DX,DMACAPT ;I/O ADDRESS OF DMA CAPTURE REG
1129 MOV CL,0 ;INDICATE CHANNEL 0
1130 MOV AL,CL ;ALSO INTO AL
1131 CALL RMW
1132RMW3:
1133 POP DI ;RESTORE DI (ADDR OF DMA CTRL 2)
1134RMW4:
1135 RET ;RETURN TO CALLER
1136;
1137CAPT_RMW ENDP
1138;
1139RMW PROC
1140;
1141 OUT DX,AL ;SETUP TO READ FROM DMA CAPTURE REG
1142 IN AL,DX ;READ IT
1143 XOR AL,AH ;DATA AS EXPECTED ?
1144 JNE RMW5 ;NO THEN EXIT
1145 ;DATA WAS GOOD---NOW GET NEXT PATTERN INTO THIS CAPTURE REG
1146 MOV DX,IDREG ;ADDRESS OF ID REG
1147 MOV AL,BL ;NEW PATTERN TO WRITE
1148 OUT DX,AL ;WRITE IT TO ID REG
1149 MOV DX,DI ;ADDRESS OF DMA CTRL 2
1150 MOV AL,CL ;DMA CHANNEL TO SET UP
1151 OUT DX,AL ;SET UP DMA---THIS CAUSES CAPTURE OF ID
1152RMW5:
1153 RET ;RETURN TO CALLER
1154;
1155RMW ENDP
1156
1157
1158
1159
1160PAGE
1161;-------------------------------------------------------------------------
1162;-------------------------------------------------------------------------
1163;
1164; INHIBIT A BLOCK OF MEMORY
1165;
1166; DESCRIPTION : This routine will set a block of SMAS memory with
1167; the code to enable or inhibit it. The user simply
1168; specifies the starting segment and length of the block in
1169; PC 'real' address space that is to be enabled/inhibited.
1170; The appropriate entries in the Translate Table are
1171; written so that this specified block in 'real' address
1172; is enabled or protected in all 16 possible TASK ID's.
1173;
1174;
1175; FUNCTION/ : To enable or inhibit SMAS memory in specified areas of
1176; PURPOSE PC 'real'address space (ie.,diplay buffer, BIOS,
1177; distributed ROS...)
1178;
1179; ENTRY POINT : INHIBLK
1180;
1181; ENTRY : (AX) starting segment in PC address space to be
1182; CONDITIONS protected/enabled. Must be on 4K boundary else
1183; this routine will round UP to next 4K block.
1184;
1185; (CX) number of 4K blocks to be protected
1186;
1187; (BL) 01 = ENABLE
1188; 00 = INHIBIT
1189;
1190; EXIT : specified entries in Translate Table are enabled or
1191; inhibited for all posible task ID's.
1192;
1193; AX,BH,CX,DX ARE DESTROYED
1194;-------------------------------------------------------------------------
1195;
1196INHIBLK PROC
1197;
1198 ;ADJUST SI FOR TRANSLATE TABLE ENTRY
1199 XCHG AL,AH ;ROTATE RIGHT BY 8
1200 XOR AH,AH ;CLEAR AH
1201 ;AX IS NOW ADJUSTED FOR ENTRY INTO
1202 ;XLAT TABLE FOR TASK ID=0
1203 PUSH AX ;SAVE IT
1204 PUSH CX ;SAVE COUNT OF 4K BLOCKS
1205;
1206 MOV SI,TTDATA ;ADDRESS OF TT DATA REG
1207 MOV DI,AIDATA ;ADDRESS OF TT DATA WITH AUTO INC
1208 XOR BH,BH ;BH IS TASK ID
1209INH1:
1210 MOV DX,TTPOINTER ;ADDRESS OF TT POINTER
1211 POP CX ;RESTORE COUNT
1212 POP AX ;RESTORE TT ENTRY
1213 PUSH AX ;SAVE BOTH
1214 PUSH CX ; OF THEM
1215 MOV AH,BH ;APPEND TASK ID TO TT POINTER
1216 OUT DX,AX ;SET TT POINTER TO STARTING ENTRY
1217INH2:
1218 MOV DX,SI ;TT DATA REG
1219 IN AX,DX ;READ CURRENT ENTRY
1220 MOV DX,DI ;ADDRESS OF TT DATA WITH AUTO INC
1221 ;DETERMINE IF ENABLE OR INHIBIT BLOCK
1222 CMP BL,ENABLE ;WANT TO ENABLE THIS BLOCK ?
1223 JNE INH3 ;NO - THEN DISABLE IT
1224 AND AH,BLK_ON ;MASK OFF INHIBIT BIT
1225 JMP INH4
1226INH3:
1227 OR AH,BLK_OFF ;MASK ON INHIBIT BIT
1228INH4:
1229 OUT DX,AX ;WRITE IT THEN INC TO NEXT TT ENTRY
1230 LOOP INH2 ;REPEAT FOR EACH BLOCK OF 4K
1231 INC BH ;NEXT TASK ID
1232 CMP BH,MAX_TASK_ID ;COMPLETED FOR ALL TASK ID's ?
1233 JBE INH1 ;NO - THEN LOOP TILL DONE
1234INHIBLK_EXIT:
1235 POP CX
1236 POP AX
1237 RET
1238;
1239INHIBLK ENDP
1240
1241
1242
1243
1244PAGE
1245;-------------------------------------------------------------------------
1246;-------------------------------------------------------------------------
1247;
1248; STORAGE TEST
1249;
1250; DESCRIPTION : This routine performs a bit and address test on a
1251; 64K block of storage.
1252;
1253; (i) 55AA is written to each location.
1254; (ii) 55AA is read back
1255; (iii) if good, write AA55 and point to next location
1256; (iv) repeat step (iii) for all 64K locations
1257; (v) repeat steps (ii) to (iv) for AA55, FF00, 0101, 0000
1258; (vi) check parity bits
1259;
1260;
1261; FUNCTION/ : See description
1262; PURPOSE
1263;
1264; ENTRY POINT : STGTST
1265;
1266; ENTRY : (ES) storage segment to be tested
1267; CONDITIONS (DS) storage segment to be tested
1268;
1269; EXIT : (zero flag) = 0 if storage error
1270; (AX) expected data XOR'ed with actual data
1271; if ax = 0 and zf = 0 then parity error
1272; DS:SI point to failing location
1273;
1274; AX,BX,CX,DX,DI,SI ARE DESTROYED
1275;
1276;-------------------------------------------------------------------------
1277;
1278STGTST PROC
1279;
1280 CMP CS:WARM_START,'Y' ;is this a warm start?
1281 JNE STG1A ;if no then do mem test
1282 CALL CLEAR_MEM ;if yes then just clear memory
1283 XOR AX,AX ;set zero flag
1284 JMP STG6 ;exit
1285
1286
1287 ;DISABLE NMI AND ENABLE I/O CHANNEL CHECK
1288STG1A:
1289 MOV AL,CS:MODEL_BYTE ;GET SAVED MODEL BYTE
1290 CMP AL,PC1 ;IS IT A PC1?
1291 JE STG1 ;IF NO THEN TRY FOR PC_XT
1292 CMP AL,PC_XT ;IS IT AN XT?
1293 JE STG1 ;IF NO THEN TRY FOR AQUARIUS
1294 CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS?
1295 JE STG1 ;IF NO THEN USE AT NMI REGS
1296 ;USE PC-AT NMI REGISTER
1297 MOV DX,AT_NMI_REG ;AT's NMI REGISTER
1298 MOV AL,AT_NMI_OFF ;MASK OFF NMI
1299 OUT DX,AL ;OUTPUT IT
1300 MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG
1301 IN AL,DX ;READ IT
1302 OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
1303 OUT DX,AL ;WRITE IT
1304 AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
1305 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
1306 ;ENABLED
1307 ;USE PC1, XT, AQUARIUS REGISTERS
1308STG1:
1309 MOV DX,XT_NMI_REG ;XT's NMI REGISTER
1310 MOV AL,XT_NMI_OFF ;MASK OFF NMI
1311 OUT DX,AL ;OUTPUT IT
1312 MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG
1313 IN AL,DX ;READ IT
1314 OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
1315 OUT DX,AL ;WRITE IT
1316 AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
1317 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
1318 ;ENABLED
1319
1320
1321
1322 ;ROLL A BIT THROUGH THE FIRST WORD
1323 SUB DI,DI ;FIRST LOCATION
1324 MOV CX,16 ;ROLL 16 BITS
1325 MOV AX,0001H ;FIRST PATTERN TO WRITE
1326 MOV BX,AX ;SAVE IT
1327STG2:
1328 MOV [DI],AX ;WRITE PATTERN
1329 MOV [DI+2],0FFFFH ;CHARGE BUS
1330 MOV AX,[DI] ;READ PATTERN
1331 XOR AX,BX ;IS IT CORRECT ?
1332 JNE STG_EXIT ;IF NO - THEN EXIT
1333 SHL BX,1 ;SHIFT BIT
1334 MOV AX,BX ;GET IT INTO AX
1335 LOOP STG2 ;REPEAT
1336;
1337 CLD ;FILL FORWARD
1338 SUB DI,DI ;POINT TO FIRST LOCATION
1339 MOV CX,2000H ;8K WORDS ;an000; dms;
1340 MOV AX,55AAH ;INITIAL PATTERN TO WRITE
1341 REP STOSW ;FILL ENTIRE SEGMENT
1342;
1343 MOV BX,55AAH ;PATTERN TO LOOK FOR
1344 MOV DX,0AA55H ;NEXT PATTERN TO WRITE
1345 CALL STG_CNT
1346 JNZ STG_EXIT ;EXIT IF ERROR
1347;
1348 MOV BX,0AA55H ;PATTERN TO LOOK FOR
1349 MOV DX,0101H ;NEXT PATTERN TO WRITE
1350 CALL STG_CNT
1351 JNZ STG_EXIT ;EXIT IF ERROR
1352;
1353 MOV BX,0101H ;PATTERN TO LOOK FOR
1354 MOV DX,0000H ;NEXT PATTERN TO WRITE
1355 CALL STG_CNT
1356 JNZ STG_EXIT ;EXIT IF ERROR
1357;
1358; MOV BX,0000H ;PATTERN TO LOOK FOR
1359; MOV DX,0000H ;NEXT PATTERN TO WRITE
1360; CALL STG_CNT
1361; JNZ STG_EXIT ;EXIT IF ERROR
1362;
1363 ;IF TEST REACHES THIS POINT THEN MEMORY IS GOOD
1364 ;NEED TO CHECK PARITY BITS...IF PARITY ERROR EXISTS THEN
1365 ;CAN ASSUME BAD PARITY BIT OR BAD PARITY GENERATOR
1366;
1367 MOV AL,CS:MODEL_BYTE ;GET SAVED MODEL BYTE
1368 CMP AL,PC1 ;IS IT A PC1?
1369 JE STG3 ;USE XT REGISTERS
1370 CMP AL,PC_XT ;IS IT AN XT?
1371 JE STG3 ;USE XT REGISTERS
1372 CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS?
1373 JE STG3 ;USE XT REGISTERS
1374 ;IF NONE OF THE ABOVE THEN...
1375 ;USE AT NMI REGISTER
1376 MOV DX,AT_CHCHK_REG ;AT's I/O CH CHK REG
1377 IN AL,DX ;READ IT
1378 AND AL,AT_CHCHK ;IS CH CHK BIT ON ?
1379 JZ STG4 ;IF NO - THEN EXIT
1380 MOV AX,0 ;ELSE - CLEAR AX TO INDICATE
1381 ;PARITY ERROR
1382 JMP STG4 ;EXIT
1383 ;USE XT/AQUARIUS NMI REGISTER
1384STG3:
1385 MOV DX,XT_CHCHK_REG ;XT's I/O CH CHK REG
1386 IN AL,DX ;READ IT
1387 AND AL,XT_CHCHK ;IS CH CHK BIT ON ?
1388 JZ STG4 ;IF NO - THEN EXIT
1389 MOV AX,0 ;ELSE - CLEAR AX TO INDICATE
1390 ;PARITY ERROR
1391STG4:
1392STG_EXIT:
1393 PUSH AX ;SAVE THESE REGS
1394 PUSH DX ;THEY CONTAIN
1395 PUSH SI
1396 PUSHF ;USEFUL ERROR INFORMATION
1397 ;BEFORE NMI IS ENABLED, CLEAR PARITY CHECK LATCH ON XMA
1398 MOV SI,0
1399 MOV AX,[SI] ;READ 1ST WORD OF THIS SEG
1400 MOV [SI],AX ;WRITE BACK SAME WORD
1401 ;THE WRITE WILL CLEAR PCHK LTCH
1402 ;CLEAR I/O CHANNEL CHECK LATCHES AND ENABLE NMI
1403 MOV AL,CS:MODEL_BYTE ;GET SAVED MODEL BYTE
1404 CMP AL,PC1 ;IS IT A PC1?
1405 JE STG5 ;USE XT REGISTERS
1406 CMP AL,PC_XT ;IS IT AN XT?
1407 JE STG5 ;USE XT REGISTERS
1408 CMP AL,XT_AQUARIUS ;IS IT AN AQUARIUS?
1409 JE STG5 ;USE XT REGISTERS
1410 ;IF NONE OF THE ABOVE THEN...
1411 ;USE AT NMI REGISTER
1412 MOV DX,AT_CHCHK_EN_REG ;AT's I/O CH CHK REG
1413 IN AL,DX ;READ IT
1414 OR AL,AT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
1415 OUT DX,AL ;WRITE IT
1416 AND AL,AT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
1417 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
1418 ;ENABLED
1419 MOV DX,AT_NMI_REG ;AT's NMI REGISTER
1420 MOV AL,AT_NMI_ON ;MASK ON NMI
1421 OUT DX,AL ;OUTPUT IT
1422 ;USE XT/AQUARIUS NMI REGISTER
1423STG5:
1424 MOV DX,XT_CHCHK_EN_REG ;XT's I/O CH CHK REG
1425 IN AL,DX ;READ IT
1426 OR AL,XT_CHCHK_DIS ;MASK OFF I/O CH CHK ENABLE
1427 OUT DX,AL ;WRITE IT
1428 AND AL,XT_CHCHK_EN ;MASK ON I/O CH CHK ENABLE
1429 OUT DX,AL ;TOGGLE CH CHK LTCH AND LEAVE
1430 ;ENABLED
1431 MOV DX,XT_NMI_REG ;XT's NMI REGISTER
1432 MOV AL,XT_NMI_ON ;MASK ON NMI
1433 OUT DX,AL ;OUTPUT IT
1434;
1435 POPF
1436 POP SI
1437 POP DX
1438 POP AX ;RESTORE REGS
1439STG6:
1440 RET ;RETURN TO CALLER
1441
1442
1443
1444CLEAR_MEM PROC ;INTERNAL PROC TO CLEAR MEMORY
1445 XOR DI,DI ;start of segment
1446 XOR CX,CX ;clear entire segment
1447 XOR AX,AX ;write zeroes
1448
1449 STOSB ;just write
1450 RET ;back to caller
1451CLEAR_MEM ENDP
1452
1453
1454STGTST ENDP
1455
1456
1457PAGE
1458;-------------------------------------------------------------------------
1459;-------------------------------------------------------------------------
1460;
1461; STORAGE TEST SUBROUTINE
1462;
1463; DESCRIPTION : This routine performs a bit and address test on a
1464; 64K block of storage.
1465;
1466; (i) a word is read and compared against the value in (BX)
1467; (ii) if good the value in (DX) is written into that location
1468; (iii) point to next location and repeat steps (i) to (ii)
1469;
1470;
1471; FUNCTION/ : See description
1472; PURPOSE
1473;
1474; ENTRY POINT : STG_CNT
1475;
1476; ENTRY : (ES) storage segment to be tested
1477; CONDITIONS (DS) storage segment to be tested
1478; (BX) value to be compared
1479; (DX) new value to be written
1480;
1481; EXIT : (zero flag) = 0 if storage error
1482; (AX) expected data XOR'ed with actual data
1483; if ax = 0 and zf = 0 then parity error
1484; DS:SI point to failing location
1485;-------------------------------------------------------------------------
1486;
1487STG_CNT PROC
1488;
1489 MOV CX,2000H ;8K WORDS ;an000; dms;
1490 SUB DI,DI ;FIRST LOCATION
1491 MOV SI,DI ;FIRST LOCATION
1492SC1:
1493 LODSW ;READ OLD WORD FROM STORAGE
1494 XOR AX,BX ;DATA AS EXPECTED ?
1495 JNE SC2 ;IF NO - THEN EXIT
1496 MOV AX,DX ;GET NEW PATTERN
1497 STOSW ;WRITE IT
1498 LOOP SC1 ;REPEAT
1499SC2:
1500 RET
1501
1502STG_CNT ENDP
1503
1504
1505
1506
1507PAGE
1508;-------------------------------------------------------------------------
1509;-------------------------------------------------------------------------
1510;
1511; PRINT MEMORY GOOD
1512;
1513; DESCRIPTION : This routine will print to the screen how much memory
1514; has been tested.
1515;
1516; The format will be: xxxx KB TESTED
1517;
1518; FUNCTION/ : See description
1519; PURPOSE
1520;
1521;
1522; ENTRY POINT : KB_OK
1523;
1524; ENTRY : (DX) = 1/4 OF GOOD MEMORY + 64K IN KB
1525; CONDITIONS ex: if (DX) = 16 then
1526; (16 * 4) + 64 = 128KB is OK
1527;
1528; NOTE: if (DX) = FFF0 then 0 KB is OK
1529;
1530;
1531; EXIT : Message is displayed
1532;
1533; All registers are preserved
1534;
1535;-------------------------------------------------------------------------
1536;
1537KB_OK PROC
1538;
1539 PUSH AX
1540 PUSH BX
1541 PUSH CX
1542 PUSH DX
1543 PUSH SI
1544 PUSH DI
1545 PUSH DS ;SAVE REGISTERS
1546;
1547 PUSH CS
1548 POP DS ;GET DS TO THIS CODE SEGMENT
1549 ;CONVERT DX TO KILO BYTES
1550 SHL DX,1
1551 SHL DX,1 ;MULTIPLY BY 4
1552 ADD DX,16 ;ADJUST BY 16 ;an000; dms;
1553;
1554 MOV AX,DX ;GET NUMBER INTO AX
1555 MOV BX,10 ;READY FOR DECIMAL CONVERT
1556 MOV CX,4 ;OF 4 DIGITS
1557K1:
1558 XOR DX,DX ;CLEAR HI WORD OF DIVIDEND
1559 ;AX IS LOW WORD OF DIVIDEND
1560 DIV BX ;DIVIDE BY 10
1561 OR DL,30H ;MAKE MODULO INTO ASCII
1562 PUSH DX ;SAVE IT
1563 LOOP K1 ;REPEAT FOR ALL DIGITS
1564;
1565 XOR SI,SI ;CLEAR SI
1566 MOV CX,4
1567K2:
1568 POP AX ;ASCII DIGIT GOES INTO AL
1569 MOV BX,OFFSET MEM_OK
1570 MOV CS:[BX+SI],AL ;BUILD ASCII MESSAGE
1571 INC SI
1572 LOOP K2
1573 ;MOVE THE CURSOR AND PRINT MESSAGE
1574 MOV DX,CUR_SAVE
1575 MOV BH,ACTIVE_PAGE
1576 MOV AH,2 ;SET CURSOR
1577
1578 INT 10H ;BIOS VIDEO CALL SET CURSOR
1579 MOV AH,9 ;DOS PRINT STRING
1580 MOV DX,OFFSET SIZE_MSG1 + 1 ;OFFSET OF MEM_OK MSG
1581 INT 21H ;DISPLAY MESSAGE
1582
1583 POP DS
1584 POP DI
1585 POP SI
1586 POP DX
1587 POP CX
1588 POP BX
1589 POP AX ;RESTORE ALL REGISTERS
1590
1591 RET ;RETURN TO CALLER
1592
1593KB_OK ENDP
1594
1595
1596PAGE
1597;-------------------------------------------------------------------------
1598;-------------------------------------------------------------------------
1599;
1600; SET TRANSLATE TABLE
1601;
1602; DESCRIPTION : This routine will write the Translate Table so that
1603; a specified block of PC 'real' address will be mapped
1604; to a specified block of SMAS physycal memory. Note that
1605; this routine will map only into CONTIGUOUS blocks of
1606; SMAS memory. PC memory is referenced by segments
1607; (must be on 4K boundaries) while SMAS memory is referenced
1608; by block number (each block is 4K).
1609;
1610; EXAMPLE: segment 4000 can be mapped to block 5
1611; segment 4100 can be mapped to block 6
1612;
1613; FUNCTION/ : To map PC 'real' addresses into SMAS physical memory.
1614; PURPOSE
1615;
1616;
1617; ENTRY POINT : SETXLAT
1618;
1619; ENTRY : (AX) starting segment in PC address space to be
1620; CONDITIONS mapped. Must be on 4K boundary else
1621; this routine will round UP to next 4K block.
1622;
1623; (CX) number of 4K blocks translated.
1624;
1625; (BH) task ID for this memory allocation
1626;
1627; (BL) 01 = ENABLE
1628; 00 = INHIBIT
1629;
1630; (DX) starting block number in SMAS memory
1631;
1632;
1633; EXIT : specified entries in Translate Table are enabled or
1634; inhibited for all posible task ID's.
1635;
1636;
1637; AX,CX,DX ARE DESTROYED
1638;
1639;-------------------------------------------------------------------------
1640;
1641SETXLAT PROC
1642;
1643 ;ADJUST AX FOR TRANSLATE TABLE ENTRY
1644 XCHG AL,AH ;ROTATE RIGHT BY 8
1645 MOV AH,BH ;TASK ID INTO BH
1646 ;AX IS NOW ADJUSTED FOR ENTRY INTO
1647 ;XLAT TABLE FOR TASK ID=(BH)
1648 PUSH DX ;SAVE STARTING SMAS BLOCK NUMBER
1649;
1650 MOV DX,TTPOINTER ;ADDRESS OF TT POINTER
1651 OUT DX,AX ;SET TT POINTER TO STARTING ENTRY
1652 POP AX ;GET STARTING BLOCK NUMBER INTO AX
1653;
1654 MOV DX,AIDATA ;TT DATA REG WITH AUTO INC
1655 ;DETERMINE IF ENABLE OR INHIBIT BLOCK
1656 CMP BL,ENABLE ;WANT TO ENABLE THIS BLOCK ?
1657 JE SETX1 ;YES - THEN SKIP THE DISABLE STEP
1658 OR AH,BLK_OFF ;MASK ON INHIBIT BIT
1659SETX1:
1660 OUT DX,AX ;WRITE IT THEN INC TO NEXT TT ENTRY
1661 INC AX ;NEXT BLOCK OF SMAS MEMORY
1662 LOOP SETX1 ;REPEAT FOR EACH BLOCK OF 4K
1663SETXLAT_EXIT:
1664 RET
1665;
1666SETXLAT ENDP
1667
1668 PAGE
1669;-------------------------------------------------------------------------
1670;-------------------------------------------------------------------------
1671;
1672; AUTO-INCREMENT TEST
1673;
1674; DESCRIPTION : This routine will test the auto-increment of
1675; the Translate Table pointer. The test will procede
1676; in the following manner:
1677; (i) A basic check of the TT pointer reg is performed
1678; (ii) The TT pointer is initialized to '00'H
1679; (iii) The auto increment data reg is written
1680; (iv) The TT pointer is read and checked for increment
1681; (v) Repeat until TT pointer wraps from 'FFF'H to '000'H
1682; (vi) Repeat test for auto-increment for read of data reg
1683;
1684; FUNCTION/ : To ensure that the Translate Table pointer can auto
1685; PURPOSE increment when 31A5 is written or read.
1686;
1687; ENTRY POINT : INCTST
1688;
1689; ENTRY : NONE
1690; CONDITIONS
1691;
1692; EXIT :
1693; (zero flag) = 0 indicates an error
1694; (DX) failing register (ie.,TT pointer reg)
1695; (AX) expected data XOR'ed with actual data
1696;-------------------------------------------------------------------------
1697;
1698;
1699INCTST PROC
1700;
1701 MOV AL,AUTO_INC
1702 MOV CS:TEST_ID,AL
1703;
1704;PERFORM SIMPLE TEST OF TTPOINTER REG
1705;
1706 MOV BX,0AA55H ;SET UP PATTERN TO WRITE
1707 MOV AX,BX
1708 MOV DX,TTPOINTER ;I/O TO TTPOINTER REG
1709 MOV SI,TTDATA ;SAVE FOR I/O TO TTDATA
1710 OUT DX,AX ;WRITE THE REGISTER
1711 XCHG DX,SI ;I/O TO TTDATA REG
1712 XCHG AH,AL ;INVERSE PATTERN
1713 OUT DX,AX ;CHARGE BUS WITH OPPOSITE PATTERN
1714 XCHG DX,SI ;I/O TO TTPOINTER REG
1715 IN AX,DX ;READ TTPOINTER REG
1716 XOR AX,BX ;READ AS EXPECTED
1717 AND AX,0FFFH ;MASK OFF HI NIBBLE (INVALID)
1718 JNE INC_ERROR ;NO - THEN EXIT
1719;
1720;CONTINUE WITH AUTO-INC TEST
1721;
1722 MOV DI,2 ;2 PASSES...1 WRITE , 1 READ
1723AI1:
1724 MOV SI,AIDATA ;SAVE FOR I/O TO TTDATA WITH AUTO-INC
1725AI2:
1726 MOV CX,1000H ;TTPOINTER RANGE 0 -> FFF
1727 MOV BX,0001H ;INITIAL COMPARE VALUE
1728 MOV AX,0 ;SET TTPONTER TO ZERO
1729 OUT DX,AX ;TTPOINTER IS INITIALIZED TO ZERO
1730AI2X:
1731 XCHG DX,SI ;I/O TO TTDATA WITH AUTO-INC
1732;
1733;DETERMINE IF WRITE OR READ TEST
1734;
1735 CMP DI,2 ;DOING A AUTO-INC WRITE TEST ?
1736 JNE AI3 ;NO - THEN MUST BE AUTO-INC READ TEST
1737 OUT DX,AX ;WRITE TO AUTO-INC DATA REG
1738 JMP AI4 ;CONTINUE WITH TEST
1739AI3:
1740 IN AX,DX ;READ FROM AUTO-INC DATA REG
1741AI4:
1742 XCHG DX,SI ;I/O TO TTPOINTER REG
1743 IN AX,DX ;READ TTPOINTER (31A1 -> AH)
1744 XOR AX,BX ;DATA AS EXPECTED ?
1745 AND AX,0FFFH ;MASK OFF UPPER NIBBLE (INVALID)
1746 JNE INC_ERROR ;NO - GO TO ERROR
1747 INC BX ;NEXT VALUE TO LOOK FOR
1748 LOOP AI2X ;CONTINUE TIL ALL VALUES ARE TESTED
1749;
1750 DEC DI
1751 CMP DI,0 ;COMPLETE WITH WRITE AND READ TEST ?
1752 JE INC_EXIT ;YES - THEN EXIT
1753 JMP AI1 ;NO - THEN CONTINUE WITH READ TEST
1754;
1755INC_ERROR:
1756INC_EXIT: RET
1757;
1758INCTST ENDP
1759
1760PAGE
1761;-------------------------------------------------------------------------
1762;-------------------------------------------------------------------------
1763;
1764; TRANSLATE TABLE TEST
1765;
1766; DESCRIPTION : This routine performs a write/read storage test
1767; on the Translate Table. The test is as follows:
1768; (i) A bit is rolled through the first word of the TT
1769; (ii) A bit and address test is performed on the
1770; remainder of the TT.
1771;
1772; FUNCTION/ : To verify the integrity of the Translate Table.
1773; PURPOSE
1774;
1775; ENTRY POINT : XLATST
1776;
1777; ENTRY : NONE
1778; CONDITIONS
1779;
1780; EXIT : Entire Translate Table is left with FFF (passover code)
1781;
1782; (zero flag) = 0 indicates an error
1783; (DX) failing register (TT data register)
1784; (AX) expected data XOR'ed with actual data
1785; (31A0) address in TT of failure
1786;-------------------------------------------------------------------------
1787;
1788XLATST PROC
1789;
1790 MOV AL,XLAT_TABLE_TEST
1791 MOV CS:TEST_ID,AL
1792;
1793;ROLL A BIT THROUGH THE FIRST BYTE
1794;
1795 MOV BX,0001H ;SET UP INITIAL PATTERN
1796 MOV SI,TTDATA ;SAVE FOR I/O TO DATA REG
1797 MOV DX,TTPOINTER ;I/O TO TTPOINTER REG
1798 MOV CX,12 ;ROLL 12 BIT POSITIONS
1799 XOR AX,AX ;CLEAR AX (WRITE TO 1st TT LOCATION)
1800 OUT DX,AX ;SET TT POINTER
1801 XCHG DX,SI ;READY FOR I/O TO TTDATA REG
1802X1:
1803 MOV AX,BX ;GET BIT PATTERN
1804 OUT DX,AX ;WRITE BIT PATTERN TO TT
1805 XCHG DX,SI ;READY FOR I/O TO TTPOINTER REG
1806 XOR AX,AX ;CLEAR AX
1807 OUT DX,AX ;CHARGE BUS WITH 0000 PATTERN
1808 XCHG DX,SI ;READY FOR I/O TO TTDATA REG
1809 IN AX,DX ;READ TT (31A1 -> AH)
1810 XOR AX,BX ;DATA READ AS EXPECTED ?
1811 AND AX,0FFFH ;MASK OFF UPPER NIBBLE (INVALID)
1812 JNE XLA_ERROR ;NO - THEN EXIT
1813 SHL BX,1 ;SHIFT BIT TO NEXT POSITION
1814 LOOP X1
1815;
1816;CONTINUE REMAINDER OF TRANSLATE TABLE
1817;
1818 MOV DX,AIDATA
1819;
1820 XCHG DX,SI ;READY FOR I/O TO TTPOINTER
1821 XOR AX,AX ;CLEAR AX
1822 OUT DX,AX ;TTPOINTER AT 1st LOCATION
1823;
1824 XCHG DX,SI ;READY FOR I/O TO TT DATA W/AUTO-INC
1825 MOV AX,0AA55H ;INITIAL DATA PATTERN
1826 MOV CX,TABLEN ;NUMBER OF TT ENTRIES
1827X2:
1828 OUT DX,AX ;SETUP INVERSE PATTERN
1829 LOOP X2 ;FILL ENTIRE XLATE TABLE
1830;
1831 MOV SI,TTDATA ;ADDRESS OF TTDATA WITHOUT INC.
1832 MOV BX,AX ;SAVE VALUE FOR COMPARE
1833 MOV DI,055AAH ;NEXT PATTERN TO WRITE
1834X3:
1835 MOV CX,TABLEN ;NUMBER OF TT ENTRIES
1836X4:
1837 XCHG DX,SI ;GET IT INTO DX...SI GETS AUTO-INC
1838 IN AX,DX ;READ TABLE ENTRY (HI BYTE -> AH)
1839 XOR AX,BX ;DATA READ AS EXPECTED ?
1840 AND AX,0FFFH ;MASK OFF HI NIBBLE (INVALID)
1841 JNE XLA_ERROR ;NO - THE EXIT
1842 XCHG DX,SI ;GET TTDATA WITH AUTO-INC
1843 MOV AX,DI ;RECOVER NEXT PATTERN TO WRITE
1844 OUT DX,AX ;WRITE IT THEN INCREMENT
1845 LOOP X4 ;REPEAT TILL TABLE FILLED
1846
1847
1848;
1849 CMP DI,0FFFFH ;LAST PASS ?
1850 JE XLA_EXIT ;YES - THEN EXIT REG TEST
1851;
1852 XCHG BX,DI ;BX GETS NEXT PATTERN TO TEST
1853;
1854 CMP BX,055AAH ;LAST PASS FOR AA55,55AA PATTERN?
1855 JNE X5 ;NO
1856 MOV DI,0FF00H ;YES- PREPARE TO WRITE NEW PATTERN
1857 JMP X3 ;DO IT
1858X5:
1859 CMP BX,0FF00H ;READY TO READ 0FF00 PATTERN
1860 JNE X6 ;NO
1861 MOV DI,00FFH ;YES- PREPARE TO WRITE NEW PATTERN
1862 JMP X3 ;DO IT
1863X6:
1864 MOV DI,0FFFFH ;PREPARE TO SET ALL OF TT INACTIVE
1865 JMP X3 ;DO IT
1866;
1867XLA_ERROR:
1868XLA_EXIT: RET
1869;
1870XLATST ENDP
diff --git a/v4.0/src/DEV/XMA2EMS/XMA2EMS.ASM b/v4.0/src/DEV/XMA2EMS/XMA2EMS.ASM
new file mode 100644
index 0000000..43f038f
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/XMA2EMS.ASM
@@ -0,0 +1,2591 @@
1
2PAGE 85,132 ;Set for 5182 Pageprinter
3 ;85 lines per page, 132 col per line
4 ;(formerly 60,132)
5
6;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
7;º º
8;º This is the new version of the XMA2EMS driver for DOS 3.3. º
9;º It contains the following revisions and code flags: º
10;º º
11;º @RH0 - Correct scrolling problem º
12;º @RH1 - Expand table to 32M º
13;º @RH2 - Real Mode support (XMA/A card) º
14;º @RH3 - Memory Expansion Option (MXO a.k.a. XMO) support º
15;º @RH4 - LIM 4.0 support º
16;º @RH5 - Multicard support º
17;º @RH6 - WSP interfaces º
18;º @RH7 - 386 XMA Emulator support º
19;º @RH8 - Make driver reentrant º
20;º º
21;º AN007 P5134 - Provide variable planar size support. º
22;º Modify linked list to forward link vs. the º
23;º reverse linked list. º
24;º º
25;º AN008 P5150 - Fix incorrect access of slot 0 when no º
26;º Catskill/Holster card is in slot 0. º
27;º º
28;ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
29;º It should be noted that certain EMS calls will alter the contents º
30;º of the translate table pointer for any supported memory cards or º
31;º emulators (i.e. MXO, XMA, XMA/A cards, 80386 XMA emulator). º
32;º Therefore, software that writes to the translate table(s) has the º
33;º responsiblity of keeping the integrity of the TT pointer. For º
34;º example, programs should disable interrupts between setting the º
35;º TT pointer and writing the TT data. This will prevent: An interrupt º
36;º occurring between the two, control going to another application º
37;º that makes an EMS call and thus screws up the TT ptr. The EMS calls º
38;º that do this are: º
39;º Function # EMS Call º
40;º 5 Map logical to physical page º
41;º 8, 15/0 Save (Get) mapping array º
42;º 9, 15/1 Restore (Set) mapping array º
43;º 15/2 Get and Set mapping array º
44;º º
45;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
46
47;XMA2EMS provides a Lotus/Intel/Microsoft Expanded Memory (EMS) interface
48;for the IBM Expanded Memory Adapter (XMA).
49
50;Program Property of Microsoft
51
52;Add the following statement to CONFIG.SYS
53; DEVICE=[d:][path]XMA2EMS.SYS
54
55
56;-----------------------------------------------------------------------;
57; Equates go here ;
58;-----------------------------------------------------------------------;
59EMS_INT EQU 67H ;EMS INTERRUPT
60EM_INT EQU 15H ;EM INTERRUPT ;an000; dms;
61DK_Int equ 13h ;disk interrupt ;an004; dms;
62EM_Size_Get EQU 88h ;get EM size ;an000; dms;
63EMM_VERSION EQU 40H ;VERSION 4.0
64PF_HI_LIMIT EQU 0E000H ;highest allowable page frame segment
65PF_LOW_LIMIT EQU 0A000H ;lowest allowable page frame segment
66OK EQU 'OK' ;card is good
67HW_ERROR EQU 'HW' ;card is not functional...HardWare error
68SW_ERROR EQU 'SW' ;SoftWare error has been detected
69PAGE_INHIBITTED EQU 0FFFFh ;Entry in the save area indicating
70 ; a page is currently inhibitted
71REUSABLE_HANDLE EQU 'HR' ;Reusable (free) entry in the @RH1
72 ; handle lookup table. Placed in @RH1
73 ; the 'pages' field @RH1
74REUSABLE_SAVEA EQU 'SR' ;Reusable (free) entry in the @RH1
75 ; handle save area. 0 is a valid @RH1
76 ; page #, and 'FFFF' is for saving @RH1
77 ; an inhibitted field, so S(ave) @RH1
78 ; R(eusable) is stored. Page 5352 @RH1
79 ; not a valid page (5352 = 333Meg) @RH1
80 ;Page Allocation List entries
81 ; Allocated pages have the handle #
82UNALLOCATED EQU 'U' ; Unused entry
83ALLOCATED EQU 'X' ; Temporary...used by reallocate @RH4
84PAL_NULL EQU '--' ; End of list marker @RH8
85EXTENDED EQU 'ME' ; Extended memory (not for EMS use)@RH8
86BACMEM_ALLOC EQU 'MB' ; Allocated to back conventional @RH8
87 ; memory (back disabled planar)
88WSP_ALLOC EQU 'SW' ; Allocated to Workstation Program @RH8
89 ; Pages kept as extended memory by:
90RESR_EXT EQU 'ER' ; /E parameter
91PREV_EXT EQU 'EP' ; Previously loaded drivers
92 ; These values are OK as long as the
93 ; # of handles supported (40h) is
94 ; not above the ascii 'B' (42h)
95WARM_MASK EQU 1 ;ISOLATE WARM START BIT
96OFFSET_IN_XREF EQU BYTE PTR[BX+SI]
97LENGTH_IN_XREF EQU BYTE PTR[BX+SI+1]
98PAGE_LIST_ENTRY EQU WORD PTR[SI + OFFSET PAGE_ALLOC_LIST] ; @RH8
99page_table_entry EQU byte PTR[SI + OFFSET PAGE_ALLOC_table] ;temp for assembl
100XREF_TABLE_ENTRY EQU word PTR[DI + OFFSET HANDLE_XREF_TABLE] ; @RH1
101NUM_PHYSICAL_PAGES EQU 4
102STACK_SIZE EQU 100H
103Instance_Size EQU 150 ;instance size ;an000; dms;
104Instance_Count EQU 3 ;number of instances ;an000; dms;
105
106 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
107 ;³ Common memory adapter declares ³
108 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
109SLOT_SETUP EQU 08h ;Mask to put the desired adapter @RH2
110 ; slot into setup mode, activating @RH2
111 ; the 10X registers @RH2
112CARD_ID_LO EQU 100H ;PS/2 Adapter card id low and @RH2
113CARD_ID_HI EQU 101H ; high bytes - read only @RH2
114 ;Card IDs read from port 100,101 @RH2
115XMAA_CARD_ID EQU 0FEF7h ; XMA/A Card ID @RH2
116HLST_CARD_ID EQU 0FEFEh ; MXO @RH3
117NO_CARD EQU 0FFFFh ; No card present @RH5
118 ;Values for the flag MEMCARD_MODE @RH5
119 ; indicating what type of memory @RH5
120 ; card is being used. @RH5
121XMA1_VIRT EQU 00000001B ; XMA 1...always in virtual
122XMAA_VIRT EQU 00000010B ; XMA/A card (PS/2) in virtual
123EMUL_VIRT EQU 00000100B ; XMA emulator on 80386 @RH7
124XMAA_REAL EQU 00001000B ; XMA/A in real mode...no banking @RH3
125HOLS_REAL EQU 00010000B ; MXO card @RH3
126 ;Combinations
127XMA1A_VIRT EQU 00000011B ; XMA1 or XMA/A in virtual mode
128WSP_VIRT EQU 00000111B ; Any virtual mode...banking used
129
130 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
131 ;³ XMA, XMA\A, and XMA emulator declares ³
132 ;³ ³
133 ;³ The XMA translate table is a 4K x 12 bit ³
134 ;³ array. A 12 bit address points to entries ³
135 ;³ in the TT. The data in the entry is: ³
136 ;³ ³
137 ;³ Bit Contents ³
138 ;³ 12 Inhibit bit (1 = inhibit xlate) ³
139 ;³ 10-0 On XMA 1, pointer to 4K block ³
140 ;³ for up to 4 meg capability ³
141 ;³ 11-0 On XMA/A, pointer to 4K block ³
142 ;³ for up to 8 meg capability ³
143 ;³ ³
144 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
145 ;All are byte ports unless indicated
146
147X_CTRL_REG EQU 102H ;Control register - en/disable functions
148X_CONF_REG EQU 105H ;Config (mem size), channel check reg.
149RM_TTPTR_LO EQU 106H ;Translate table pointer low and
150RM_TTPTR_HI EQU 107H ; high bytes
151RM_TTDATA_LO EQU 103H ;TT data - high and low bytes
152RM_TTDATA_HI EQU 104H ; Low byte (103) auto incs the TT ptr
153
154 ;Virtual mode port addresses for:
155TTPOINTER EQU 31A0H ; Translate Table Pointer (word)
156TTDATA EQU 31A2H ; Translate Table Data (word)
157AIDATA EQU 31A4H ; TT Data with auto increment (word)
158IDREG EQU 31A6H ; Bank ID register
159MODE_REG EQU 31A7H ; Mode register
160DMACAPT EQU 31A8H ; DMA capture register
161
162CR_ROMSLEEP_DIS EQU 11011111B ;XMA/A control register mask to
163 ; disable the ROM on XMA/A card
164XMA_TT_INHIBIT EQU 0000100000000000B ;XMA mask for an inhibitted TT entry
165XMA_TT_MASK EQU 0000111111111111B ;XMA mask for anding off unused bits
166EMUL_TTDATA_ON EQU 1000000000000000B ;XMA translate table data - mask for
167 ; the emulator. On XMA cards, data
168 ; is only 12 bits. On the emulator,
169 ; bit 15 turned on indicates data is
170 ; 15 bits. This allows the emulator
171 ; to use more than 8 Meg. Note that
172 ; both 0FFFh and FFFFh are inhibit.
173
174 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
175 ;³ MXO declares ³
176 ;³ ³
177 ;³ The MXO translate table is a 1K x 8 bit ³
178 ;³ array. A 10 bit address points to entries ³
179 ;³ in the TT. The data in the entry is: ³
180 ;³ ³
181 ;³ Bit Contents ³
182 ;³ 8 Inhibit bit (0 = inhibit xlate) ³
183 ;³ 7-0 Pointer to 16K block for up to ³
184 ;³ 2 meg capability ³
185 ;³ ³
186 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
187 ;All are byte ports
188H_CARD_INFO EQU 102H ;Info Bits 7-1 mem size Bit 0 sleep
189H_CC_PRES EQU 105H ;Channel check, presence (Bit 0)
190H_TTPTR_LO EQU 106H ;Translate table pointer low and
191H_TTPTR_HI EQU 107H ; high bytes
192H_TTDATA EQU 103H ;TT data - one byte. No auto inc.
193
194H_TT_INHIBIT EQU 00000000B ;MXO value for setting inhibitted
195 ; translate table entry
196H_TT_ENBMASK EQU 10000000B ;Pattern to test if TT entry read is
197 ; enabled. 'and' with entry,jz inhib
198
199 ;EMS ERROR CODES
200EMS_CODE80 EQU 80H ; Sotware malfunction
201EMS_CODE81 EQU 81H ; Hardware malfunction
202EMS_CODE82 EQU 82H ; This return code not used
203EMS_CODE83 EQU 83H ; Handle not found
204EMS_CODE84 EQU 84H ; Invalid function code
205EMS_CODE85 EQU 85H ; All handles used
206EMS_CODE86 EQU 86H ; Save or restore mapping error
207EMS_CODE87 EQU 87H ; Not enough pages to satisfy request
208EMS_CODE88 EQU 88H ; Not enough unallocated pages
209EMS_CODE89 EQU 89H ; Can't allocate zero pages
210EMS_CODE8A EQU 8AH ; Logical page out of range
211EMS_CODE8B EQU 8BH ; Physical page out of range
212EMS_CODE8C EQU 8CH ; Hardware save area is full
213EMS_CODE8D EQU 8DH ; Save area already saved for handle
214EMS_CODE8E EQU 8EH ; Save area not saved for this handle
215EMS_CODE8F EQU 8FH ; Subfunction parameter not defined
216;-------------------------------------------------------------------
217EMS_CODE91 EQU 091H
218EMS_CODE92 EQU 092H ; added for DMS ;an000;
219EMS_CODE93 EQU 093H ;an000;
220EMS_CODE94 EQU 094H ;an000;
221EMS_CODE95 EQU 095H ;an000;
222EMS_CODE96 EQU 096H ;an000;
223EMS_CODE97 EQU 097H ;an000;
224EMS_CODE98 EQU 098H ;an000;
225EMS_CODE9E EQU 09EH ;an000;
226EMS_CODE9C EQU 09CH ;an000;
227;------------------------------------------------------------------- ;an000;
228EMS_CODEA0 EQU 0A0h ; No matching handle
229EMS_CODEA1 EQU 0A1h ; Duplicate handle name
230EMS_CODEA2 EQU 0A2h ; Memory wrap error
231EMS_CODEA3 EQU 0A3h ; Data in control structure corrupted
232EMS_CODEA4 EQU 0A4h ; Access to this function denied
233
234;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
235;³ Request Header (Common portion) ³
236;³ ³
237;³ This structure defines the portion that is common to ³
238;³ all Request Headers. ³
239;³ ³
240;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
241RH EQU DS:[BX] ;addressability to Request Header structure
242
243RHC STRUC ;fields common to all request types
244 DB ? ;length of Request Header (including data)
245 DB ? ;unit code (subunit)
246RHC_CMD DB ? ;command code
247RHC_STA DW ? ;status
248 DQ ? ;reserved for DOS
249RHC ENDS ;end of common portion
250
251CMD_INPUT EQU 4 ;RHC_CMD is INPUT request
252
253;status values for RHC_STA
254
255STAT_GOOD EQU 0000H ;invalid command code error
256STAT_DONE EQU 0100H ;function complete status (OR on bit)
257STAT_CMDERR EQU 8003H ;invalid command code error
258STAT_CRC EQU 8004H ;CRC error
259STAT_SNF EQU 8008H ;sector not found error
260STAT_GENFAIL EQU 800CH ;general failure
261NOT_BUSY EQU 11111101B ;busy bit (9) NOT BUSY mask (high order byte)
262BUSY_MASK EQU 00000010B ;busy bit (9) BUSY mask (high order byte)
263
264;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
265;³ Request Header for INIT command ³
266;³ ³
267;³ This structure defines the Request Header for the ³
268;³ INIT command ³
269;³ ³
270;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
271RH0 STRUC
272 DB (TYPE RHC) DUP (?) ;common portion
273
274RH0_NUN DB ? ;number of units
275 ;set to 1 if installation succeeds,
276 ;set to 0 to cause installation failure
277RH0_ENDO DW ? ;offset of ending address
278RH0_ENDS DW ? ;segment of ending address
279RH0_BPBO DW ? ;offset of BPB array address
280RH0_BPBS DW ? ;segment of BPB array address
281RH0_DRIV DB ? ;drive code (DOS 3 only)
282RH0_ERR DW 0 ; error flag used by DOS - gga
283RH0 ENDS
284
285RH0_BPBA EQU DWORD PTR RH0_BPBO ;OFFSET/SEGMENT OF BPB
286;note RH0_BPBA at entry to init points to all after DEVICE= on CONFIG.SYS stmt
287
288;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
289;³ Request Header for OUTPUT STATUS command ³
290;³ ³
291;³ This structure defines the Request Header for the ³
292;³ Output Status command. ³
293;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
294RH10 STRUC
295 DB (TYPE RHC) DUP (?) ;common portion
296RH10 ENDS
297
298
299;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
300;³ Request Header for Generic IOCTL Request ³
301;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
302
303RH19 STRUC
304 DB (TYPE RHC) DUP (?) ; Reserve space for the header @RH6
305
306RH19_MAJF DB ? ; Major function @RH6
307RH19_MINF DB ? ; Minor function @RH6
308RH19_SI DW ? ; Contents of SI @RH6
309RH19_DI DW ? ; Contents of DI @RH6
310RH19_RQPK DD ? ; Pointer to Generic IOCTL request packet @RH6
311RH19 ENDS
312
313
314;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
315;³ Map EMS INT 67H vector in low storage ³
316;³ ³
317;³ The vector for the interrupt handler for INT 67H ³
318;³ is defined here. ³
319;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
320INT_VEC SEGMENT AT 00H
321 ORG 4*EMS_INT
322EMS_VEC LABEL DWORD
323EMS_VECO DW ? ;offset
324EMS_VECS DW ? ;segment
325INT_VEC ENDS
326
327;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
328;³ Map EM INT 15H vector in low storage ³
329;³ ³
330;³ The vector for the extended memory interrupt handler INT 15h ³
331;³ is defined here. ³
332;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
333INT_VEC15 SEGMENT AT 00H ;an000; dms;
334 ORG 4*EM_INT ;an000; dms;
335EM_VEC LABEL DWORD ;an000; dms;
336EM_VECO DW ? ;offset ;an000; dms;
337EM_VECS DW ? ;segment ;an000; dms;
338INT_VEC15 ENDS ;an000; dms;
339
340
341;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
342;³ Map INT 13h vector in low storage ³
343;³ ³
344;³ The vector for the disk access interrupt handler INT 13h ³
345;³ is defined here. ³
346;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
347INT_VEC13 SEGMENT AT 00H ;an004; dms;
348 ORG 4*DK_INT ;an004; dms;
349DK_VEC LABEL DWORD ;an004; dms;
350DK_VECO DW ? ;offset ;an004; dms;
351DK_VECS DW ? ;segment ;an004; dms;
352INT_VEC13 ENDS ;an004; dms;
353
354;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
355;º This marks the start of the device driver code segment º
356;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
357
358CSEG SEGMENT PARA PUBLIC 'CODE'
359 ASSUME CS:CSEG
360
361START EQU $ ;begin resident XMA2EMS data & code
362
363;DEVICE HEADER - must be at offset zero within device driver
364 DD -1 ;becomes pointer to next device header
365 DW 0C040H ;attribute (character device)
366 DW OFFSET STRATEGY ;pointer to device "strategy" routine
367 DW OFFSET IRPT ;pointer to device "interrupt handler"
368 DB 'EMMXXXX0' ;device name
369
370
371;-----------------------------------------------------------------------;
372; The next word is used to inform the 3270 Workstation Program ;
373; which 4K block in XMA marks the start of EMS Expanded Memory. ;
374;-----------------------------------------------------------------------;
375EMS_START_IN_XMA DW 0 ;initially, memory manager uses all
376
377;-----------------------------------------------------------------------;
378; The following is the Code Label:
379;-----------------------------------------------------------------------;
380COPYRIGHT DB '74X9921 (C)COPYRIGHT 1988 Microsoft '
381 DB 'LEVEL 1.00 LICENSED MATERIAL - PROGRAM '
382 DB 'PROPERTY OF Microsoft '
383
384;-----------------------------------------------------------------------;
385; Request Header (RH) address, saved here by "strategy" routine ;
386;-----------------------------------------------------------------------;
387RH_PTRA LABEL DWORD
388RH_PTRO DW ? ;offset
389RH_PTRS DW ? ;segment
390 db 7 dup(0) ;align following tables on seg.
391
392;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
393;³ HANDLE LOOKUP TABLE ³
394;³ ³
395;³ This table keeps track of EMS handles and pages assigned ³
396;³ to each handle. An entry exists for each of the 64 handles ³
397;³ supported. If the handle is active, the first field will ³
398;³ contain the number of pages it owns. Otherwise, the field ³
399;³ will indicate the handle is free. The second field is a head ³
400;³ pointer to the handle's pages in the linked Page Allocation List. ³
401;³ ³
402;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
403H_LOOKUP_STRUC STRUC ;Structure for Handle lookup table @RH1
404H_PAGES DW REUSABLE_HANDLE ;If handle is active, # of owned @RH8
405 ; pages. Init to reusable handle RH8
406H_PAL_PTR DW PAL_NULL ;Head ptr for owned pages in PAL @RH8
407H_NAME DB 8 DUP(0) ;Name - new for LIM 4.0 @GGA
408H_BANK DB 0 ;If virtual, this handle's bank @RH6
409xref_pages dw 0 ;temp to compile
410xref_index dw 0 ;temp to compile
411H_LOOKUP_STRUC ENDS
412
413NUM_HANDLES EQU 64 ;One structure @RH1
414HANDLE_LOOKUP_TABLE H_LOOKUP_STRUC <0,,,,,> ; initialize handle 0
415 H_LOOKUP_STRUC NUM_HANDLES-1 DUP (<>) ; for OS use - gga
416
417;-----------------------------------------------------------------------;
418; HANDLE CROSS REFERENCE (XREF) TABLE ;
419; Each entry in the Handle_Xref_Table points to a corresponding ;
420; page in the page allocation table. Entries in the XREF table ;
421; are contiguous for a handle, while PAT entries may not be. ;
422;-----------------------------------------------------------------------;
423XREF_TABLE_LEN EQU 2048 ; @RH1
424
425HANDLE_XREF_TABLE DW XREF_TABLE_LEN DUP(0) ; Changed from byte to @RH1
426 ; word table @RH1
427XREF_TABLE_END EQU ($) ;Used for table shift on deallocate @RH1
428;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
429;³ PAGE ALLOCATION LIST ³
430;³ ³
431;³ This is the structure pointed to by the handle lookup table. ³
432;³ The Page Allocation list is a linked list governing EMS pages. ³
433;³ Each 16KB EMS page has an entry in the PAGE_ALLOC_LIST. ³
434;³ The entries correspond to the physical blocks on the extended ³
435;³ memory cards (ex. the first 2 Meg card in a system will use the ³
436;³ first 128 entries in the PAL). ³
437;³ At initialization time, a 'free' pointer will point to the last³
438;³ (top) page in the PAL, and all entries will be linked from top ³
439;³ down. Whenever pages are allocated they are retreived from the ³
440;³ free chain, and deallocated pages are placed back on the free ³
441;³ chain. ³
442;³ ³
443;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
444EMS_PAGES_SUPPORTED EQU 1024 ;Support up to 16 Megabytes of EMS @RH8
445
446PAGE_ALLOC_LIST DW EMS_PAGES_SUPPORTED DUP(0)
447 ;Page Allocation List (PAL) @RH8
448page_alloc_table db 1024 dup(unallocated) ;temp for assemble
449;-----------------------------------------------------------------------;
450; HANDLE SAVE AREA ;
451; Each handle has 4 entries where the page frame map can ;
452; be stored. Each entry contains a word for the handle and ;
453; a word for the logical page active there. If no save has ;
454; occurred for a handle, then the logical page field in the ;
455; save area will contain a value indicating it's reusable. ;
456;-----------------------------------------------------------------------;
457H_SAVEA_ENTRY STRUC ;This is an overlay for one page's @RH5
458HSA_HNDL DW ? ; entry in the handle save area. @RH5
459HSA_LP DW ? ; It is used to clear the save @RH5
460H_SAVEA_ENTRY ENDS ; area after a restore. While not @RH5
461 ; directly used by the structure @RH5
462 ; below, its size should match @RH5
463 ; that for one page entry @RH5
464
465H_SAVE_STRUC STRUC ;Structure for Handle Save Area @RH1
466PG0_HNDL DW 0
467PG0_LP DW REUSABLE_SAVEA
468PG1_HNDL DW 0
469PG1_LP DW REUSABLE_SAVEA
470PG2_HNDL DW 0
471PG2_LP DW REUSABLE_SAVEA
472PG3_HNDL DW 0
473PG3_LP DW REUSABLE_SAVEA
474PGFE_HNDL DW 0 ;AN006;
475PGFE_LP DW REUSABLE_SAVEA ;AN006;
476PGFF_HNDL DW 0 ;AN006;
477PGFF_LP DW REUSABLE_SAVEA ;AN006;
478H_SAVE_STRUC ENDS
479
480HANDLE_SAVE_AREA H_SAVE_STRUC NUM_HANDLES DUP (<>)
481 ;One structure for each handle @RH1
482
483H_SAVE_ENTRY EQU WORD PTR[DI + OFFSET HANDLE_SAVE_AREA] ; @RH1
484
485
486;-------------------------------------------------------------------
487;
488; mappable_phys_page table
489;
490; This table is used by function 5800h
491;
492;-------------------------------------------------------------------
493
494mappable_phys_page_struct STRUC ; define the structure
495 phys_page_segment dw ? ; segment
496 phys_page_number dw ? ; page ID
497 ppm_handle dw ? ; handle, -1 means unused
498 ppm_log_page dw ? ; logical page, -1 means unused
499mappable_phys_page_struct ENDS
500
501; allocate the storage
502
503map_table mappable_phys_page_struct <-1, -1, -1, -1> ;p0 no default
504 mappable_phys_page_struct <-1, -1, -1, -1> ;p1 no default
505 mappable_phys_page_struct <-1, -1, -1, -1> ;p2 no default
506 mappable_phys_page_struct <-1, -1, -1, -1> ;p3 no default
507 mappable_phys_page_struct <-1, -1, -1, -1> ;p254 no default
508 mappable_phys_page_struct <-1, -1, -1, -1> ;p255 no default
509
510map_count_def equ 6 ; default 6
511map_count dw 0 ;
512map_size dw type mappable_phys_page_struct * map_count_def ; size of default table
513ppm_size equ 6 ;size of partial page map entry
514
515; flags and a word used in setting up map_table stuff, see parmpars.inc
516
517p0_flag equ 0001h ; flags used to indicate which p's were
518p1_flag equ 0002h ; set on command line
519p2_flag equ 0004h
520p3_flag equ 0008h
521p254_flag equ 0010h
522p255_flag equ 0020h
523frame_flag equ 8000h ; special flag used when FRAME= was found
524
525page_flags dw 0 ; word of above flags used in setting map_table
526parse_flag dw 0 ; flag used to indicate command line args were encountered
527
528;-------------------------------------------------------------------
529; rom scan stuff
530;-------------------------------------------------------------------
531family1 equ 1
532micro_channel equ 2
533
534
535rom_scan_type dw micro_channel ;
536segment_error dw 0 ; segment error flag = 0 means all OK
537
538;-----------------------------------------------------------------------
539; Tables added for multicard support º
540; º
541; These tables manage the mapping of multiple memory cards º
542; on a PS/2 Model 50 and 60. These systems may have a combination º
543; of MXO and XMA/A cards. The model 80 is excluded, since º
544; it uses the XMA emulator. º
545; º
546;-----------------------------------------------------------------------
547 ;-----------------------------------------------
548 ; Memory Card Descriptor Table º
549 ;-----------------------------------------------
550
551MEM_CARD_STRUC STRUC ;Structure for the memory cards @RH5
552CARD_ID DW NO_CARD ;Card ID from ports 100 and 101 @RH5
553CARD_SLOT DB ? ;Physical slot of card (0 based) @RH5
554START_PG_NUM DW ? ;Starting and ending #s of the @RH5
555END_PG_NUM DW ? ; pages this card has within the @RH5
556MEM_CARD_STRUC ENDS ; total EMS page pool (0 based) @RH5
557
558 ;Memory Card Table - entries are @RH5
559 ; filled in ascending order (from @RH5
560 ; slot 0) for each card found. @RH5
561 ; MXOs scanned 1st, then XMA/A @RH5
562MAX_SLOTS EQU 8 ;Max of 8, but most @RH5
563MEM_CARD_TABLE MEM_CARD_STRUC MAX_SLOTS DUP (<>) ; likely 1 or 2 cards @RH5
564
565 ;-----------------------------------------------
566 ; Multicard Page Frame Descriptor Table º
567 ;-----------------------------------------------
568MULTIC_PM_STRUC STRUC ;Structure for storing the card ID @RH5
569PG_CARD DW NO_CARD ; and slot of the card currently @RH5
570PG_SLOT DB 0 ; mapped to this page of the page @RH5
571MULTIC_PM_STRUC ENDS ; frame @RH5
572
573 ;Multicard Page Mapping Table.
574 ; Entry for each page of the page
575 ; frame (including pages FE & FF)
576MC_PM_TABLE MULTIC_PM_STRUC MAP_COUNT_DEF DUP (<>)
577
578 ;-----------------------------------------------
579 ; Assorted Multicard declares º
580 ;-----------------------------------------------
581NUM_MEM_CARDS DW 0
582NUM_OF_SLOTS DB ? ;Number of adapter slots RR 8 TB 4 @RH2
583WTT_CARD_SLOT DB ? ;Slot # of the memory card being @RH2
584 ; used to map a page @RH2
585
586
587Instance_Entry_Struc struc ;required data in first 2 entries ;an000; dms;
588 IE_Alloc_Byte db ? ;instance allocated byte ;an000; dms;
589 IE_Saved_DI_Reg dw ? ;saved di register ;an000; dms;
590Instance_Entry_Struc ends ;end struc ;an000; dms;
591
592;-----------------------------------------------------------------------;
593; Table of DOS command processing routine entry points ;
594; ;
595; An '*' in the comment area indicates the command is handled ;
596; by meaningful code. All other commands simply set a good ;
597; return code and exit back to DOS. ;
598;-----------------------------------------------------------------------;
599CMD_TABLE LABEL WORD
600 DW OFFSET INIT ; 0 - *Initialization
601 DW OFFSET MEDIA_CHECK ; 1 - Media check
602 DW OFFSET BLD_BPB ; 2 - Build BPB
603 DW OFFSET INPUT_IOCTL ; 3 - IOCTL input
604 DW OFFSET INPUT ; 4 - Input
605 DW OFFSET INPUT_NOWAIT ; 5 - Non destructive input no wait
606 DW OFFSET INPUT_STATUS ; 6 - Input status
607 DW OFFSET INPUT_FLUSH ; 7 - Input flush
608 DW OFFSET OUTPUT ; 8 - Output
609 DW OFFSET OUTPUT_VERIFY ; 9 - Output with verify
610 DW OFFSET OUTPUT_STATUS ;10 - *Output status
611 DW OFFSET OUTPUT_FLUSH ;11 - Output flush
612 DW OFFSET OUTPUT_IOCTL ;12 - IOCTL output
613 DW OFFSET DEVICE_OPEN ;13 - Device OPEN
614 DW OFFSET DEVICE_CLOSE ;14 - Device CLOSE
615 DW OFFSET REMOVABLE_MEDIA ;15 - Removable media
616 DW OFFSET INVALID_FCN ;16 - Invalid IOCTL function gga ;AN003;
617 DW OFFSET INVALID_FCN ;17 - Invalid IOCTL function gga ;AN003;
618 DW OFFSET INVALID_FCN ;18 - Invalid IOCTL function gga ;AN003;
619 DW OFFSET GENERIC_IOCTL ;19 - *Generic IOCTL function gga ;AN003;
620 DW OFFSET INVALID_FCN ;20 - Invalid IOCTL function gga ;AN003;
621 DW OFFSET INVALID_FCN ;21 - Invalid IOCTL function gga ;AN003;
622 DW OFFSET INVALID_FCN ;22 - Invalid IOCTL function gga ;AN003;
623 DW OFFSET GET_LOG_DEVICE ;23 - Invalid IOCTL function gga ;AN003;
624MAX_CMD EQU ($-CMD_TABLE)/2 ;highest valid command follows
625 DW OFFSET SET_LOG_DEVICE ;24 - Invalid IOCTL function gga ;AN003;
626
627;-----------------------------------------------------------------------;
628; Table of Expanded Memory Manager routine entry points ;
629;-----------------------------------------------------------------------;
630FCN_TABLE LABEL WORD
631 DW OFFSET EMM_STATUS ;40 - Get status of memory manager
632 DW OFFSET Q_PAGE_FRAME ;41 - Get segment of page frame
633 DW OFFSET Q_PAGES ;42 - Get number of alloc & unalloc pgs
634 DW OFFSET GET_HANDLE ;43 - Request ID and allocate n pages
635 DW OFFSET MAP_L_TO_P ;44 - Map logical to physical page
636 DW OFFSET DE_ALLOCATE ;45 - Deallocate all pages of ID n
637 DW OFFSET Q_VERSION ;46 - Get version number
638 DW OFFSET SAVE_MAP ;47 - Save mapping array
639 DW OFFSET RESTORE_MAP ;48 - Restore mapping array
640 DW OFFSET GET_PORT_ARRAY ;49 - Get I/O port array
641 DW OFFSET GET_L_TO_P ;4A - Get logical to physical array
642 DW OFFSET Q_OPEN ;4B - Get number of open ID's
643 DW OFFSET Q_ALLOCATE ;4C - Get pages allocated to ID n
644 DW OFFSET Q_OPEN_ALL ;4D - Get all ID's and pages allocated
645 DW OFFSET GET_SET_MAP ;4E - Group of subfunctions that Get
646 ;and/or Set the page map
647
648;------------------------------------------------------------------- ;GGA
649; these functions were added for LIM 4.0 support ;GGA
650;------------------------------------------------------------------- ;GGA
651 ;GGA
652 dw offset partial_map ; 4F - get/set partial page map ;GGA
653 dw offset map_mult ; 50 - map/unmap multiple handle pages ;GGA
654 dw offset reallocate ; 51 - reallocate pages ;GGA
655 dw offset handle_attrib ; 52 - get/set handle attributes ;GGA
656 dw offset handle_name ; 53 - get/set handle name ;GGA
657 dw offset handle_dir ; 54 - get handle directory ;GGA
658 dw offset alter_and_jump ; 55 - alter page map and jump ;GGA
659 dw offset alter_and_call ; 56 - alter page map and call ;GGA
660 dw offset exchng_region ; 57 - move/exchange memory region ;GGA
661 dw offset address_array ; 58 - Get mappable physical address array ;GGA
662 dw offset hardware_info ; 59 - Get extended momory hardware information ;GGA
663 dw offset alloc_raw ; 5A - allocate raw pages ;GGA
664 dw offset alternate_map ; 5B - alternate map register set ;GGA
665 dw offset prepare_boot ; 5C - Prepare for WarmBoot ;GGA
666MAX_FCN EQU ($-FCN_TABLE)/2 ; highest valid command follows ;GGA
667 dw offset enable_os ; 5D - enable/disable OS/E functions ;GGA
668
669;-----------------------------------------------------------------------;
670; Data variables go here ;
671;-----------------------------------------------------------------------;
672PAGE_FRAME_STA DW 0D000H ;STARTING SEG OF PAGE FRAME
673TOTAL_SYS_PAGES DW 1024/16 ;Total number of 16k pages on the
674 ; memory card(s) that are initially
675 ; expanded memory. On PS/2 50 + 60,
676 ; pages used as extended are subtracted.
677TOTAL_EMS_PAGES DW 1024/16 ;Pages left after conventional
678 ; memory is backed
679FREE_PAGES DW 1024/16 ;Total unallocated pages for EMS use
680EM_Ksize dw ? ;size in Kb of extended memory ;an000; dms;
681CARD_STATUS DW 'OK' ;STATUS OF THE HARDWARE
682 ; DEFAULT='OK' FAILURE='HW'
683MANAGER_STATUS DW 'OK' ;STATUS OF THE MEMORY MANAGER
684 ; DEFAULT='OK' FAILURE='SW'
685STARTING_BLOCK DW 0 ;number of 4K blocks reserved by pinta
686OVERFLOW DB 0
687WARM_START DB 'N' ;initially not a warm start
688MULTIPLIER DW ? ;Used for figuring table offsets @RH1
689TEN DW 10 ; via multiplication...not the @RH1
690SIXTEEN DW 16 ; most efficient, but flexible @RH1
691MEMCARD_MODE DB XMA1_VIRT ;Flag indicating the type of memory@RH2
692 ; card being used. Default to @RH2
693 ; XMA 1 card.
694BANKID DB ? ;Current XMA Bank ID @RH1
695BLOCKS_PER_PAGE DW 4 ;XMA blocks per EMS page (multiply)@RH1
696SEG_PER_PAGE DW 1024 ;Segments(16 bytes) per EMS page @RH1
697
698INTV15 LABEL DWORD ;an000; dms;
699INTV15O DW ? ;offset ;an000; dms;
700INTV15S DW ? ;segment ;an000; dms;
701
702INTV13 LABEL DWORD ;an004; dms;
703INTV13O DW ? ;offset ;an004; dms;
704INTV13S DW ? ;segment ;an004; dms;
705
706PAL_FREE_PTR DW PAL_NULL
707;-------------------------------------------------------------------
708; define some flags and storage for the enable/disable functions
709;-------------------------------------------------------------------
710
711ose_enabled equ 1 ; flags used to enable/disable OS/E fcns ;an000;
712ose_disabled equ 0 ;an000;
713
714access_code dd 0 ; access code used by OS/E functions ;an000;
715ose_functions dw ose_enabled ; OS/E functions 1 = enabled, 0 = disabled ;an000;
716
717;-------------------------------------------------------------------
718; define some storage for the ROM scan logic
719;-------------------------------------------------------------------
720where_to_start dw 0a000h ; start ROM scan at A000
721
722
723;-----------------------------------------------------------------------;
724; INT 15H Interrupt Handler routine ;
725;-----------------------------------------------------------------------;
726
727;=========================================================================
728; XMA_INT15 : This routine traps the INT 15h requests to perform its
729; own unique services. This routine provides 1 INT 15h
730; service; function 8800h.
731;
732; Service - Function 8800h: Obtains the size of EM from the word
733; value EM_KSize
734; Call With: AX - 8800h
735; Returns : AX - Kbyte size of EM
736;
737;=========================================================================
738XMA_INT15 PROC ;an000; dms;
739
740 cmp ah,EM_Size_Get ;an000; dms;function 88h?
741 jne XMA_INT15_Jump ;an000; dms;no - jump to old INT 15h
742 mov ax,cs:EM_KSize ;an000; dms;return size
743 clc ;an000; dms;clear CY
744 jmp XMA_INT15_Exit ;an000; dms;exit handler
745
746XMA_INT15_Jump: ;an000; dms;
747
748 jmp cs:INTV15 ;an000; dms;jump to org. vector
749
750XMA_INT15_Exit: ;an000; dms;
751
752
753 iret ;an000; dms;
754
755XMA_INT15 ENDP ;an000; dms;
756
757include I13HOOK.INC ;an004; dms;
758
759
760;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
761;º Device "strategy" entry point º
762;º º
763;º Retain the Request Header address for use by Interrupt routine º
764;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
765STRATEGY PROC FAR
766 MOV CS:RH_PTRO,BX ;offset
767 MOV CS:RH_PTRS,ES ;segment
768 RET
769STRATEGY ENDP
770
771
772;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
773;º DOS Device "interrupt" entry point º
774;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
775IRPT PROC FAR ;device interrupt entry point
776 PUSH DS ;save all registers Revised
777 PUSH ES
778 PUSH AX
779 PUSH BX
780 PUSH CX
781 PUSH DX
782 PUSH DI
783 PUSH SI
784 ;BP isn't used, so it isn't saved
785 CLD ;all moves forward
786
787 LDS BX,CS:RH_PTRA ;get RH address passed to "strategy" into DS:BX
788
789 MOV AL,RH.RHC_CMD ;command code from Request Header
790 CBW ;zero AH (if AL > 7FH, next compare will
791 ;catch that error)
792
793 CMP AL,MAX_CMD ;if command code is not too high
794 JNA IRPT_CMD_OK ; then handle the command
795 MOV RH.RHC_STA,STAT_CMDERR ;"invalid command" and error
796 JMP IRPT_CMD_EXIT
797
798IRPT_CMD_OK:
799 MOV RH.RHC_STA,STAT_GOOD ;initialize return to "no error"
800
801 ADD AX,AX ;double command code for table offset
802 MOV DI,AX ;put into index register for JMP
803
804;At entry to command processing routine:
805; DS:BX = Request Header address
806; CS = VDISK code segment address
807; AX = 0
808
809 CALL CS:CMD_TABLE[DI] ;call routine to handle the command
810
811
812IRPT_CMD_EXIT: ;return from command routine
813 ;AX = value to OR into status word
814 LDS BX,CS:RH_PTRA ;restore DS:BX as Request Header pointer
815 OR RH.RHC_STA,STAT_DONE ;add "done" bit to status word
816 POP SI ;restore registers
817 POP DI
818 POP DX
819 POP CX
820 POP BX
821 POP AX
822 POP ES
823 POP DS
824
825 RET ;far return back to DOS
826IRPT ENDP
827
828include genioctl.inc ; include code for genioctl fcn gga
829
830;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
831;º Set 'OUTPUT STATUS' entry point º
832;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
833OUTPUT_STATUS PROC ;Output status
834 LDS BX,CS:RH_PTRA ;DS:BX as pointer to request header
835 MOV AX,RH.RHC_STA ;get status word
836OS1:
837 AND AH,NOT_BUSY ;turn off busy bit
838OS2:
839 MOV RH.RHC_STA,AX ;write it back to request header
840 RET
841OUTPUT_STATUS ENDP
842
843
844IGNORED_CMDS PROC
845IRPT_CMD_ERROR: ;CALLed for unsupported character mode commands
846
847MEDIA_CHECK: ;Media check
848BLD_BPB: ;Build BPB
849INPUT_IOCTL: ;IOCTL input
850INPUT: ;Input
851INPUT_NOWAIT: ;Non destructive input no wait
852INPUT_STATUS: ;Input status
853INPUT_FLUSH: ;Input flush
854OUTPUT: ;Output
855OUTPUT_VERIFY: ;Output with verify
856OUTPUT_FLUSH: ;Output flush
857OUTPUT_IOCTL: ;IOCTL output
858DEVICE_OPEN: ;Device OPEN
859DEVICE_CLOSE: ;Device CLOSE
860REMOVABLE_MEDIA: ;Removable media
861INVALID_FCN: ; invalid IOCTL function ;AN003;
862GET_LOG_DEVICE: ; get logical device ;AN003;
863SET_LOG_DEVICE: ; set logical device ;AN003;
864 RET
865IGNORED_CMDS ENDP
866
867
868
869;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
870;º Entry point for EMM interrupt handler º
871;º º
872;º º
873;º The interrupt vector 67H points here. º
874;º º
875;º On Entry: º
876;º The AH register contains the function number and the º
877;º necessary parameters are passed in registers defined º
878;º by the Expanded Memory Specification. º
879;º º
880;º On Exit: º
881;º (AH) = 0 if no error º
882;º (AH) = error # if error º
883;º º
884;º other register contain information as specified by EMSº
885;º otherwise all registers remain unchanged º
886;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
887EMS_INT67 PROC
888 push bp ;save instance pointer ;an000; dms;
889 call Set_Instance ;set BP to proper instance entry ;an000; dms;
890 jc INT67_Instance_Exit ;not enough instances ;an000; dms;
891
892 mov cs:[bp].IE_Saved_DI_Reg,di ;save reg in instance table ;an000; dms;
893
894
895 SUB AH,40H ;adjust to range of fcn table
896 CMP AH,0 ;too low?
897; $IF GE,AND
898 JNGE $$IF1
899 CMP AH,MAX_FCN ;too high?
900; $IF LE
901 JNLE $$IF1
902 MOV DI,OFFSET INT67_EXIT ;get common exit addr
903 PUSH DI ;put it on stack
904 PUSH AX ;save ax...al may contain parms
905 XCHG AH,AL ;adjust
906 XOR AH,AH ; for ax
907 ADD AX,AX ; to be offset into table
908 MOV DI,AX ;use di for index into table
909 POP AX ;recover ax ... parms in al
910;At entry to function handler:
911; CS = INT67 code segment
912; TOP OF STACK is return address, INT67_EXIT
913
914 JMP CS:FCN_TABLE[DI] ;call routine handler
915; $ENDIF
916$$IF1:
917 MOV AH,EMS_CODE84 ;function call out of range
918
919
920
921INT67_EXIT:
922
923 mov di,cs:[bp].IE_Saved_DI_Reg ;save reg in instance table ;an000; dms;
924 call Reset_Instance ;deallocte instance entry ;an000; dms;
925
926INT67_Instance_Exit:
927
928 pop bp ;restore instance pointer ;an000; dms;
929
930 IRET ;end of interrupt 67
931EMS_INT67 ENDP
932
933
934
935;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
936;º Entry point for EMM STATUS Function 1 º
937;º º
938;º on entry: (AH) = '40'x º
939;º º
940;º on exit: (AH) = status º
941;º all other registers preserved º
942;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
943EMM_STATUS PROC
944 CMP MANAGER_STATUS,SW_ERROR ;is manager ok?
945; $IF E ;if no then
946 JNE $$IF3
947 MOV AH,EMS_CODE80 ;indicate bad status
948 JMP ST1 ;exit
949; $ENDIF
950$$IF3:
951 CMP CARD_STATUS,HW_ERROR ;is card ok?
952; $IF E ;if no then
953 JNE $$IF5
954 MOV AH,EMS_CODE81 ;indicate bad status
955 JMP ST1 ;exit
956; $ENDIF
957$$IF5:
958 XOR AH,AH ;set good return status
959ST1:
960 RET ;return to caller
961EMM_STATUS ENDP
962
963
964;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
965;º Entry point for GET PAGE FRAME Function 2 º
966;º º
967;º on entry: (AH) = '41'x º
968;º º
969;º on exit: (AH) = status º
970;º (BX) = segment address of page frame º
971;º all other registers preserved º
972;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
973Q_PAGE_FRAME PROC
974 push cx ;save regs ;an000; dms;
975 push dx ; ;an000; dms;
976 push si ; ;an000; dms;
977
978 cmp cs:Map_Count,4 ;enough frames? ;an000; dms;
979 jb Q_Page_Frame_Error_Exit ;no - exit with error ;an000; dms;
980
981 mov cx,4h ;loop only 4 times ;an000; dms;
982 xor ax,ax ;page number reference ;an000; dms;
983 mov si,offset cs:Map_Table ;point to map table ;an000; dms;
984 mov bx,cs:[si].Phys_Page_Segment ;set start segment value ;an000; dms;
985 mov dx,bx ;segment reference ;an000; dms;
986
987Q_Page_Frame_Loop:
988
989 cmp cs:[si].Phys_Page_Number,ax ;page matches reference? ;an000; dms;
990 jne Q_Page_Frame_Error_Exit ;no - exit with error ;an000; dms;
991
992 cmp cs:[si].Phys_Page_Segment,dx ;page frame match reference ;an000; dms;
993 jne Q_Page_Frame_Error_Exit ;no - exit with error ;an000; dms;
994
995 add si,Type Mappable_Phys_Page_Struct;adjust pointer ;an000; dms;
996 add dx,400h ;next page frame ;an000; dms;
997 inc ax ;next page ;an000; dms;
998 loop Q_Page_Frame_Loop ;continue loop ;an000; dms;
999
1000 xor ah,ah ;set good return ;an000; dms;
1001 jmp Q_Page_Exit ;exit the routine ;an000; dms;
1002
1003Q_Page_Frame_Error_Exit:
1004
1005 mov ah,EMS_Code80 ;signal software error ;an000; dms;
1006
1007Q_Page_Exit:
1008
1009 pop si ;restore regs ;an000; dms;
1010 pop dx ; ;an000; dms;
1011 pop cx ; ;an000; dms;
1012
1013 RET
1014Q_PAGE_FRAME ENDP
1015
1016
1017;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
1018;º Entry point for QUERY TOTAL & UNALLOCATED PAGES Function 3 º
1019;º º
1020;º on entry: (AH) = '42'x º
1021;º º
1022;º on exit: (AH) = status º
1023;º (BX) = number of pages available in expanded memory º
1024;º (DX) = total number of pages in expanded memory º
1025;º all other registers preserved º
1026;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
1027Q_PAGES PROC
1028
1029 XOR AH,AH ;Init good return status
1030 MOV BX,CS:FREE_PAGES ;bx gets num unalloc pages
1031 MOV DX,CS:TOTAL_EMS_PAGES ;dx gets num total pages
1032 CMP BX,DX ;If unalloc <= total then OK
1033 JNA Q_PAGES_RET ;Otherwise sumptin's rong
1034 MOV AH,EMS_CODE81 ; set that return code
1035Q_PAGES_RET:
1036 RET
1037Q_PAGES ENDP
1038
1039
1040
1041;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
1042;º Entry point for GET HANDLE AND ALLOCATE Function 4 º
1043;º º
1044;º on entry: (AH) = '43'x º
1045;º (BX) = number of pages to allocate º
1046;º º
1047;º on exit: (AH) = status º
1048;º (DX) = handle º
1049;º AX,DX Revised...all other registers preserved º
1050;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
1051GET_HANDLE PROC
1052 PUSH BX
1053 PUSH CX
1054 PUSH DI
1055 PUSH SI
1056 PUSH DS ;save these registers
1057
1058 PUSH CS ;get cs
1059 POP DS ;into ds
1060
1061 ;Remove test for BX = 0. This is @RH4
1062 ; valid under LIM 4.0
1063
1064 cmp bx,0 ;0 page allocate is invalid ;an000; dms;
1065 jne GH_OKCount ;0 pages not requested ;an000; dms;
1066 mov ah,EMS_Code89 ;flag 0 pages requested ;an000; dms;
1067 jmp GH_Exit ;exit routine ;an000; dms;
1068
1069GH_OKCount:
1070
1071 CMP BX,TOTAL_EMS_PAGES ;Enough total EMS pages?
1072 JNA GH_OKTOTAL
1073 MOV AH,EMS_CODE87
1074 JMP GH_EXIT
1075
1076GH_OKTOTAL:
1077 cli ;ints off ;an000; dms;
1078 CMP BX,FREE_PAGES ;Enough unallocated pages?
1079 sti ;ints on ;an000; dms;
1080 JNA GH_OKFREE
1081 MOV AH,EMS_CODE88
1082 JMP GH_EXIT
1083 ;-----------------------------------------------------
1084 ; Search for a free handle @RH1 º
1085 ;-----------------------------------------------------
1086GH_OKFREE:
1087 MOV CX,NUM_HANDLES ;loop counter is #handles
1088 DEC CX ;handle 0 reserved for op. sys. @RH1
1089 MOV DX,1 ;handle assignment set to 1 @RH1
1090 MOV DI,TYPE H_LOOKUP_STRUC ;init table index to 1st entry @RH1
1091;--------------------------------
1092 CLI ;interrupts OFF during allocation
1093;--------------------------------
1094GH_FREEHSRCH:
1095 CMP HANDLE_LOOKUP_TABLE.H_PAGES[DI],REUSABLE_HANDLE
1096 ;Is this handle available? @RH1
1097 JE GH_HFREE ;yes end search dx=handle id @RH1
1098 INC DX ;next handle assignment
1099 ADD DI,TYPE H_LOOKUP_STRUC ;next entry in handle lookup @RH1
1100 ;repeat for all table entries
1101 LOOP GH_FREEHSRCH
1102 MOV AH,EMS_CODE85 ;no available handles
1103 JMP GH_EXIT ;go to exit ;GGA
1104
1105 ;-----------------------------------------------------
1106 ; If here then there's enough pages for request. @RH1 º
1107 ; DX = handle #, DI = ptr to hndl lookup entry @RH1 º
1108GH_HFREE:
1109
1110 MOV CX,NUM_HANDLES ;loop counter
1111 DEC CX ;handle 0 reserved for op. sys. @RH1
1112 ;si = index to hndl lookup tbl @RH1
1113 MOV SI,TYPE H_LOOKUP_STRUC ; for adding pages (skip 0 entry) @RH1
1114 XOR AX,AX ;clear page counter
1115 CLC ;clear carry for addition
1116GH_PAGESUM:
1117 CMP HANDLE_LOOKUP_TABLE.H_PAGES[SI],REUSABLE_HANDLE
1118 JE GH_PGSUM_BOT ;If handle is free don't add @RH4
1119 ADD AX,HANDLE_LOOKUP_TABLE.H_PAGES[SI]
1120 ;add lengths (pages) of PALs @RH1
1121 ADD SI,TYPE H_LOOKUP_STRUC ; next entry in handle lookup @RH1
1122GH_PGSUM_BOT:
1123 LOOP GH_PAGESUM
1124 CMP AX,TOTAL_EMS_PAGES ;pages in handle lookup > total? @RH1
1125 JNA GH_CALCHLUP ;no OK @RH1
1126 MOV AH,EMS_CODE80 ;software error..we screwed up @RH1
1127 JMP GH_EXIT ;go to exit @RH1 ;GGA
1128
1129GH_CALCHLUP: ;calculate entry in hndl lkup tbl @RH1
1130
1131 cli ;ints off ;an001; dms;
1132 mov cx,bx ;alloc count ;an000; dms;
1133 call EMS_Page_Contig_Chk ;do we have contig pgs. ;an001; dms;
1134 jnc GH_Alloc ;yes continue process ;an001; dms;
1135 mov ah,EMS_Code88 ;no signal error ;an001; dms;
1136 sti ;ints on ;an001; dms;
1137 jmp GH_Exit ;exit routine ;an001; dms;
1138
1139GH_Alloc:
1140
1141 call EMS_Link_Set ;set up links ;an001; dms;
1142
1143
1144 sub Free_Pages,bx ;free = free - requested pages
1145 mov Handle_LookUp_Table.H_Pages[di],bx ;page count ;an000; dms;
1146 mov Handle_LookUp_Table.H_Pal_Ptr[di],si ;initialize to ptr for ;ac001; dms;
1147 ; pages
1148 sti ;ints on ;an001; dms;
1149 xor ah,ah ;clear flag ;an000; dms;
1150
1151
1152GH_EXIT: ;GGA
1153
1154 POP DS
1155 POP SI
1156 POP DI
1157 POP CX
1158 POP BX
1159
1160 RET
1161GET_HANDLE ENDP
1162
1163
1164;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
1165;º Entry point for MAP LOGICAL TO PHYSICAL PAGE Function 5 º
1166;º º
1167;º on entry: (AH) = '44'x º
1168;º (AL) = physical page j º
1169;º (BX) = logical page i º
1170;º (DX) = handle º
1171;º º
1172;º on exit: (AH) = status º
1173;º all other registers preserved º
1174;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
1175
1176MAP_L_TO_P PROC
1177 PUSH BX
1178 PUSH CX
1179 PUSH DX
1180 PUSH DI
1181 PUSH SI
1182 PUSH DS ;save these registers
1183 PUSH CS ;get cs
1184 POP DS ;into ds
1185
1186 CMP BX,PAGE_INHIBITTED ;If the log pg = inhibit, ignore @RH4
1187 JNE MLP_HANDLE_CHK ; checking handle ID. Restore PF @RH4
1188 MOV SI,BX ; calls this proc, and a saved pg @RH4
1189 JMP SHORT MLP_GET_SEG ; that has never been mapped will @RH4
1190 ; have no handle ID @RH4
1191
1192MLP_HANDLE_CHK:
1193 CMP DX,NUM_HANDLES-1 ;handle within range ?
1194 JBE MLP_DXINRANGE
1195 MOV AH,EMS_CODE83 ;handle not found
1196 JMP MLP_EXIT ;exit
1197MLP_DXINRANGE:
1198 push ax ;save affected regs ;an000; dms;
1199 push dx ; ;an000; dms;
1200 MOV AX,DX ; (DX:AX used in MUL @RH1
1201 MOV DX,TYPE H_LOOKUP_STRUC ;SI = entry's offset into @RH8
1202 MUL DX ; the handle lookup table @RH8
1203 MOV SI,AX ; @RH1
1204 pop dx ;restore affected regs ;an000; dms;
1205 pop ax ; ;an000; dms;
1206
1207 MOV CX,HANDLE_LOOKUP_TABLE.H_PAGES[SI] ;CX = handle's pages @RH8
1208 CMP CX,REUSABLE_HANDLE ;Handle have pages?
1209 JNE MLP_DXHASPAGES ;Yes next check
1210 MOV AH,EMS_CODE83 ;No handle not used
1211 JMP MLP_EXIT ; set error and exit
1212MLP_DXHASPAGES:
1213 CMP BX,TOTAL_EMS_PAGES ;Logical pg requested (0 based) @RH1
1214 JB MLP_BX_LE_TOT ; less than or = to total pages? @RH1
1215 MOV AH,EMS_CODE8A ;No... logical page out of range
1216 JMP MLP_EXIT ;exit
1217MLP_BX_LE_TOT:
1218 CMP BX,CX ;Logical page requested <= number @RH1
1219 JB MLP_LP_OK ; of pages for this handle?
1220 MOV AH,EMS_CODE8A ;No...error log. page out of range @RH1
1221 JMP MLP_EXIT ;exit
1222 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1223 ;³ Convert handle's logical page to ³
1224 ;³ relative page in the EMS pool (SI) ³
1225 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1226MLP_LP_OK: ;Get this handle's @RH8
1227 MOV DI,HANDLE_LOOKUP_TABLE.H_PAL_PTR[SI] ; head index to PAL @RH8
1228 CMP BX,0 ;If 1st pg wanted @RH8
1229 JE MLP_GOT_PHYS_PG ; then we've got it @RH8
1230 MOV CX,BX ;Else scan linked PAL@RH8
1231 ; for log pg - 1. @RH8
1232MLP_SCAN_PAL: ; (log p is 0 based) @RH8
1233 SHL DI,1 ;2 bytes per PAL ent
1234 ; mult is slow here
1235 MOV DI,PAGE_ALLOC_LIST[DI] ; This loop will get @RH8
1236 LOOP MLP_SCAN_PAL ; the index of the @RH8
1237MLP_GOT_PHYS_PG: ; desired page @RH8
1238 MOV SI,DI ;SI = page on card @RH8
1239
1240
1241
1242
1243 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1244 ;³ Get seg addr of the phys page (DI) ³
1245MLP_GET_SEG: ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1246 XOR DI,DI ;Clear offset into mappable phys. @RH4
1247 MOV CX,MAP_COUNT ; page table. Loop for # entries. @RH4
1248MLP_PP_CHECK:
1249 CMP AL,BYTE PTR MAP_TABLE.PHYS_PAGE_NUMBER[DI] ;AX = table pp? @RH4
1250 JE MLP_PP_OK ;Yes..get seg @RH4
1251 ADD DI,TYPE MAPPABLE_PHYS_PAGE_STRUCT ;No..check next @RH4
1252 LOOP MLP_PP_CHECK ; table entry @RH4
1253 MOV AH,EMS_CODE8B ;If here physical page not found @RH1
1254 JMP MLP_EXIT ; in mappable phys pg table..Error @RH1
1255MLP_PP_OK:
1256 MOV MAP_TABLE.PPM_LOG_PAGE[DI],BX ;Place the logical pg @RH4
1257 MOV MAP_TABLE.PPM_HANDLE[DI],DX ; the mappable pp table @RH4
1258 MOV DI,MAP_TABLE.PHYS_PAGE_SEGMENT[DI] ;DI= page's PC seg addr @RH1
1259
1260 ;-------------------------------------
1261 ; Map L to P depending on memory card º
1262 ;-------------------------------------
1263MLP_VIRTUAL:
1264 TEST MEMCARD_MODE,WSP_VIRT ;Using either an XMA 1, XMA/A, or @RH2
1265 JZ MLP_MC_TEST ; XMA Emulator in virtual mode? @RH2
1266 CALL W_EMSPG_XVIRT ;Yes..Map one logical page to
1267 JMP MLP_GOODRC ; physical page using 310X regs
1268 ;Else not virtual...use real mode
1269MLP_MC_TEST: ;If system has multiple cards, @RH5
1270 CMP NUM_MEM_CARDS,1 ; then adjust absolute EMS page to @RH5
1271 JNA MLP_REAL ; its corresponding page on the @RH5
1272 CALL MLP_MCARD_SETUP ; card to be used @RH5
1273MLP_REAL:
1274 CMP MEMCARD_MODE,XMAA_REAL ;XMA/A card (on PS/2 mod 50 or 60) @RH3
1275 JNE MLP_HLST ; in real mode (WSP not loaded)? @RH3
1276 CALL W_EMSPG_XREAL ;Map one logical page to physical @RH2
1277 JMP MLP_GOODRC
1278MLP_HLST: ;If not XMA then MXO
1279 CALL W_EMSPG_HLST ;Map one logical page to physical @RH3
1280MLP_GOODRC:
1281 XOR AH,AH ;Good return status..mapping
1282 ; should always be successful
1283MLP_EXIT:
1284
1285 POP DS ;restore these registers
1286 POP SI
1287 POP DI
1288 POP DX
1289 POP CX
1290 POP BX
1291
1292 RET
1293MAP_L_TO_P ENDP
1294
1295
1296
1297
1298
1299;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1300;³ Subroutine: WRITE TRANSLATE TABLE FOR EMS PAGE ³
1301;³ XMA VIRTUAL MODE ³
1302;³ ³
1303;³ This routine will write the Translate Table so that the ³
1304;³ specified 16K page of 'real' address will be mapped to a ³
1305;³ specified 16K page of XMA physical memory. ³
1306;³ This routine is called if the XMA card is in 'virtual' ³
1307;³ mode - i.e. bank swapping is active. The 16 bit 31AX ports ³
1308;³ are used for setting up the XMA translate table. ³
1309;³ The XMA 1 card and XMA emulator are always in virtual ³
1310;³ mode. The XMA\A card is in virtual mode if bank switching ³
1311;³ is active (used by the 3270 Workstation Program). ³
1312;³ ³
1313;³ On entry: (DI) is starting segment in PC address space. ³
1314;³ Must be on 4K boundary else is rounded ³
1315;³ down to the nearest 4K. ³
1316;³ (SI) absolute EMS page number (not handle relative) RH4³
1317;³ or FFFFh if page is to be inhibitted RH4³
1318;³ ³
1319;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1320
1321W_EMSPG_XVIRT PROC
1322 MOV DX,IDREG ;Save the current bank ID @RH1
1323 IN AL,DX ; (bank of the requestor). Write @RH1
1324 MOV BANKID,AL ; to the trans. table for this bank@RH1
1325
1326 MOV AX,DI ;Get the PC seg. addr of the page @RH1
1327 XCHG AL,AH ;Div by 256 (Segments per 4K block)@RH1
1328 MOV AH,BANKID ;Join with the bank ID to get the @RH1
1329 MOV DX,TTPOINTER ; ptr to the translate table entry @RH1
1330 OUT DX,AX ;Set TT ptr @RH1
1331
1332 MOV AX,SI ;Get absolute EMS page number @RH4
1333 CMP AX,PAGE_INHIBITTED ;Is TT entry to be inhibitted? @RH4
1334 JE VM_TTDATA_OK ;Yes..write the FFFF in AX @RH4
1335 MUL BLOCKS_PER_PAGE ;Else convert page to XMA 4K block @RH1
1336 TEST MEMCARD_MODE,EMUL_VIRT ;If running on the emulator then @RH7
1337 JZ VM_TTDATA_OK ; turn high order bit of data on @RH7
1338 OR AX,EMUL_TTDATA_ON ; allowing >8M support on emulator @RH7
1339VM_TTDATA_OK:
1340 MOV CX,BLOCKS_PER_PAGE ;Set up one page - loop on blocks @RH1
1341 MOV DX,AIDATA ; per page using the auto inc reg @RH1
1342VM_WRITE:
1343 OUT DX,AX ;Write TT entry, inc TT ptr @RH1
1344 CMP AX,PAGE_INHIBITTED ;Inhibit TT entry?
1345 JE VM_NEXT_TT ;Yes..don't inc AX
1346 INC AX ;Inc block ptr..contiguous blocks @RH1
1347VM_NEXT_TT:
1348 LOOP VM_WRITE ;Loop for all blocks in a page @RH1
1349
1350 RET
1351W_EMSPG_XVIRT ENDP
1352
1353
1354;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1355;³ Subroutine: WRITE TRANSLATE TABLE FOR EMS PAGE ³
1356;³ XMA REAL MODE ³
1357;³ ³
1358;³ This routine performs basically the same functions as ³
1359;³ the above routine. It is called if the XMA/A card is in ³
1360;³ 'real' mode (i.e. bank switching not active, planar memory ³
1361;³ is not disabled). The 8 bit 10X ports are used for setting ³
1362;³ up the XMA translate table. ³
1363;³ ³
1364;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1365W_EMSPG_XREAL PROC
1366
1367 MOV AL,WTT_CARD_SLOT ;Put the XMA/A card into setup @RH2
1368 OR AL,SLOT_SETUP ; mode @RH2
1369 OUT 96h,AL ; @RH2
1370
1371 XOR AL,AL ;Set the translate table ptr by @RH2
1372 MOV DX,RM_TTPTR_HI
1373 OUT DX,AL ; dividing the PC seg. addr in DI @RH2
1374 MOV AX,DI
1375 XCHG AL,AH ; by 256 (Segments per 4K block). @RH2
1376 MOV DX,RM_TTPTR_LO
1377 OUT DX,AL ;High byte always 0..no banking @RH2
1378
1379 MOV AX,SI ;Get absolute EMS page number @RH4
1380 CMP AX,PAGE_INHIBITTED ;Is TT entry to be inhibitted? @RH4
1381 JE RM_TTDATA_OK ;Yes..write the FFFF in AX @RH4
1382 MUL BLOCKS_PER_PAGE ;Else convert page to XMA 4K block @RH1
1383RM_TTDATA_OK:
1384 MOV CX,BLOCKS_PER_PAGE ;Set up one page - loop on blocks @RH2
1385 ; per page using the auto inc regs @RH2
1386RM_WRITE:
1387 XCHG AH,AL ;Write TT data high byte first, @RH2
1388 MOV DX,RM_TTDATA_HI ; then write low byte. This is @RH2
1389 OUT DX,AL ; not an auto increment port. @RH2
1390 XCHG AH,AL ; @RH2
1391 MOV DX,RM_TTDATA_LO ; @RH2
1392 OUT DX,AL ; @RH1
1393 CMP AX,PAGE_INHIBITTED ;Inhibit TT entry?
1394 JE RM_NEXT_TT ;Yes..don't inc AX
1395 INC AX ;Inc block ptr..contiguous blocks @RH1
1396RM_NEXT_TT:
1397 LOOP RM_WRITE ;Loop for all blocks in a page @RH1
1398
1399 MOV AL,0 ;Reset the slot ID @RH5
1400 OUT 96h,AL ; @RH5
1401 RET
1402W_EMSPG_XREAL ENDP
1403
1404;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1405;³ Subroutine: WRITE TRANSLATE TABLE FOR EMS PAGE ³
1406;³ Memory Expansion Option (MXO) ³
1407;³ ³
1408;³ This routine is used to map a logical page to a physical ³
1409;³ page off the MXO card. MXO has 16K blocks, as opposed ³
1410;³ to 4K on the XMA. The 8 bit 10X ports are used for setting ³
1411;³ up MXO's translate table. Note that the data in the ³
1412;³ translate table is only 8 bits, and the high order bit is a ³
1413;³ 0 to inhibit translation (where inhibit = 1 on XMA). ³
1414;³ ³
1415;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1416W_EMSPG_HLST PROC
1417 PUSH CX ; @RH3
1418
1419 MOV AL,WTT_CARD_SLOT ;Put the MXO card into setup @RH3
1420 OR AL,SLOT_SETUP ; mode @RH3
1421 OUT 96h,AL ; @RH3
1422
1423 MOV AX,DI ;Set the MXO translate table @RH3
1424 MOV CL,10 ; ptr by dividing the PC segment @RH3
1425 SHR AX,CL ; addr in DI by 1024 @RH3
1426 MOV DX,H_TTPTR_LO ; (segments per 16K MXO block). @RH3
1427 OUT DX,AL ; @RH3
1428 XCHG AL,AH ; @RH3
1429 MOV DX,H_TTPTR_HI ; @RH3
1430 OUT DX,AL ; @RH3
1431
1432 MOV AX,SI ;Get absolute EMS page number @RH4
1433 CMP AX,PAGE_INHIBITTED ;Is TT entry to be inhibitted? @RH4
1434 JE HM_TTDATA_INH ;Yes write MXO inhibit pattern @RH4
1435 ;Else turn on enable and write pg @RH3
1436 OR AL,H_TT_ENBMASK ; (no need to convert.. 16K EMS @RH3
1437 JMP SHORT HM_WRITETT ; page = 16K MXO block) @RH3
1438HM_TTDATA_INH: ;
1439 MOV AL,H_TT_INHIBIT ;AL = MXO TT inhibit data @RH3
1440HM_WRITETT:
1441 MOV DX,H_TTDATA ; Write to the 1 MXO TT entry. @RH3
1442 OUT DX,AL ; @RH3
1443 MOV AL,0 ;Reset the slot ID @RH5
1444 OUT 96h,AL ; @RH5
1445
1446 POP CX ; @RH3
1447 RET
1448W_EMSPG_HLST ENDP
1449
1450;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1451;³ Subroutine: MULTIPLE MEMORY CARD SETUP ³
1452;³ ³
1453;³ This subroutine selects the correct card in a multicard ³
1454;³ system for mapping a physical page. Given the absolute page ³
1455;³ number within the EMS pool (SI), it finds the card to use for ³
1456;³ this page, and converts SI to the offset of the page within ³
1457;³ this card. Before this new page is mapped, it may be necessary ³
1458;³ to disable the translate table entry of the card that's ³
1459;³ currently mapped. ³
1460;³ ³
1461;³ On entry: (DI) is starting segment in PC address space. ³
1462;³ (SI) absolute EMS page number (not handle relative) ³
1463;³ or FFFFh if page is to be inhibitted ³
1464;³ ³
1465;³ On exit: (DI) is unchanged. ³
1466;³ (SI) offset of the page within the selected card ³
1467;³ or FFFFh if page is to be inhibitted ³
1468;³ WTT_CARD_SLOT = Slot # of the new card to map ³
1469;³ MEMCARD_MODE = Flag indicating if XMA/A or MXO ³
1470;³ ³
1471;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1472
1473PG_NEW_CARD_ID DW ? ;Holders for the ID and the slot # @RH5
1474PG_NEW_CARD_SLOT DB ? ; of the card that will be used @RH5
1475 ; in the new mapping @RH5
1476MC_TABLE_OFFSET DW ? ;Holder for offset into the @RH5
1477 ; multicard page mapping table @RH5
1478
1479MLP_MCARD_SETUP PROC
1480 PUSH AX
1481 PUSH CX
1482 ;-------------------------------------
1483 ; Get the ID and slot of the card to º
1484 ; make active. Convert SI to be º
1485 ; the correct page within this card. º
1486 ;-------------------------------------
1487 PUSH DI ;Loop through the mem @RH5
1488 XOR DI,DI ; card table to find @RH5
1489 MOV CX,NUM_MEM_CARDS ; card used to map the @RH5
1490MC_GET_CARD: ; absolute page (SI) @RH5
1491 CMP MEM_CARD_TABLE.END_PG_NUM[DI],SI ;If the last pg this @RH5
1492 JAE MC_FOUND_CARD ; card maps <= SI then @RH5
1493 ADD DI,TYPE MEM_CARD_STRUC ; use this card @RH5
1494 LOOP MC_GET_CARD ;Else check next card @RH5
1495 ; Note: if SI = FFFF @RH5
1496 ; the last card is @RH5
1497 ; selected. This is @RH5
1498 ; OK, since it doesn't @RH5
1499 ; matter which is inh @RH5
1500MC_FOUND_CARD: ; @RH5
1501 MOV AX,MEM_CARD_TABLE.CARD_ID[DI] ;Save the card ID and @RH5
1502 MOV PG_NEW_CARD_ID,AX ; the slot # of the @RH5
1503 MOV AL,MEM_CARD_TABLE.CARD_SLOT[DI] ; card used to map @RH5
1504 MOV PG_NEW_CARD_SLOT,AL ; the new page. @RH5
1505 MOV AX,MEM_CARD_TABLE.START_PG_NUM[DI] ;If SI is not inhibit, @RH5
1506 CMP SI,PAGE_INHIBITTED ; convert SI from the @RH5
1507 JE MC_DEACTIVATE ; absolute pg number @RH5
1508 SUB SI,AX ; to the offset of the @RH5
1509 ; page within this card @RH5
1510
1511 ;-------------------------------------
1512MC_DEACTIVATE: ; Deactivate (inhibit) the translate º
1513 POP DI ; table entry of the current card. º
1514 ;-------------------------------------
1515 ; Search for the seg addr in the @RH5
1516 ; map phys pg table to get the @RH5
1517 ; corresponding entry in the @RH5
1518 PUSH SI ; multicard page mapping table @RH5
1519 XOR SI,SI ;SI = offset into map phy pg table @RH5
1520 XOR AX,AX ;AX = offset into multic pm table @RH5
1521 MOV CX,MAP_COUNT ;Loop on # phys pgs (incl FE & FF) @RH5
1522MC_SRCH_MPP: ; @RH5
1523 CMP MAP_TABLE.PHYS_PAGE_SEGMENT[SI],DI ;If no segment match @RH5
1524 JE MC_CHECK_CUR_PG ; then next entry in @RH5
1525 ADD SI,TYPE MAPPABLE_PHYS_PAGE_STRUCT ; map phys pg tbl & @RH5
1526 ADD AX,TYPE MULTIC_PM_STRUC ; multicard pm table @RH5
1527 LOOP MC_SRCH_MPP ; @RH5
1528
1529 ;Examine the current card ID and @RH5
1530 ; slot used for this page @RH5
1531MC_CHECK_CUR_PG:
1532 MOV MC_TABLE_OFFSET,AX ;Save mc tbl offset @RH5
1533 MOV SI,AX ; and put it in SI @RH5
1534 CMP MC_PM_TABLE.PG_CARD[SI],NO_CARD ;If the page is @RH5
1535 JE MC_MAP_NEW ; inhibitted or if @RH5
1536 MOV AL,MC_PM_TABLE.PG_SLOT[SI] ; the new page is @RH5
1537 CMP AL,PG_NEW_CARD_SLOT ; on the same card @RH5
1538 JE MC_MAP_NEW ; as the old page @RH5
1539 ; then dont inhibit @RH5
1540
1541 ;Inhibit TT entry for current card @RH5
1542 MOV WTT_CARD_SLOT,AL ;Save slot # and ID @RH5
1543 MOV AX,MC_PM_TABLE.PG_CARD[SI] ; of current card @RH5
1544 MOV SI,PAGE_INHIBITTED ;Page = inhibitted @RH5
1545 CMP AX,XMAA_CARD_ID ;If card = XMA/A @RH5
1546 JNE MC_INH_HLST ; then inh XMA/A TT @RH5
1547 CALL W_EMSPG_XREAL ; entry for pg via @RH5
1548 JMP SHORT MC_MAP_NEW ; real mode regs @RH5
1549MC_INH_HLST: ;Else inhibit TT @RH5
1550 CALL W_EMSPG_HLST ; entry for MXO @RH5
1551
1552 ;-------------------------------------
1553 ; Activate (enable) the translate º
1554 ; table entry of the new card. º
1555MC_MAP_NEW: ;-------------------------------------
1556 ;Set the multicard page frame @RH5
1557 ; table for the new card @RH5
1558 POP SI ;Restore EMS page @RH5
1559 PUSH DI ; and save pc seg addr. @RH5
1560 MOV DI,MC_TABLE_OFFSET ; @RH5
1561 MOV AL,PG_NEW_CARD_SLOT ;Store slot # of new card in @RH5
1562 MOV MC_PM_TABLE.PG_SLOT[DI],AL ; multc pm tbl and in variable @RH5
1563 MOV WTT_CARD_SLOT,AL ; used by map log to phys proc @RH5
1564 CMP SI,PAGE_INHIBITTED ;If new pg is not inhibitted @RH5
1565 JE MC_NEWID_INH ; then set card ID field in @RH5
1566 MOV AX,PG_NEW_CARD_ID ; the multicard page mapping @RH5
1567 MOV MC_PM_TABLE.PG_CARD[DI],AX ; table to new card ID @RH5
1568 JMP SHORT MC_SET_FLGS ; @RH5
1569MC_NEWID_INH: ; @RH5
1570 MOV AX,NO_CARD ;Else set card ID as no card @RH5
1571 MOV MC_PM_TABLE.PG_CARD[DI],AX ; @RH5
1572 ;............................
1573 ;Set flags so main MLP proc @RH5
1574 ; can map the new page @RH5
1575MC_SET_FLGS: ;............................. @RH5
1576 POP DI ;Restore PC seg addr
1577 CMP PG_NEW_CARD_ID,XMAA_CARD_ID ;Set the flag that tells @RH5
1578 JNE MC_MAP_HLST ; the main Map Log to P proc @RH5
1579 MOV MEMCARD_MODE,XMAA_REAL ; which subroutine to call @RH5
1580 JMP SHORT MC_END_PROC ;At this point, @RH5
1581MC_MAP_HLST: ; DI = PC segment addr of page @RH5
1582 MOV MEMCARD_MODE,HOLS_REAL ; SI = page's offset into card @RH5
1583MC_END_PROC: ; WTT_CARD_SLOT = card slot # @RH5
1584 POP CX ; MEMCARD_MODE = flag showing @RH5
1585 POP AX ; if card is XMAA or MXO @RH5
1586 RET ; @RH5
1587MLP_MCARD_SETUP ENDP
1588
1589;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
1590;º Entry point for DEALLOCATE PAGES Function 6 º
1591;º º
1592;º on entry: (AH) = '45'x º
1593;º (DX) = handle º
1594;º º
1595;º on exit: (AH) = status º
1596;º AX Revised...all other registers preserved º
1597;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
1598DE_ALLOCATE PROC
1599 PUSH BX ;save these registers
1600 PUSH CX
1601 PUSH DX
1602 PUSH DI
1603 PUSH SI
1604 PUSH DS
1605 PUSH ES ; @RH1
1606
1607 PUSH CS ;get this code segment
1608 POP DS ;into ds
1609 PUSH CS ;Set up ES for shifting (MOVSB) @RH1
1610 POP ES ; the PAL table @RH1
1611
1612 cmp dx,0 ;handle zero? ;an000; dms;
1613 jne D_Check_Handle ;no continue ;an000; dms;
1614 mov bx,0 ;reallocate to a page count of 0 ;an000; dms;
1615 call Reallocate ; ;an000; dms;
1616 jmp DA_Exit ;exit routine ;an000; dms;
1617
1618D_Check_Handle:
1619
1620 CMP DX,NUM_HANDLES-1 ;handle within range ?
1621 JBE D_OKRANGE ;if not then...
1622 MOV AH,EMS_CODE83 ;handle not found
1623 JMP DA_EXIT ;exit
1624D_OKRANGE: ;check if active (valid) handle
1625 PUSH DX ;Save handle id @RH1
1626 MOV AX,DX ;set up indexing into h lookup @RH1
1627 MOV DX,TYPE H_LOOKUP_STRUC ; @RH8
1628 MUL DX ;get handle lookup entry offset @RH8
1629 POP DX ;Restore handle id @RH1
1630 MOV DI,AX ;Put offset into index reg @RH1
1631
1632 CMP HANDLE_LOOKUP_TABLE.H_Pages[DI],REUSABLE_HANDLE
1633 ;Handle has pages? @RH1
1634 JNE D_OKHNDL ;Yes OK handle
1635 MOV AH,EMS_CODE83 ;No handle not in use. error.
1636 JMP DA_EXIT ;exit
1637 ;-----------------------------------------------------
1638D_OKHNDL: ; Before deallocation can continue, insure the @RH1 º
1639 ; page frame map is not saved under this handle @RH1 º
1640 ;-----------------------------------------------------
1641 PUSH DX ;Save handle id @RH1
1642 MOV AX,DX ;Get the correct offset @RH1
1643 MOV DX,TYPE H_SAVE_STRUC ; into the handle save @RH8
1644 MUL DX ; area for this handle @RH8
1645 POP DX ;Restore handle id @RH1
1646 MOV SI,AX ; @RH1
1647D_HSAVECHK:
1648 CMP HANDLE_SAVE_AREA.PG0_LP[SI],REUSABLE_SAVEA
1649 JE D_PAT_UPDATE ;If the 1st entry for this handle @RH1
1650 MOV AH,EMS_CODE86 ; in the save area is not free
1651 JMP DA_EXIT ; then in use...exit with error
1652 ;-----------------------------------------------------
1653 ; Update Page Allocation List - unallocate
1654D_PAT_UPDATE:
1655
1656 PUSH DX ;Save handle id @RH1
1657
1658
1659
1660 MOV CX,HANDLE_LOOKUP_TABLE.H_PAGES[DI] ;Get the # of pages @RH1
1661 MOV AX,HANDLE_LOOKUP_TABLE.H_PAL_PTR[DI] ;Load si with ptr @RH1
1662 MOV SI,AX ;pass ptr ;an000; dms;
1663
1664 push cx ;save loop count ;an000; dms;
1665
1666 cmp cx,0 ;handle has 0 pages? ;an001; dms;
1667 je D_Depat_Exit1 ;yes - don't changes ptr;an001; dms;
1668
1669 mov ax,cs:PAL_Free_Ptr ;no - dealloc pages ;an001; dms;
1670 mov cs:PAL_Free_Ptr,si ;set free ptr to root of;an001; dms;
1671 ; handle list
1672 dec cx ;don't loop past last pg;an001; dms;
1673
1674D_DEPAT:
1675
1676 ;this loop scans to
1677 ;the end of the allocated
1678 ;chain
1679
1680 cmp cx,0 ;end of deallocate? ;an000; dms;
1681 je D_Depat_Exit ;yes - exit ;an000; dms;
1682 shl si,1 ;no - adjust to index ;an001; dms;
1683 mov si,Page_Alloc_List[si] ;get new ptr val ;an001; dms;
1684 dec cx ;dec loop ctr ;an001; dms;
1685 jmp D_DEPAT ;continue ;an000; dms;
1686
1687D_DEPAT_EXIT:
1688
1689 shl si,1 ;adjust to index value ;an001; dms;
1690 mov Page_Alloc_List[si],ax ;pt. last page to orig. ;an001; dms;
1691 ; free ptr.
1692
1693D_Depat_Exit1:
1694
1695 pop cx ;restore loop count ;an000; dms;
1696 pop dx ;restore handle ;an000; dms;
1697
1698 push ds ;save regs ;an000; dms;
1699 push si ; ;an000; dms;
1700
1701 mov ax,cs ;swap segs ;an000; dms;
1702 mov ds,ax ; ;an000; dms;
1703 mov si,offset cs:Null_Handle_Name ;point to null handle ;an000; dms;
1704 mov ax,5301h ;set handle name func ;an000; dms;
1705 call Handle_Name ;set the handle name to ;an000; dms;
1706 ; nulls
1707 pop si ;restore regs ;an000; dms;
1708 pop ds ; ;an000; dms;
1709
1710 cli ;ints off ;an000; dms;
1711 add cs:Free_Pages,cx ;free up page ;an000; dms;
1712 mov Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;deallocate ;an000; dms;
1713 ; handle
1714 sti ;ints on ;an000; dms;
1715
1716 xor ah,ah ;clear flag ;an000; dms;
1717
1718DA_EXIT:
1719
1720 POP ES ; @RH1
1721 POP DS
1722 POP SI
1723 POP DI
1724 POP DX
1725 POP CX
1726 POP BX
1727
1728 RET
1729DE_ALLOCATE ENDP
1730
1731
1732;====================================================================
1733; Deallocate_Chain - This routine deallocates a page from a
1734; handle and links it to the free list
1735;
1736; Inputs : SI - PTR to entry to deallocate
1737;
1738; Outputs : SI - PTR to next entry to deallocate
1739;
1740;====================================================================
1741
1742Deallocate_Chain proc ;deallocate page ;an000; dms;
1743
1744 push ax ;save regs ;an000; dms;
1745 push bx ; ;an000; dms;
1746 push cx ; ;an000; dms;
1747
1748 cli ;ints off ;an000; dms;
1749
1750 mov bx,si ;alloc_ptr ;an000; dms;
1751
1752 mov ax,si ;get page_ptr ;an000; dms;
1753 mov dx,Type Page_Alloc_List ;get entry size ;an000; dms;
1754 mul dx ;get pointer val ;an000; dms;
1755 mov si,ax ;page_ptr ;an000; dms;
1756
1757 mov ax,Page_List_Entry ;page_ptr value ;an000; dms;
1758 mov cx,cs:PAL_Free_PTR ;free_ptr ;an000; dms;
1759
1760
1761 mov cs:PAL_Free_PTR,bx ;new free_ptr ;an000; dms;
1762 mov Page_List_Entry,cx ;new free_ptr value ;an000; dms;
1763 mov si,ax ;next page to deallocate;an000; dms;
1764 sti ;ints on ;an000; dms;
1765
1766 pop cx ;restore regs ;an000; dms;
1767 pop bx ; ;an000; dms;
1768 pop ax ; ;an000; dms;
1769
1770 ret ; ;an000; dms;
1771
1772Deallocate_Chain endp ; ;an000; dms;
1773
1774;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
1775;º Entry point for QUERY MEMORY MANAGER VERSION Function 7 º
1776;º º
1777;º on entry: (AH) = '46'x º
1778;º º
1779;º on exit: (AH) = status º
1780;º all other registers preserved º
1781;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
1782Q_VERSION PROC
1783 MOV AL,EMM_VERSION ;al get version number
1784 XOR AH,AH ;good return code
1785 RET
1786Q_VERSION ENDP
1787
1788
1789
1790;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
1791;º Entry point for SAVE MAPPING CONTEXT Function 8 º
1792;º º
1793;º on entry: (AH) = '47'x º
1794;º (DX) = handle assigned to the interrupt service º
1795;º routine (i.e. save map under this handle). º
1796;º º
1797;º on exit: (AH) = status º
1798;º all other registers preserved º
1799;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
1800SAVE_MAP PROC
1801 PUSH DX
1802 PUSH DI
1803 PUSH SI
1804 PUSH DS
1805 PUSH ES ;save these registers
1806
1807 PUSH CS ;get cs
1808 POP DS ;into ds
1809 PUSH CS ;Get CS into ES (save area is in
1810 POP ES ; this segment)
1811
1812 CMP DX,NUM_HANDLES-1 ;handle within range ?
1813 JBE SM_DXINRANGE ;if not then...
1814 MOV AH,EMS_CODE83 ;handle not found
1815 JMP SM_EXIT ;exit
1816SM_DXINRANGE:
1817 PUSH DX ;Handle destroyed by MUL @RH1
1818 MOV AX,DX ;SI = requested handle's @RH1
1819 MOV DX,TYPE H_LOOKUP_STRUC ; offset into the handle @RH8
1820 MUL DX ; lookup table @RH8
1821 MOV SI,AX ; @RH1
1822 POP DX ;Restore handle ID @RH1
1823
1824 CMP HANDLE_LOOKUP_TABLE.H_Pages[SI],REUSABLE_HANDLE
1825 JNE SM_HACTIVE ;If handle is in use (active), ok @RH1
1826 MOV AH,EMS_CODE83 ;else handle not in use; error
1827 JMP SM_EXIT ;exit
1828SM_HACTIVE:
1829 MOV AX,DX ;DI = requested handle's @RH1
1830 MOV DX,TYPE H_SAVE_STRUC ; offset into the handle @RH1
1831 MUL DX ; save area @RH1
1832 MOV DI,AX ;Add the table base to @RH1
1833 ADD DI,OFFSET HANDLE_SAVE_AREA ; make ES:DI a pointer @RH1
1834
1835 ;-------------------------------------
1836 ; Insure save area free for this hndl º
1837SM_AREACHECK: ;-------------------------------------
1838 CMP [DI].PG0_LP,REUSABLE_SAVEA
1839 JE SM_SAVE_OK ;If 1st entry free then OK to save @RH1
1840 MOV AH,EMS_CODE8D ;Else page map already saved for
1841 JMP SM_EXIT ; this handle. Exit with error
1842SM_SAVE_OK:
1843 CALL SAVE_PGFRM_MAP ;Save to area pointed to by ES:DI @RH1
1844 XOR AH,AH ;Set good return code
1845SM_EXIT:
1846 POP ES ;restore these registers
1847 POP DS
1848 POP SI
1849 POP DI
1850 POP DX
1851 RET ;return to caller
1852SAVE_MAP ENDP
1853
1854;-----------------------------------------------------------------------;
1855; Subroutine: SAVE PAGE FRAME MAP ;
1856; ;
1857; purpose: To save the map of the 4 pages within the ;
1858; page frame to a save area pointed to by ES:DI. ;
1859; The handle ID and logical page active within each ;
1860; of the 4 physical pages is saved. Each is a word ;
1861; value. ;
1862; called by: Save mapping array (Function 8) using a handle ID ;
1863; and our save area. ;
1864; Get page map (Function 15 subfunction 0) without ;
1865; a handle ID using the application's save area. ;
1866; ;
1867; on entry: ES:DI points to save area ;
1868; ;
1869; on exit: All registers preserved ;
1870;-----------------------------------------------------------------------;
1871SAVE_PGFRM_MAP PROC
1872 PUSH AX ;save these registers
1873 PUSH CX
1874 PUSH DI
1875 PUSH SI
1876 PUSH DS
1877
1878 PUSH CS ;get this segment into DS
1879 POP DS
1880 ;-------------------------------------
1881 ; Read the current handle ID and log º
1882 ; pg #s in the mappable phys pg tableº
1883 ;-------------------------------------
1884 CLD ;Set direction for STOSW forward @RH5
1885 XOR SI,SI ;Clear offset into mappable phys. @RH5
1886 MOV CX,map_count ; page table. Loop for # entries @RH5
1887SM_HLP_STORE: ;Store the word for the @RH5
1888 MOV AX,MAP_TABLE.PPM_HANDLE[SI] ; currently active handle@RH5
1889 STOSW ; and logical page into @RH5
1890 MOV AX,MAP_TABLE.PPM_LOG_PAGE[SI] ; the save area at ES:DI @RH5
1891 STOSW ; STOSW moves AX to ES:DI@RH5
1892 ADD SI,TYPE MAPPABLE_PHYS_PAGE_STRUCT ;Next entry in mpp table @RH5
1893 LOOP SM_HLP_STORE ; @RH5
1894
1895 POP DS ;Recover these registers
1896 POP SI
1897 POP DI
1898 POP CX
1899 POP AX
1900 RET ;return to caller
1901SAVE_PGFRM_MAP ENDP
1902
1903
1904;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
1905;º Entry point for RESTORE MAPPING CONTEXT Function 9 º
1906;º º
1907;º on entry: (AH) = '48'x º
1908;º (DX) = handle assigned to the interrupt service º
1909;º routine (i.e. handle map was saved under). º
1910;º º
1911;º on exit: (AH) = status º
1912;º all other registers preserved º
1913;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
1914RESTORE_MAP PROC
1915 PUSH BX
1916 PUSH CX
1917 PUSH DX
1918 PUSH DI
1919 PUSH SI
1920 PUSH DS ;save these registers
1921
1922 PUSH CS ;Get CS into DS (save area is in
1923 POP DS ; this segment)
1924
1925 CMP DX,NUM_HANDLES-1 ;handle within range ?
1926 JBE RM_DXINRANGE ;if not then...
1927 MOV AH,EMS_CODE83 ;handle not found
1928 JMP RM_EXIT ;exit
1929RM_DXINRANGE:
1930 PUSH DX ;Handle destroyed by MUL @RH1
1931 MOV AX,DX ;SI = requested handle's @RH1
1932 MOV DX,TYPE H_LOOKUP_STRUC ; offset into the handle @RH1
1933 MUL DX ; lookup table @RH1
1934 MOV SI,AX ; @RH1
1935 POP DX ;Restore handle ID @RH1
1936
1937 CMP HANDLE_LOOKUP_TABLE.H_Pages[SI],REUSABLE_HANDLE
1938 JNE RM_HACTIVE ;If handle is in use (active), ok @RH1
1939 MOV AH,EMS_CODE83 ;else handle not in use; error
1940 JMP RM_EXIT ;exit
1941RM_HACTIVE:
1942 MOV AX,DX ;SI = requested handle's @RH1
1943 MOV DX,TYPE H_SAVE_STRUC ; offset into the handle @RH1
1944 MUL DX ; save area @RH1
1945 MOV SI,AX ;Add the table base to @RH1
1946 ADD SI,OFFSET HANDLE_SAVE_AREA ; make DS:SI a pointer @RH1
1947
1948 ;-------------------------------------
1949 ; Insure save area used for this hndl º
1950RM_AREACHECK: ;-------------------------------------
1951 CMP [SI].PG0_LP,REUSABLE_SAVEA ;Unused save table entry? @RH1
1952 JNE RM_SAVE_OK ;No used..OK check next @RH1
1953 MOV AH,EMS_CODE8E ;Yes error ..no page map
1954 JMP RM_EXIT ; saved. Exit.
1955
1956 ;-------------------------------------
1957 ; Call RESTORE_PGFRM_MAP º
1958RM_SAVE_OK: ;-------------------------------------
1959 CALL RESTORE_PGFRM_MAP ;Restore page frame map
1960 CMP AH,0 ;Successful?
1961 JNE RM_EXIT ;No exit
1962
1963 ;-------------------------------------
1964 ; Clear the save area for the handle º
1965 ;-------------------------------------
1966 ;DS:SI still ptr to save area @RH5
1967 MOV CX,map_count ;Clear all saved entries @RH5
1968RM_CLEAR_SA: ;Use an overlay to mark the @RH5
1969 MOV [SI].HSA_LP,REUSABLE_SAVEA ; save area free - put reusabl @RH5
1970 ADD SI,TYPE H_SAVEA_ENTRY ; indicator in the log p field @RH5
1971 LOOP RM_CLEAR_SA ; @RH5
1972
1973RM_EXIT:
1974 POP DS ;restore these registers
1975 POP SI
1976 POP DI
1977 POP DX
1978 POP CX
1979 POP BX
1980 RET ;return to caller
1981RESTORE_MAP ENDP
1982
1983;-----------------------------------------------------------------------;
1984; Subroutine: RESTORE PAGE FRAME MAP ;
1985; ;
1986; purpose: To restore the map of the 4 pages within the ;
1987; page frame from a save area pointed to by DS:SI. ;
1988; The save area consists of a handle ID and logical ;
1989; page for each of the 4 physical pages. Each is a ;
1990; word value. ;
1991; called by: Restore mapping context (Function 9) using a ;
1992; handle ID and our save area. ;
1993; Set page map (Function 15 subfunction 1) without ;
1994; a handle ID using the application's save area. ;
1995; ;
1996; on entry: DS:SI points to the save area ;
1997; ;
1998; on exit: (AX) = Status ;
1999; All other registers preserved ;
2000; ;
2001;-----------------------------------------------------------------------;
2002RESTORE_PGFRM_MAP PROC
2003 PUSH BX
2004 PUSH CX
2005 PUSH DX
2006 PUSH DI
2007 PUSH SI
2008
2009 XOR DI,DI ;Use for mappable phys page table @RH5
2010 MOV CX,map_count ;Loop for all pages in page frame @RH5
2011RP_RSTR_LP: ; @RH5
2012 PUSH DS ;Get the phys page from @RH5
2013 MOV AX,MAP_TABLE.PHYS_PAGE_NUMBER[DI] ; the map phys pg tbl @RH5
2014 POP DS ; (only AL is used) @RH5
2015 MOV DX,[SI] ;DX = Handle ID..inc SI @RH5
2016 ADD SI,TYPE PG0_HNDL ; by len needed for hnd @RH5
2017 MOV BX,[SI] ;BX = Log. page..inc SI @RH5
2018 ADD SI,TYPE PG0_LP ; by len needed for lp @RH5
2019 CALL MAP_L_TO_P ;Call main Map module @RH5
2020 CMP AH,0 ;If an error occurred @RH5
2021 JE RP_NEXT ; anywhere set software @RH5
2022 MOV AH,EMS_CODE80 ; error and exit @RH5
2023 JMP SHORT RP_EXIT ;Else map next page @RH5
2024RP_NEXT: ;Advance offset into @RH5
2025 ADD DI,TYPE MAPPABLE_PHYS_PAGE_STRUCT ; map phys page table @RH5
2026 LOOP RP_RSTR_LP ;Loop for 4 EMS pages @RH5
2027
2028RP_EXIT:
2029 POP SI
2030 POP DI ;Restore entry regs
2031 POP DX
2032 POP CX
2033 POP BX
2034 RET ;return to caller
2035RESTORE_PGFRM_MAP ENDP
2036
2037
2038;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
2039;º Entry point for GET EMM HANDLE COUNT Function 12 º
2040;º º
2041;º on entry: (AH) = '4B'x º
2042;º º
2043;º on exit: (AH) = status º
2044;º (BX) = number of open (active) EMS handles º
2045;º all other registers preserved º
2046;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
2047Q_OPEN PROC
2048 PUSH CX ;save these registers
2049 PUSH SI
2050 PUSH DS
2051
2052 PUSH CS ;get this segment
2053 POP DS ;into ds
2054
2055 XOR BX,BX ;clear open handle counter
2056 XOR SI,SI ;SI = offset of handle lookup table@RH1
2057 MOV CX,NUM_HANDLES ;loop counter = number of handles
2058QH_CHECKALL:
2059 CMP HANDLE_LOOKUP_TABLE.H_Pages[SI],REUSABLE_HANDLE
2060 ;Handle have pages? @RH1
2061 JE QH_NEXTH ;No..not active..next @RH1
2062 INC BX ;Else open handle @RH1
2063QH_NEXTH:
2064 ADD SI,TYPE H_LOOKUP_STRUC ;Point to next handle lookup entry @RH1
2065 LOOP QH_CHECKALL ; and check it out @RH1
2066 XOR AH,AH ;good return status
2067
2068 POP DS ;recover these registers
2069 POP SI
2070 POP CX
2071 RET ;return to caller
2072Q_OPEN ENDP
2073
2074
2075;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
2076;º Entry point for GET EMM HANDLE PAGES Function 13 º
2077;º NOTE - CAN HANDLE HANDLE WITH 0 PAGES º
2078;º on entry: (AH) = '4C'x º
2079;º (DX) = handle id º
2080;º º
2081;º on exit: (AH) = status º
2082;º (BX) = number of pages allocated to this handle º
2083;º all other registers preserved º
2084;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
2085Q_ALLOCATE PROC
2086 PUSH DX ;save these registers
2087 PUSH SI
2088 PUSH DS
2089
2090 PUSH CS ;get this segment
2091 POP DS ;into ds
2092
2093 CMP DX,NUM_HANDLES-1 ;DX <= Number of handles @RH1
2094 JBE QP_DXINRANGE ;Yes OK @RH1
2095 MOV AH,EMS_CODE83 ;No out of range..error @RH1
2096 JMP Q_ALLOC_EXIT ;exit @RH1
2097QP_DXINRANGE:
2098 MOV AX,DX ;SI = offset into @RH1
2099 MOV DX,TYPE H_LOOKUP_STRUC ; handle lookup tbl @RH1
2100 MUL DX ; for the given @RH1
2101 MOV SI,AX ; handle @RH1
2102 MOV BX,HANDLE_LOOKUP_TABLE.H_Pages[SI] ;Return # of pages @RH1
2103
2104 CMP BX,REUSABLE_HANDLE ; is this one free ;AN004;
2105 JNE QP_GOOD_RC ; no, must be a real number ;AN004;
2106 mov ah,EMS_Code83 ; this page is not allocated currently ;an004; dms;
2107 XOR BX,BX ; yes, zero BX (number of pages) ;AN004;
2108 jmp Q_Alloc_Exit ; exit the routine ;an004; dms;
2109 ;AN004;
2110QP_GOOD_RC: ;AN004;
2111 XOR AH,AH ;good return status
2112Q_ALLOC_EXIT:
2113 POP DS ;recover these registers
2114 POP SI
2115 POP DX
2116 RET ;return to caller
2117Q_ALLOCATE ENDP
2118
2119
2120;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
2121;º Entry point for GET ALL OPEN HANDLES AND PAGES Function 14 º
2122;º º
2123;º on entry: (AH) = '4D'x º
2124;º ES:DI = Points to an array. Each entry consists of º
2125;º 2 words. The first word is for an active º
2126;º EMS handle and the 2nd word for the number º
2127;º of pages allocated to that handle. This º
2128;º procedure will fill in the table, but the º
2129;º requestor must supply a large enough array. º
2130;º º
2131;º on exit: (AH) = status º
2132;º (BX) = Number of active EMS handles º
2133;º all other registers preserved º
2134;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
2135Q_OPEN_ALL PROC
2136 PUSH CX ;save these registers
2137 PUSH DX
2138 PUSH DI
2139 PUSH SI
2140 PUSH DS
2141
2142 PUSH CS ;get this segment
2143 POP DS ;into ds
2144
2145 MOV DI,cs:[bp].IE_Saved_DI_Reg ;restore di to its value on - gga P1501 ;an004;
2146 ;entry
2147
2148 XOR BX,BX ;Init number of active handles @RH1
2149 XOR DX,DX ; and handle id @RH1
2150 XOR SI,SI ;SI = offset into handle lup table @RH1
2151 MOV CX,NUM_HANDLES ;Loop for all entries in h lup tbl @RH1
2152QHP_CHECKALL:
2153 MOV AX,HANDLE_LOOKUP_TABLE.H_Pages[SI] ; @RH1
2154 CMP AX,REUSABLE_HANDLE ;If entry is reusable (free), @RH1
2155 JE QHP_NEXT ; don't count it. Check next hndl @RH1
2156 INC BX ;Else active handle. Inc hndl cnt @RH1
2157 MOV ES: WORD PTR [DI],DX ;Write handle # in the user's area @RH1
2158 MOV ES: WORD PTR [DI+2],AX ;Write # of pages in the 2nd word @RH1
2159 ADD DI,4 ;Advance ptr to user's area @RH1
2160QHP_NEXT: ;Check next entry in h lup table @RH1
2161 ADD SI,TYPE H_LOOKUP_STRUC ;Inc offset into handle lup table @RH1
2162 INC DX ;Next handle ID
2163 LOOP QHP_CHECKALL
2164
2165 XOR AH,AH ;good return status
2166
2167 POP DS ;restore these registers
2168 POP SI
2169 POP DI
2170 POP DX
2171 POP CX
2172 RET ;return to caller
2173Q_OPEN_ALL ENDP
2174
2175
2176;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
2177;º Entry point for GET/SET PAGE MAP SUBFUNCTIONS Function 15 º
2178;º º
2179;º on entry: (AH) = '4E'x º
2180;º (AL) = subfunction number º
2181;º ES:DI = destination save area for Get Subfunction º
2182;º DS:SI = source save area for Set Subfunction º
2183;º º
2184;º on exit: (AH) = status º
2185;º all other registers preserved º
2186;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
2187SUBFCN_TABLE LABEL WORD
2188 DW OFFSET GET_SUBFCN ;0 - Put page frame map into ES:DI array
2189 DW OFFSET SET_SUBFCN ;1 - Set page frame map from DS:SI array
2190 DW OFFSET GET_SET_SUBFCN ;2 - Put page frame map into ES:DI array
2191 ;and Set page frame map from DS:SI array
2192MAX_SUBFCN EQU ($-SUBFCN_TABLE)/2 ;maximum allowable subfunction number
2193 DW OFFSET SIZE_SUBFCN ;3 - Return storage requirements of the
2194 ;Get and Set subfunctions
2195GET_SET_MAP PROC
2196 MOV DI,cs:[bp].IE_Saved_DI_Reg ;restore di to its value on
2197 PUSH BX ;save bx
2198 CMP AL,MAX_SUBFCN ;is subfunctiion number within range?
2199; $IF BE ;do if yes...
2200 JNBE $$IF86
2201 MOV BX,OFFSET GET_SET_EXIT ;get return address common to all subfcns
2202 PUSH BX ;put it on stack for return
2203 XOR AH,AH ;adjust ax to make it
2204 ADD AX,AX ; offset into jump table
2205 MOV BX,AX ;get it into bx for jump
2206;At entry to subfunction handler:
2207; CS = INT67 code segment
2208; TOP OF STACK is return address, GET_SET_EXIT
2209
2210 JMP CS:SUBFCN_TABLE[BX] ;call subfunction handler
2211; $ENDIF
2212$$IF86:
2213 ;if subfcn # is out of range then do...
2214 MOV AH,EMS_CODE8F ;function call out of range
2215GET_SET_EXIT:
2216 POP BX ;recover bx
2217 RET ;return to caller
2218GET_SET_MAP ENDP
2219
2220
2221 page
2222;-----------------------------------------------------------------------;
2223; Subfunction 0 to GET PAGE MAP Function 15/0 ;
2224; ;
2225; on entry: (AH) = '43'x ;
2226; (AL) = 0 ;
2227; ES:DI = Destination save area ;
2228; ;
2229; on exit: (AH) = status ;
2230; all other registers preserved ;
2231;-----------------------------------------------------------------------;
2232GET_SUBFCN PROC
2233 PUSH DI ;save
2234 PUSH ES ;save
2235
2236
2237 CALL SAVE_PGFRM_MAP ;save page frame map to ES:DI
2238 XOR AH,AH ;good return status
2239 POP ES ;restore
2240 POP DI ;restore
2241 RET ;return to caller
2242GET_SUBFCN ENDP
2243
2244
2245;-----------------------------------------------------------------------;
2246; Subfunction 1 to SET PAGE MAP Function 15/1 ;
2247; ;
2248; on entry: (AH) = '43'x ;
2249; (AL) = 1 ;
2250; DS:SI = Source save area ;
2251; ;
2252; on exit: (AH) = status ;
2253; all other registers preserved ;
2254;-----------------------------------------------------------------------;
2255SET_SUBFCN PROC
2256 PUSH SI ;save
2257 PUSH DS ;save
2258 CALL RESTORE_PGFRM_MAP ;restore page frame map from DS:SI
2259 XOR AH,AH ;good return status
2260 POP DS ;restore
2261 POP SI ;restore
2262 RET ;return to caller
2263SET_SUBFCN ENDP
2264
2265
2266;-----------------------------------------------------------------------;
2267; Subfunction 2 to GET and SET PAGE MAP Function 15/2 ;
2268; ;
2269; on entry: (AH) = '43'x ;
2270; (AL) = 2 ;
2271; ES:DI = destination save area ;
2272; DS:SI = source save area ;
2273; ;
2274; on exit: (AH) = status ;
2275; all other registers preserved ;
2276;-----------------------------------------------------------------------;
2277GET_SET_SUBFCN PROC
2278 PUSH DI
2279 PUSH SI
2280
2281 MOV DI,cs:[bp].IE_Saved_DI_Reg ;restore di to its value on
2282 ;entry into irpt handler
2283
2284 CALL SAVE_PGFRM_MAP ;save page frame map to ES:DI
2285 CALL RESTORE_PGFRM_MAP ;restore page frame map from DS:SI
2286 XOR AH,AH ;good return status
2287
2288 POP SI
2289 POP DI
2290 RET ;return to caller
2291GET_SET_SUBFCN ENDP
2292
2293;-----------------------------------------------------------------------;
2294; Subfunction 3 to RETURN SIZE OF SAVE ARRAY Function 15/3 ;
2295; ;
2296; on entry: (AH) = '43'x ;
2297; (AL) = 3 ;
2298; ;
2299; on exit: (AH) = status ;
2300; (AL) = Number of bytes needed for a GET or SET ;
2301; all other registers preserved ;
2302;-----------------------------------------------------------------------;
2303SIZE_SUBFCN PROC
2304 MOV AL,TYPE H_SAVE_STRUC ;get size requirements for save area
2305 XOR AH,AH ;good return status
2306 RET ;return to caller
2307SIZE_SUBFCN ENDP
2308
2309;=========================================================================
2310; Set_Instance This routine accesses the instance table.
2311;
2312; Inputs : Instance_Table - Table of instances of reentrancy.
2313;
2314; Outputs : BP - pointer to instance table entry to use
2315; NC - instance table entry found
2316; CY - no instance table entry found
2317; AH - error code on CY
2318;=========================================================================
2319
2320Set_Instance proc ;set the instance table ;an000; dms;
2321
2322 cli ;disable interrupts ;an000; dms;
2323 push cx ; ;an000; dms;
2324
2325 mov bp,offset cs:Instance_Table ;get pointer to instance table ;an000; dms;
2326 mov cx,Instance_Count ;number of instances ;an000; dms;
2327
2328Set_Instance_Loop:
2329
2330 cmp cs:[bp].IE_Alloc_Byte,Unallocated;unallocated entry? ;an000; dms;
2331 je Set_Instance_Found ;open entry ;an000; dms;
2332 add bp,Instance_Size ;next instance ;an000; dms;
2333 loop Set_Instance_Loop ;continue ;an000; dms;
2334
2335 mov ah,EMS_Code80 ;not enough instance entries ;an000; dms;
2336 stc ;signal error ;an000; dms;
2337 jmp Set_Instance_Exit ;exit routine ;an000; dms;
2338
2339Set_Instance_Found:
2340
2341 mov cs:[bp].IE_Alloc_Byte,Allocated ;instance allocated ;an000; dms;
2342 clc ;signal good exit ;an000; dms;
2343
2344Set_Instance_Exit:
2345
2346 pop cx ;restore regs ;an000; dms;
2347 sti ;turn on interrupts ;an000; dms;
2348
2349 ret ;return ;an000; dms;
2350
2351Set_Instance endp ; ;an000; dms;
2352
2353;=========================================================================
2354; Reset_Instance This routine accesses the instance table.
2355;
2356; Inputs : BP - pointer to currently active instance entry
2357;
2358; Outputs : Instance_Table - Deactivated instance entry
2359;=========================================================================
2360
2361Reset_Instance proc
2362
2363 cli ;turn off interrupts ;an000; dms;
2364 mov cs:[bp].IE_Alloc_Byte,Unallocated;deallocate instance ;an000; dms;
2365 sti ;set interrupts ;an000; dms;
2366
2367 ret ;return ;an000; dms;
2368
2369Reset_Instance endp ; ;an000; dms;
2370
2371
2372;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
2373;º Entry point for UNSUPPORTED FUNCTION CALLS º
2374;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
2375UNSUPPORTED PROC
2376
2377GET_PORT_ARRAY:
2378GET_L_TO_P:
2379 RET
2380UNSUPPORTED ENDP
2381
2382
2383;=========================================================================
2384; EMS_Page_Contig_Chk - This routine will take CX as input, which is
2385; the count of pages needed to satisfy the
2386; Allocate, Allocate Raw, or Reallocate functions.
2387; It will scan the unallocated page list to
2388; determine if there are CX number of contiguous
2389; pages. When it finds a block of contiguous
2390; pages it will return a pointer in SI pointing
2391; to the first page in the linked list that contains
2392; CX contiguous pages. If CX contiguous pages are
2393; not found a CY will be returned.
2394;
2395; Inputs : CX (Pages needed for request)
2396;
2397; Outputs : CY (There are no CX contiguous pages)
2398; NC (There are CX contiguous pages)
2399; SI (Pointer to 1st. page of CX contiguous pages)
2400;=========================================================================
2401
2402EMS_Page_Contig_Chk proc near ;determine contiguity ;an001; dms;
2403
2404 push ax ;save regs ;an001; dms;
2405 push bx ; ;an001; dms;
2406 push cx ; ;an001; dms;
2407 push dx ; ;an001; dms;
2408 push di ; ;an001; dms;
2409
2410;;;; mov ax,cs:Free_Pages ;initialize page count ;an001; dms;
2411 mov di,cs:PAL_Free_Ptr ;pointer to free list ;an001; dms;
2412 mov si,di ;initialize ptr val ;an001; dms;
2413;;;; mov bx,di ;initialize base val ;an001; dms;
2414;;;; mov dx,1 ;initialize count val ;an001; dms;
2415
2416EMS_Page_Contig_Main_Loop:
2417
2418;;;; cmp dx,cx ;at end? ;an001; dms;
2419;;;; je EMS_Page_Found_Contig ;yes - found contig ;an001; dms;
2420
2421;;;; shl di,1 ;index value ;an001; dms;
2422;;;; mov si,Page_Alloc_List[di] ;point to next free ;an001; dms;
2423;;;; shr di,1 ;ptr value ;an001; dms;
2424;;;; dec di ;see if it is contig ;an001; dms;
2425;;;; cmp si,di ; ;an001; dms;
2426;;;; je EMS_Page_Contig_Loop ;contig - check next ;an001; dms;
2427;;;; jmp EMS_Page_Contig_Init_Loop ;not contig ;an001; dms;
2428
2429EMS_Page_Contig_Loop:
2430
2431;;;; inc dx ;inc loop counter ;an001; dms;
2432;;;; jmp EMS_Page_Contig_Main_Loop ;continue ;an001; dms;
2433
2434EMS_Page_Contig_Init_Loop:
2435
2436;;;; sub ax,dx ;adjust pages left cnt ;an001; dms;
2437;;;; cmp ax,cx ;enough left? ;an001; dms;
2438;;;; jb EMS_Page_Not_Contig ;no contig memory ;an001; dms;
2439;;;; mov bx,si ;reinit base val ;an001; dms;
2440;;;; mov di,si ;reinit ptr val ;an001; dms;
2441;;;; mov dx,1 ;reinit count val ;an001; dms;
2442;;;; jmp EMS_Page_Contig_Main_Loop ;continue check ;an001; dms;
2443
2444EMS_Page_Not_Contig:
2445
2446;;;; stc ;signal not contig ;an001; dms;
2447;;;; jmp EMS_Page_Contig_Exit ;exit routine ;an001; dms;
2448
2449EMS_Page_Found_Contig:
2450
2451 clc ;signal contig ;an001; dms;
2452;;;; mov si,bx ;pass ptr to 1st. ;an001; dms;
2453
2454EMS_Page_Contig_Exit:
2455
2456 pop di ;restore regs ;an001; dms;
2457 pop dx ; ;an001; dms;
2458 pop cx ; ;an001; dms;
2459 pop bx ; ;an001; dms;
2460 pop ax ; ;an001; dms;
2461
2462 ret ;return to caller ;an001; dms;
2463
2464EMS_Page_Contig_Chk endp ;end proc ;an001; dms;
2465
2466
2467
2468;=========================================================================
2469; EMS_Link_Set - This routine takes the SI returned from
2470; EMS_Page_Cont_Chk and removes CX pages from
2471; the linked list for the new handle.
2472;
2473; Inputs : SI - Pointer value to the beginning of pages for handle
2474; CX - Count of pages to be allocated
2475;
2476; Outputs : Adjusted unallocated list
2477; SI - Pointer value to beginning of pages for handle
2478;=========================================================================
2479
2480
2481EMS_Link_Set proc near ;set contig links ;an001; dms;
2482
2483 push ax ;save regs ;an001; dms;
2484 push bx ; ;an001; dms;
2485 push cx ; ;an001; dms;
2486 push dx ; ;an001; dms;
2487 push di ; ;an001; dms;
2488
2489;;;; cmp si,cs:PAL_Free_Ptr ;at root? ;an001; dms;
2490;;;; je EMS_Link_Set_Up_Root ;yes - set up links ;an001; dms;
2491
2492;;;; mov di,cs:PAL_Free_Ptr ;get first free link ;an001; dms;
2493
2494EMS_Link_Set_Up_Search_Loop:
2495
2496;;;; shl di,1 ;get index value ;an001; dms;
2497;;;; cmp si,Page_Alloc_List[di] ;pointers match? ;an001; dms;
2498;;;; je EMS_Link_Set_Up ;yes - set up links ;an001; dms;
2499;;;; mov di,Page_Alloc_List[di] ;get next pointer ;an001; dms;
2500;;;; jmp EMS_Link_Set_Up_Search_Loop ;continue ;an001; dms;
2501
2502EMS_Link_Set_Up:
2503
2504;;;; mov ax,di ;save index value ;an001; dms;
2505;;;; mov di,si ;point to first link ;an001; dms;
2506;;;; mov dx,1 ;init loop counter ;an001; dms;
2507
2508EMS_Link_Set_Up_Loop:
2509
2510;;;; cmp dx,cx ;at end? ;an001; dms;
2511;;;; je EMS_Link_Set_Up_Loop_Exit ;yes - exit ;an001; dms;
2512
2513;;;; shl di,1 ;index value ;an001; dms;
2514;;;; mov di,Page_Alloc_List[di] ;next ptr ;an001; dms;
2515;;;; inc dx ;inc counter ;an001; dms;
2516;;;; jmp EMS_Link_Set_Up_Loop ;continue ;an001; dms;
2517
2518EMS_Link_Set_Up_Loop_Exit:
2519
2520;;;; shl di,1 ;index value ;an001; dms;
2521;;;; mov bx,Page_Alloc_List[di] ;get next link ;an001; dms;
2522;;;; mov di,ax ;get orig. link ;an001; dms;
2523;;;; mov Page_Alloc_List[di],bx ;hook up links ;an001; dms;
2524;;;; jmp EMS_Link_Set_Up_Exit
2525
2526
2527EMS_Link_Set_Up_Root:
2528
2529 mov di,si ;point to first link ;an001; dms;
2530 xor dx,dx ;init loop counter ;an001; dms;
2531
2532EMS_Link_Set_Up_Root_Loop:
2533
2534 cmp dx,cx ;at end? ;an001; dms;
2535 je EMS_Link_Set_Up_Root_Exit ;yes - exit ;an001; dms;
2536
2537 shl di,1 ;index value ;an001; dms;
2538 mov di,Page_Alloc_List[di] ;next ptr ;an001; dms;
2539 inc dx ;inc counter ;an001; dms;
2540 jmp EMS_Link_Set_Up_Root_Loop ;continue ;an001; dms;
2541
2542EMS_Link_Set_Up_Root_Exit:
2543
2544 mov cs:PAL_Free_Ptr,di ;new free ptr ;an001; dms;
2545 jmp EMS_Link_Set_Up_Exit ;exit routine ;an001; dms;
2546
2547EMS_Link_Set_Up_Exit:
2548
2549 pop di ;restore regs ;an001; dms;
2550 pop dx ; ;an001; dms;
2551 pop cx ; ;an001; dms;
2552 pop bx ; ;an001; dms;
2553 pop ax ; ;an001; dms;
2554
2555 ret ;return to caller ;an001; dms;
2556
2557EMS_Link_Set endp ; ;an001; dms;
2558
2559
2560
2561
2562;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
2563;³ ³
2564;³ LIM 4.0 functions are kept in a seperate include file, ³
2565;³ LIM40.INC ³
2566;³ ³
2567;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
2568include lim40.inc
2569
2570Instance_Table db Instance_Size*Instance_Count dup(Unallocated) ;instance table ;an000; dms;
2571
2572RESIDENT: ;last address that must stay resident
2573PAGE
2574PAGE
2575
2576INCLUDE EMSINIT.INC ;Main file for throwaway
2577 ; initialization code
2578INCLUDE XMA1DIAG.INC ;XMA 1 diagnostics and routines
2579INCLUDE PS2_5060.INC ;Diagnostics for PS/2 models 50 @RH2
2580 ; and 60. Support for XMA/A and @RH2
2581 ; MXO cards @RH2
2582INCLUDE XMA2EMS.CL1
2583
2584
2585TEMP_STACK DB STACK_SIZE DUP(0) ;RESERVE FOR TEMP STACK
2586TOP_OF_STACK DB ? ;DURING INITIALIZATION
2587
2588CSEG ENDS
2589 END START
2590
2591
diff --git a/v4.0/src/DEV/XMA2EMS/XMA2EMS.LC b/v4.0/src/DEV/XMA2EMS/XMA2EMS.LC
new file mode 100644
index 0000000..bee5cc6
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/XMA2EMS.LC
@@ -0,0 +1,11 @@
1XMA2EMS.ASM
2XMA2EMSP.INC
3DIAGS.ASM
4LIM40.INC
5LIM40B.INC
6PS2_5060.INC
7PARMPARS.INC
8EMSINIT.INC
9XMA1DIAG.INC
10GENIOCTL.INC
11 \ No newline at end of file
diff --git a/v4.0/src/DEV/XMA2EMS/XMA2EMS.SKL b/v4.0/src/DEV/XMA2EMS/XMA2EMS.SKL
new file mode 100644
index 0000000..d2a8169
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/XMA2EMS.SKL
@@ -0,0 +1,39 @@
1:class 1
2
3:use 1 xma2ems CRLF
4:use 2 xma2ems Welcome_Msg
5:use 3 xma2ems DGS_Start_Msg
6:use 4 xma2ems DGS_End_Msg
7:use 5 xma2ems Page_Frame_Msg
8:use 6 xma2ems PF_Start
9:use 7 xma2ems Conv_Pages
10:use 8 xma2ems Reserve_Msg
11:use 9 xma2ems Res_Pages
12:use 10 xma2ems Avail_Msg
13
14:use 11 xma2ems EMS_Pages
15:use 12 xma2ems XMA1_Err_Msg
16:use 13 xma2ems Not_Found_Msg
17:use 14 xma2ems Parm_Err_Msg
18:use 15 xma2ems No_Emul_Msg
19:use 16 xma2ems Wrong_Emul_Msg
20:use 17 xma2ems Wrong_XMAA_Msg
21:use 18 xma2ems Req_EMS_Err_Msg
22:use 19 xma2ems Not_Instl_Msg
23:use 20 xma2ems Conflict_Msg
24
25:use 21 xma2ems Confl_Address
26:use 22 xma2ems Hole_Msg
27:use 23 xma2ems Hole_Address
28:use 24 xma2ems Frame_Msg
29:use 25 xma2ems Frame_Address
30:use 26 xma2ems No_Pages_Msg
31:use 27 xma2ems Size_Msg1
32:use 28 xma2ems Mem_OK
33:use 29 xma2ems Next_Line
34:use 28 common Prompt_Msg
35:use 30 xma2ems XMA2EMS_Msg_Term
36:use 16 common No_EMS_Memory
37:use 30 xma2ems XMA2EMS_Msg_Term1
38
39:end
diff --git a/v4.0/src/DEV/XMA2EMS/XMA2EMSP.INC b/v4.0/src/DEV/XMA2EMS/XMA2EMSP.INC
new file mode 100644
index 0000000..fa4196f
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/XMA2EMSP.INC
@@ -0,0 +1,243 @@
1
2INCSW EQU 0 ;INCLUDE PSDATA.INC ;AN000;
3FARSW EQU 0 ;CALL THE PARSER BY NEAR CALL
4DATESW EQU 1 ; ;SUPPRESS DATE CHECKING ;AN000;
5TIMESW EQU 1 ; ;SUPPRESS TIME CHECKING ;AN000;
6FILESW EQU 1 ;SUPPORT CHECKING FILE SPECIFICATION ;AN000;
7CAPSW EQU 1 ; ;SUPPRESS FILE TABLE CAPS ;AN000;
8CMPXSW EQU 1 ; ;SUPPRESS CHECKING COMPLEX LIST
9DRVSW EQU 1 ; ;SUPPRESS SUPPORT OF DRIVE ONLY FORMAT
10QUSSW EQU 1 ; ;SUPPRESS SUPPORT OF QUOTED STRING FORMAT ;AN000;
11NUMSW EQU 1 ; ;SUPPRESS CHECKING NUMERIC VALUE
12KEYSW EQU 1 ;SUPPORT KEYWORDS ;AN000;
13SWSW EQU 1 ;DO SUPPORT SWITCHES ;AN000;
14VAL1SW EQU 1 ;SUPPORT VALUE DEFINITION 1 ;AN000;
15VAL2SW EQU 1 ; ;SUPPRESS SUPPORT OF VALUE DEFINITION 2 ;AN000;
16VAL3SW EQU 1 ;DO SUPPORT VALUE DEFINITION 3
17
18include psdata.inc
19
20;***********************************************************************
21
22;-------------------------------------------------------------------
23;
24; parser stuff for XMA2EMS.SYS
25;
26;-------------------------------------------------------------------
27
28p_block:
29 dw offset px_block ; address of extended parms block
30 db 0 ; number of extra stuff
31
32;$P_PARMS_Blk <offset px_block, 0, 0> ; parm block
33
34;------------------------
35; extended parameter block for APPEND first load
36
37px_block:
38 db 1 ; min number positional operands
39 db 1 ; max number positional operands
40 dw offset dummy_ctl ; dummy control block
41
42 db 1 ; /X only switch
43 dw offset X_Switch ; control block for /X switch
44
45 db 7 ; max number of keywords
46 dw offset frame_ctl ; offset of FRAME= keyword control block
47 dw offset p0_ctl ; offset of p0 keyword control block
48 dw offset p1_ctl ; offset of p1 keyword control block
49 dw offset p2_ctl ; offset of p2 keyword control block
50 dw offset p3_ctl ; offset of p3 keyword control block
51 dw offset p254_ctl ; offset of p254 keyword control block
52 dw offset p255_ctl ; offset of p255 keyword control block
53
54;------------------------
55
56dummy_ctl:
57 dw 0200h ;
58 dw 0 ; no caps
59 dw offset dum_result ; pointer to dummy result block
60 dw offset dum_values ; pointer to null values block
61 db 0 ; number of switches and synonyms
62
63dum_values:
64 dw 0 ; null value list
65
66X_Switch:
67 dw $P_Num_Val ; /X:64
68 dw 0002 ; caps
69 dw offset X_Result ; pointer to result block
70 dw offset X_Values ; pointer to values block, none
71 db 1 ; number of switches and synonyms
72 db "/X",0 ; only /X is valid
73
74X_Values:
75 db 1 ; numeric values
76 db 1 ; 1 ranges
77 db 1 ; = 1 means good range
78 dd 4 ; valid values range from 4 (64Kb)...
79 dd 512 ; 512 (8MB)
80
81;------------------------
82
83frame_ctl:
84 dw $P_Simple_S ; used for FRAME= and Pxxx=
85 dw 0 ; cap by char table
86 dw offset frame_result ; pointer to result block
87 dw offset address_values ; pointer to values block
88 db 1 ; number of synonyms
89 db "FRAME=",0
90
91p0_ctl:
92 dw $P_Simple_S ; used for FRAME= and Pxxx=
93 dw 0 ; cap by char table
94 dw offset p0_result ; pointer to result block
95 dw offset address_values ; pointer to values block
96 db 3 ; number of synonyms
97 db "P0=",0
98 db "P00=",0
99 db "P000=",0
100
101p1_ctl:
102 dw $P_Simple_S ; used for FRAME= and Pxxx=
103 dw 0 ; cap by char table
104 dw offset p1_result ; pointer to result block
105 dw offset address_values ; pointer to values block
106 db 3 ; number of synonyms
107 db "P1=",0
108 db "P01=",0
109 db "P001=",0
110
111p2_ctl:
112 dw $P_Simple_S ; used for FRAME= and Pxxx=
113 dw 0 ; cap by char table
114 dw offset p2_result ; pointer to result block
115 dw offset address_values ; pointer to values block
116 db 3 ; number of synonyms
117 db "P2=",0
118 db "P02=",0
119 db "P002=",0
120
121p3_ctl:
122 dw $P_Simple_S ; used for FRAME= and Pxxx=
123 dw 0 ; cap by char table
124 dw offset p3_result ; pointer to result block
125 dw offset address_values ; pointer to values block
126 db 3 ; number of synonyms
127 db "P3=",0
128 db "P03=",0
129 db "P003=",0
130
131p254_ctl:
132 dw $P_Simple_S ; used for FRAME= and Pxxx=
133 dw 0 ; cap by char table
134 dw offset p254_result ; pointer to result block
135 dw offset address_values ; pointer to values block
136 db 1 ; number of synonyms
137 db "P254=",0
138
139p255_ctl:
140 dw $P_Simple_S ; used for FRAME= and Pxxx=
141 dw 0 ; cap by char table
142 dw offset p255_result ; pointer to result block
143 dw offset address_values ; pointer to values block
144 db 1 ; number of synonyms
145 db "P255=",0
146
147;------------------------
148
149address_values:
150 db 3 ; strings
151 db 0 ; zeroes here for ranges
152 db 0 ; and values
153 db 24 ; 24 possible strings
154 db 0A0h
155 dw offset A0_str
156 db 0A4h
157 dw offset A4_str
158 db 0A8h
159 dw offset A8_str
160 db 0ACh
161 dw offset AC_str
162 db 0B0h
163 dw offset B0_str
164 db 0B4h
165 dw offset B4_str
166 db 0B8h
167 dw offset B8_str
168 db 0BCh
169 dw offset BC_str
170 db 0C0h
171 dw offset C0_str
172 db 0C4h
173 dw offset C4_str
174 db 0C8h
175 dw offset C8_str
176 db 0CCh
177 dw offset CC_str
178 db 0D0h
179 dw offset D0_str
180 db 0D4h
181 dw offset D4_str
182 db 0D8h
183 dw offset D8_str
184 db 0DCh
185 dw offset DC_str
186 db 0E0h
187 dw offset E0_str
188 db 0E4h
189 dw offset E4_str
190 db 0E8h
191 dw offset E8_str
192 db 0ECh
193 dw offset EC_str
194 db 0F0h
195 dw offset F0_str
196 db 0F4h
197 dw offset F4_str
198 db 0F8h
199 dw offset F8_str
200 db 0FCh
201 dw offset FC_str
202
203
204
205A0_str db "A000",0
206A4_str db "A400",0
207A8_str db "A800",0
208AC_str db "AC00",0
209B0_str db "B000",0
210B4_str db "B400",0
211B8_str db "B800",0
212BC_str db "BC00",0
213C0_str db "C000",0
214C4_str db "C400",0
215C8_str db "C800",0
216CC_str db "CC00",0
217D0_str db "D000",0
218D4_str db "D400",0
219D8_str db "D800",0
220DC_str db "DC00",0
221E0_str db "E000",0
222E4_str db "E400",0
223E8_str db "E800",0
224EC_str db "EC00",0
225F0_str db "F000",0
226F4_str db "F400",0
227F8_str db "F800",0
228FC_str db "FC00",0
229
230;------------------------
231
232dum_result $P_Result_Blk <> ; dummy result block
233X_Result $P_Result_Blk <> ; /X result block
234frame_result $P_Result_Blk <> ; FRAME= result block
235p0_result $P_Result_Blk <> ; p0= result block
236p1_result $P_Result_Blk <> ; p1= result block
237p2_result $P_Result_Blk <> ; p2= result block
238p3_result $P_Result_Blk <> ; p3= result block
239p255_result $P_Result_Blk <> ; p254= result block
240p254_result $P_Result_Blk <> ; p255= result block
241
242
243 \ No newline at end of file