2 PAGE
85,132 ;Set for 5182 Pageprinter
3 ;85 lines per page, 132 col per line
6 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
8 ;º This is the new version of the XMA2EMS driver for DOS 3.3. º
9 ;º It contains the following revisions and code flags: º
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 º
21 ;º AN007 P5134 - Provide variable planar size support. º
22 ;º Modify linked list to forward link vs. the º
23 ;º reverse linked list. º
25 ;º AN008 P5150 - Fix incorrect access of slot 0 when no º
26 ;º Catskill/Holster card is in slot 0. º
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 º
45 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
47 ;XMA2EMS provides a Lotus/Intel/Microsoft Expanded Memory (EMS) interface
48 ;for the IBM Expanded Memory Adapter (XMA).
50 ;Program Property of Microsoft
52 ;Add the following statement to CONFIG.SYS
53 ; DEVICE=[d:][path]XMA2EMS.SYS
56 ;-----------------------------------------------------------------------;
58 ;-----------------------------------------------------------------------;
59 EMS_INT EQU 67H
;EMS INTERRUPT
60 EM_INT EQU 15H
;EM INTERRUPT ;an000; dms;
61 DK_Int equ 13h
;disk interrupt ;an004; dms;
62 EM_Size_Get EQU 88h
;get EM size ;an000; dms;
63 EMM_VERSION EQU 40H
;VERSION 4.0
64 PF_HI_LIMIT EQU
0E000H ;highest allowable page frame segment
65 PF_LOW_LIMIT EQU
0A000H ;lowest allowable page frame segment
66 OK EQU
'OK' ;card is good
67 HW_ERROR EQU
'HW' ;card is not functional...HardWare error
68 SW_ERROR EQU
'SW' ;SoftWare error has been detected
69 PAGE_INHIBITTED EQU
0FFFFh ;Entry in the save area indicating
70 ; a page is currently inhibitted
71 REUSABLE_HANDLE EQU
'HR' ;Reusable (free) entry in the @RH1
72 ; handle lookup table. Placed in @RH1
73 ; the 'pages' field @RH1
74 REUSABLE_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 #
82 UNALLOCATED EQU
'U' ; Unused entry
83 ALLOCATED EQU
'X' ; Temporary...used by reallocate @RH4
84 PAL_NULL EQU
'--' ; End of list marker @RH8
85 EXTENDED EQU
'ME' ; Extended memory (not for EMS use)@RH8
86 BACMEM_ALLOC EQU
'MB' ; Allocated to back conventional @RH8
87 ; memory (back disabled planar)
88 WSP_ALLOC EQU
'SW' ; Allocated to Workstation Program @RH8
89 ; Pages kept as extended memory by:
90 RESR_EXT EQU
'ER' ; /E parameter
91 PREV_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)
95 WARM_MASK EQU
1 ;ISOLATE WARM START BIT
96 OFFSET_IN_XREF EQU
BYTE PTR[BX+SI]
97 LENGTH_IN_XREF EQU
BYTE PTR[BX+SI+1]
98 PAGE_LIST_ENTRY EQU
WORD PTR[SI + OFFSET PAGE_ALLOC_LIST
] ; @RH8
99 page_table_entry EQU
byte PTR[SI + OFFSET PAGE_ALLOC_table
] ;temp for assembl
100 XREF_TABLE_ENTRY EQU
word PTR[DI + OFFSET HANDLE_XREF_TABLE
] ; @RH1
101 NUM_PHYSICAL_PAGES EQU
4
103 Instance_Size EQU
150 ;instance size ;an000; dms;
104 Instance_Count EQU
3 ;number of instances ;an000; dms;
106 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
107 ;³ Common memory adapter declares ³
108 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
109 SLOT_SETUP EQU
08h ;Mask to put the desired adapter @RH2
110 ; slot into setup mode, activating @RH2
111 ; the 10X registers @RH2
112 CARD_ID_LO EQU 100H
;PS/2 Adapter card id low and @RH2
113 CARD_ID_HI EQU 101H
; high bytes - read only @RH2
114 ;Card IDs read from port 100,101 @RH2
115 XMAA_CARD_ID EQU
0FEF7h ; XMA/A Card ID @RH2
116 HLST_CARD_ID EQU
0FEFEh ; MXO @RH3
117 NO_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
121 XMA1_VIRT EQU
00000001B ; XMA 1...always in virtual
122 XMAA_VIRT EQU
00000010B ; XMA/A card (PS/2) in virtual
123 EMUL_VIRT EQU
00000100B ; XMA emulator on 80386 @RH7
124 XMAA_REAL EQU
00001000B ; XMA/A in real mode...no banking @RH3
125 HOLS_REAL EQU
00010000B ; MXO card @RH3
127 XMA1A_VIRT EQU
00000011B ; XMA1 or XMA/A in virtual mode
128 WSP_VIRT EQU
00000111B ; Any virtual mode...banking used
130 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
131 ;³ XMA, XMA\A, and XMA emulator declares ³
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: ³
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 ³
144 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
145 ;All are byte ports unless indicated
147 X_CTRL_REG EQU 102H
;Control register - en/disable functions
148 X_CONF_REG EQU 105H
;Config (mem size), channel check reg.
149 RM_TTPTR_LO EQU 106H
;Translate table pointer low and
150 RM_TTPTR_HI EQU 107H
; high bytes
151 RM_TTDATA_LO EQU 103H
;TT data - high and low bytes
152 RM_TTDATA_HI EQU 104H
; Low byte (103) auto incs the TT ptr
154 ;Virtual mode port addresses for:
155 TTPOINTER EQU 31A0H
; Translate Table Pointer (word)
156 TTDATA EQU 31A2H
; Translate Table Data (word)
157 AIDATA EQU 31A4H
; TT Data with auto increment (word)
158 IDREG EQU 31A6H
; Bank ID register
159 MODE_REG EQU 31A7H
; Mode register
160 DMACAPT EQU 31A8H
; DMA capture register
162 CR_ROMSLEEP_DIS EQU
11011111B ;XMA/A control register mask to
163 ; disable the ROM on XMA/A card
164 XMA_TT_INHIBIT EQU
0000100000000000B ;XMA mask for an inhibitted TT entry
165 XMA_TT_MASK EQU
0000111111111111B ;XMA mask for anding off unused bits
166 EMUL_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.
174 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
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: ³
182 ;³ 8 Inhibit bit (0 = inhibit xlate) ³
183 ;³ 7-0 Pointer to 16K block for up to ³
184 ;³ 2 meg capability ³
186 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
188 H_CARD_INFO EQU 102H
;Info Bits 7-1 mem size Bit 0 sleep
189 H_CC_PRES EQU 105H
;Channel check, presence (Bit 0)
190 H_TTPTR_LO EQU 106H
;Translate table pointer low and
191 H_TTPTR_HI EQU 107H
; high bytes
192 H_TTDATA EQU 103H
;TT data - one byte. No auto inc.
194 H_TT_INHIBIT EQU
00000000B ;MXO value for setting inhibitted
195 ; translate table entry
196 H_TT_ENBMASK EQU
10000000B ;Pattern to test if TT entry read is
197 ; enabled. 'and' with entry,jz inhib
200 EMS_CODE80 EQU 80H
; Sotware malfunction
201 EMS_CODE81 EQU 81H
; Hardware malfunction
202 EMS_CODE82 EQU 82H
; This return code not used
203 EMS_CODE83 EQU 83H
; Handle not found
204 EMS_CODE84 EQU 84H
; Invalid function code
205 EMS_CODE85 EQU 85H
; All handles used
206 EMS_CODE86 EQU 86H
; Save or restore mapping error
207 EMS_CODE87 EQU 87H
; Not enough pages to satisfy request
208 EMS_CODE88 EQU 88H
; Not enough unallocated pages
209 EMS_CODE89 EQU 89H
; Can't allocate zero pages
210 EMS_CODE8A EQU 8
AH ; Logical page out of range
211 EMS_CODE8B EQU 8
BH ; Physical page out of range
212 EMS_CODE8C EQU 8
CH ; Hardware save area is full
213 EMS_CODE8D EQU 8
DH ; Save area already saved for handle
214 EMS_CODE8E EQU 8EH
; Save area not saved for this handle
215 EMS_CODE8F EQU 8FH
; Subfunction parameter not defined
216 ;-------------------------------------------------------------------
218 EMS_CODE92 EQU
092H ; added for DMS ;an000;
219 EMS_CODE93 EQU
093H ;an000;
220 EMS_CODE94 EQU
094H ;an000;
221 EMS_CODE95 EQU
095H ;an000;
222 EMS_CODE96 EQU
096H ;an000;
223 EMS_CODE97 EQU
097H ;an000;
224 EMS_CODE98 EQU
098H ;an000;
225 EMS_CODE9E EQU
09EH ;an000;
226 EMS_CODE9C EQU
09CH ;an000;
227 ;------------------------------------------------------------------- ;an000;
228 EMS_CODEA0 EQU
0A0h ; No matching handle
229 EMS_CODEA1 EQU
0A1h ; Duplicate handle name
230 EMS_CODEA2 EQU
0A2h ; Memory wrap error
231 EMS_CODEA3 EQU
0A3h ; Data in control structure corrupted
232 EMS_CODEA4 EQU
0A4h ; Access to this function denied
234 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
235 ;³ Request Header (Common portion) ³
237 ;³ This structure defines the portion that is common to ³
238 ;³ all Request Headers. ³
240 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
241 RH EQU
DS:[BX] ;addressability to Request Header structure
243 RHC
STRUC ;fields common to all request types
244 DB ?
;length of Request Header (including data)
245 DB ?
;unit code (subunit)
246 RHC_CMD
DB ?
;command code
248 DQ ?
;reserved for DOS
249 RHC ENDS
;end of common portion
251 CMD_INPUT EQU
4 ;RHC_CMD is INPUT request
253 ;status values for RHC_STA
255 STAT_GOOD EQU
0000H ;invalid command code error
256 STAT_DONE EQU
0100H ;function complete status (OR on bit)
257 STAT_CMDERR EQU 8003H
;invalid command code error
258 STAT_CRC EQU 8004H
;CRC error
259 STAT_SNF EQU 8008H
;sector not found error
260 STAT_GENFAIL EQU 800
CH ;general failure
261 NOT_BUSY EQU
11111101B ;busy bit (9) NOT BUSY mask (high order byte)
262 BUSY_MASK EQU
00000010B ;busy bit (9) BUSY mask (high order byte)
264 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
265 ;³ Request Header for INIT command ³
267 ;³ This structure defines the Request Header for the ³
270 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
272 DB (TYPE RHC
) DUP (?
) ;common portion
274 RH0_NUN
DB ?
;number of units
275 ;set to 1 if installation succeeds,
276 ;set to 0 to cause installation failure
277 RH0_ENDO
DW ?
;offset of ending address
278 RH0_ENDS
DW ?
;segment of ending address
279 RH0_BPBO
DW ?
;offset of BPB array address
280 RH0_BPBS
DW ?
;segment of BPB array address
281 RH0_DRIV
DB ?
;drive code (DOS 3 only)
282 RH0_ERR
DW 0 ; error flag used by DOS - gga
285 RH0_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
288 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
289 ;³ Request Header for OUTPUT STATUS command ³
291 ;³ This structure defines the Request Header for the ³
292 ;³ Output Status command. ³
293 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
295 DB (TYPE RHC
) DUP (?
) ;common portion
299 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
300 ;³ Request Header for Generic IOCTL Request ³
301 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
304 DB (TYPE RHC
) DUP (?
) ; Reserve space for the header @RH6
306 RH19_MAJF
DB ?
; Major function @RH6
307 RH19_MINF
DB ?
; Minor function @RH6
308 RH19_SI
DW ?
; Contents of SI @RH6
309 RH19_DI
DW ?
; Contents of DI @RH6
310 RH19_RQPK
DD ?
; Pointer to Generic IOCTL request packet @RH6
314 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
315 ;³ Map EMS INT 67H vector in low storage ³
317 ;³ The vector for the interrupt handler for INT 67H ³
318 ;³ is defined here. ³
319 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
320 INT_VEC
SEGMENT AT 00H
323 EMS_VECO
DW ?
;offset
324 EMS_VECS
DW ?
;segment
327 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
328 ;³ Map EM INT 15H vector in low storage ³
330 ;³ The vector for the extended memory interrupt handler INT 15h ³
331 ;³ is defined here. ³
332 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
333 INT_VEC15
SEGMENT AT 00H ;an000; dms;
334 ORG 4*EM_INT
;an000; dms;
335 EM_VEC
LABEL DWORD ;an000; dms;
336 EM_VECO
DW ?
;offset ;an000; dms;
337 EM_VECS
DW ?
;segment ;an000; dms;
338 INT_VEC15 ENDS
;an000; dms;
341 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
342 ;³ Map INT 13h vector in low storage ³
344 ;³ The vector for the disk access interrupt handler INT 13h ³
345 ;³ is defined here. ³
346 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
347 INT_VEC13
SEGMENT AT 00H ;an004; dms;
348 ORG 4*DK_INT
;an004; dms;
349 DK_VEC
LABEL DWORD ;an004; dms;
350 DK_VECO
DW ?
;offset ;an004; dms;
351 DK_VECS
DW ?
;segment ;an004; dms;
352 INT_VEC13 ENDS
;an004; dms;
354 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
355 ;º This marks the start of the device driver code segment º
356 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
358 CSEG
SEGMENT PARA
PUBLIC 'CODE'
361 START EQU
$ ;begin resident XMA2EMS data & code
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
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 ;-----------------------------------------------------------------------;
375 EMS_START_IN_XMA
DW 0 ;initially, memory manager uses all
377 ;-----------------------------------------------------------------------;
378 ; The following is the Code Label:
379 ;-----------------------------------------------------------------------;
380 COPYRIGHT
DB '74X9921 (C)COPYRIGHT 1988 Microsoft '
381 DB 'LEVEL 1.00 LICENSED MATERIAL - PROGRAM '
382 DB 'PROPERTY OF Microsoft '
384 ;-----------------------------------------------------------------------;
385 ; Request Header (RH) address, saved here by "strategy" routine ;
386 ;-----------------------------------------------------------------------;
389 RH_PTRS
DW ?
;segment
390 db 7 dup(0) ;align following tables on seg.
392 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
393 ;³ HANDLE LOOKUP TABLE ³
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. ³
402 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
403 H_LOOKUP_STRUC
STRUC ;Structure for Handle lookup table @RH1
404 H_PAGES
DW REUSABLE_HANDLE
;If handle is active, # of owned @RH8
405 ; pages. Init to reusable handle RH8
406 H_PAL_PTR
DW PAL_NULL
;Head ptr for owned pages in PAL @RH8
407 H_NAME
DB 8 DUP(0) ;Name - new for LIM 4.0 @GGA
408 H_BANK
DB 0 ;If virtual, this handle's bank @RH6
409 xref_pages dw 0 ;temp to compile
410 xref_index dw 0 ;temp to compile
413 NUM_HANDLES EQU
64 ;One structure @RH1
414 HANDLE_LOOKUP_TABLE H_LOOKUP_STRUC
<0,,,,,> ; initialize handle 0
415 H_LOOKUP_STRUC NUM_HANDLES
-1 DUP (<>) ; for OS use - gga
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 ;-----------------------------------------------------------------------;
423 XREF_TABLE_LEN EQU
2048 ; @RH1
425 HANDLE_XREF_TABLE
DW XREF_TABLE_LEN
DUP(0) ; Changed from byte to @RH1
427 XREF_TABLE_END EQU
($) ;Used for table shift on deallocate @RH1
428 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
429 ;³ PAGE ALLOCATION LIST ³
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 ³
443 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
444 EMS_PAGES_SUPPORTED EQU
1024 ;Support up to 16 Megabytes of EMS @RH8
446 PAGE_ALLOC_LIST
DW EMS_PAGES_SUPPORTED
DUP(0)
447 ;Page Allocation List (PAL) @RH8
448 page_alloc_table db 1024 dup(unallocated
) ;temp for assemble
449 ;-----------------------------------------------------------------------;
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 ;-----------------------------------------------------------------------;
457 H_SAVEA_ENTRY
STRUC ;This is an overlay for one page's @RH5
458 HSA_HNDL
DW ?
; entry in the handle save area. @RH5
459 HSA_LP
DW ?
; It is used to clear the save @RH5
460 H_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
465 H_SAVE_STRUC
STRUC ;Structure for Handle Save Area @RH1
467 PG0_LP
DW REUSABLE_SAVEA
469 PG1_LP
DW REUSABLE_SAVEA
471 PG2_LP
DW REUSABLE_SAVEA
473 PG3_LP
DW REUSABLE_SAVEA
474 PGFE_HNDL
DW 0 ;AN006;
475 PGFE_LP
DW REUSABLE_SAVEA
;AN006;
476 PGFF_HNDL
DW 0 ;AN006;
477 PGFF_LP
DW REUSABLE_SAVEA
;AN006;
480 HANDLE_SAVE_AREA H_SAVE_STRUC NUM_HANDLES
DUP (<>)
481 ;One structure for each handle @RH1
483 H_SAVE_ENTRY EQU
WORD PTR[DI + OFFSET HANDLE_SAVE_AREA
] ; @RH1
486 ;-------------------------------------------------------------------
488 ; mappable_phys_page table
490 ; This table is used by function 5800h
492 ;-------------------------------------------------------------------
494 mappable_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
499 mappable_phys_page_struct ENDS
501 ; allocate the storage
503 map_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
510 map_count_def equ
6 ; default 6
512 map_size dw type mappable_phys_page_struct
* map_count_def
; size of default table
513 ppm_size equ
6 ;size of partial page map entry
515 ; flags and a word used in setting up map_table stuff, see parmpars.inc
517 p0_flag equ
0001h ; flags used to indicate which p's were
518 p1_flag equ
0002h ; set on command line
523 frame_flag equ 8000h
; special flag used when FRAME= was found
525 page_flags dw 0 ; word of above flags used in setting map_table
526 parse_flag dw 0 ; flag used to indicate command line args were encountered
528 ;-------------------------------------------------------------------
530 ;-------------------------------------------------------------------
535 rom_scan_type dw micro_channel
;
536 segment_error dw 0 ; segment error flag = 0 means all OK
538 ;-----------------------------------------------------------------------
539 ; Tables added for multicard support º
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. º
546 ;-----------------------------------------------------------------------
547 ;-----------------------------------------------
548 ; Memory Card Descriptor Table º
549 ;-----------------------------------------------
551 MEM_CARD_STRUC
STRUC ;Structure for the memory cards @RH5
552 CARD_ID
DW NO_CARD
;Card ID from ports 100 and 101 @RH5
553 CARD_SLOT
DB ?
;Physical slot of card (0 based) @RH5
554 START_PG_NUM
DW ?
;Starting and ending #s of the @RH5
555 END_PG_NUM
DW ?
; pages this card has within the @RH5
556 MEM_CARD_STRUC ENDS
; total EMS page pool (0 based) @RH5
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
562 MAX_SLOTS EQU
8 ;Max of 8, but most @RH5
563 MEM_CARD_TABLE MEM_CARD_STRUC MAX_SLOTS
DUP (<>) ; likely 1 or 2 cards @RH5
565 ;-----------------------------------------------
566 ; Multicard Page Frame Descriptor Table º
567 ;-----------------------------------------------
568 MULTIC_PM_STRUC
STRUC ;Structure for storing the card ID @RH5
569 PG_CARD
DW NO_CARD
; and slot of the card currently @RH5
570 PG_SLOT
DB 0 ; mapped to this page of the page @RH5
571 MULTIC_PM_STRUC ENDS
; frame @RH5
573 ;Multicard Page Mapping Table.
574 ; Entry for each page of the page
575 ; frame (including pages FE & FF)
576 MC_PM_TABLE MULTIC_PM_STRUC MAP_COUNT_DEF
DUP (<>)
578 ;-----------------------------------------------
579 ; Assorted Multicard declares º
580 ;-----------------------------------------------
582 NUM_OF_SLOTS
DB ?
;Number of adapter slots RR 8 TB 4 @RH2
583 WTT_CARD_SLOT
DB ?
;Slot # of the memory card being @RH2
584 ; used to map a page @RH2
587 Instance_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;
590 Instance_Entry_Struc ends
;end struc ;an000; dms;
592 ;-----------------------------------------------------------------------;
593 ; Table of DOS command processing routine entry points ;
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 ;-----------------------------------------------------------------------;
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;
624 MAX_CMD EQU
($-CMD_TABLE
)/2 ;highest valid command follows
625 DW OFFSET SET_LOG_DEVICE
;24 - Invalid IOCTL function gga ;AN003;
627 ;-----------------------------------------------------------------------;
628 ; Table of Expanded Memory Manager routine entry points ;
629 ;-----------------------------------------------------------------------;
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
648 ;------------------------------------------------------------------- ;GGA
649 ; these functions were added for LIM 4.0 support ;GGA
650 ;------------------------------------------------------------------- ;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
666 MAX_FCN EQU
($-FCN_TABLE
)/2 ; highest valid command follows ;GGA
667 dw offset enable_os
; 5D - enable/disable OS/E functions ;GGA
669 ;-----------------------------------------------------------------------;
670 ; Data variables go here ;
671 ;-----------------------------------------------------------------------;
672 PAGE_FRAME_STA
DW 0D000H ;STARTING SEG OF PAGE FRAME
673 TOTAL_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.
677 TOTAL_EMS_PAGES
DW 1024/16 ;Pages left after conventional
679 FREE_PAGES
DW 1024/16 ;Total unallocated pages for EMS use
680 EM_Ksize dw ?
;size in Kb of extended memory ;an000; dms;
681 CARD_STATUS
DW 'OK' ;STATUS OF THE HARDWARE
682 ; DEFAULT='OK' FAILURE='HW'
683 MANAGER_STATUS
DW 'OK' ;STATUS OF THE MEMORY MANAGER
684 ; DEFAULT='OK' FAILURE='SW'
685 STARTING_BLOCK
DW 0 ;number of 4K blocks reserved by pinta
687 WARM_START
DB 'N' ;initially not a warm start
688 MULTIPLIER
DW ?
;Used for figuring table offsets @RH1
689 TEN
DW 10 ; via multiplication...not the @RH1
690 SIXTEEN
DW 16 ; most efficient, but flexible @RH1
691 MEMCARD_MODE
DB XMA1_VIRT
;Flag indicating the type of memory@RH2
692 ; card being used. Default to @RH2
694 BANKID
DB ?
;Current XMA Bank ID @RH1
695 BLOCKS_PER_PAGE
DW 4 ;XMA blocks per EMS page (multiply)@RH1
696 SEG_PER_PAGE
DW 1024 ;Segments(16 bytes) per EMS page @RH1
698 INTV15
LABEL DWORD ;an000; dms;
699 INTV15O
DW ?
;offset ;an000; dms;
700 INTV15S
DW ?
;segment ;an000; dms;
702 INTV13
LABEL DWORD ;an004; dms;
703 INTV13O
DW ?
;offset ;an004; dms;
704 INTV13S
DW ?
;segment ;an004; dms;
706 PAL_FREE_PTR
DW PAL_NULL
707 ;-------------------------------------------------------------------
708 ; define some flags and storage for the enable/disable functions
709 ;-------------------------------------------------------------------
711 ose_enabled equ
1 ; flags used to enable/disable OS/E fcns ;an000;
712 ose_disabled equ
0 ;an000;
714 access_code dd 0 ; access code used by OS/E functions ;an000;
715 ose_functions dw ose_enabled
; OS/E functions 1 = enabled, 0 = disabled ;an000;
717 ;-------------------------------------------------------------------
718 ; define some storage for the ROM scan logic
719 ;-------------------------------------------------------------------
720 where_to_start dw 0a000h ; start ROM scan at A000
723 ;-----------------------------------------------------------------------;
724 ; INT 15H Interrupt Handler routine ;
725 ;-----------------------------------------------------------------------;
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.
732 ; Service - Function 8800h: Obtains the size of EM from the word
734 ; Call With: AX - 8800h
735 ; Returns : AX - Kbyte size of EM
737 ;=========================================================================
738 XMA_INT15 PROC
;an000; dms;
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
746 XMA_INT15_Jump: ;an000; dms;
748 jmp cs:INTV15
;an000; dms;jump to org. vector
750 XMA_INT15_Exit: ;an000; dms;
755 XMA_INT15 ENDP
;an000; dms;
757 include I13HOOK
.INC ;an004; dms;
760 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
761 ;º Device "strategy" entry point º
763 ;º Retain the Request Header address for use by Interrupt routine º
764 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
766 MOV CS:RH_PTRO
,BX ;offset
767 MOV CS:RH_PTRS
,ES ;segment
772 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
773 ;º DOS Device "interrupt" entry point º
774 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
775 IRPT PROC
FAR ;device interrupt entry point
776 PUSH DS ;save all registers Revised
784 ;BP isn't used, so it isn't saved
785 CLD ;all moves forward
787 LDS BX,CS:RH_PTRA
;get RH address passed to "strategy" into DS:BX
789 MOV AL,RH
.RHC_CMD
;command code from Request Header
790 CBW ;zero AH (if AL > 7FH, next compare will
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
799 MOV RH
.RHC_STA
,STAT_GOOD
;initialize return to "no error"
801 ADD AX,AX ;double command code for table offset
802 MOV DI,AX ;put into index register for JMP
804 ;At entry to command processing routine:
805 ; DS:BX = Request Header address
806 ; CS = VDISK code segment address
809 CALL CS:CMD_TABLE
[DI] ;call routine to handle the command
812 IRPT_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
825 RET ;far return back to DOS
828 include genioctl
.inc ; include code for genioctl fcn gga
830 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
831 ;º Set 'OUTPUT STATUS' entry point º
832 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
833 OUTPUT_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
837 AND AH,NOT_BUSY
;turn off busy bit
839 MOV RH
.RHC_STA
,AX ;write it back to request header
845 IRPT_CMD_ERROR: ;CALLed for unsupported character mode commands
847 MEDIA_CHECK: ;Media check
849 INPUT_IOCTL: ;IOCTL input
851 INPUT_NOWAIT: ;Non destructive input no wait
852 INPUT_STATUS: ;Input status
853 INPUT_FLUSH: ;Input flush
855 OUTPUT_VERIFY: ;Output with verify
856 OUTPUT_FLUSH: ;Output flush
857 OUTPUT_IOCTL: ;IOCTL output
858 DEVICE_OPEN: ;Device OPEN
859 DEVICE_CLOSE: ;Device CLOSE
860 REMOVABLE_MEDIA: ;Removable media
861 INVALID_FCN: ; invalid IOCTL function ;AN003;
862 GET_LOG_DEVICE: ; get logical device ;AN003;
863 SET_LOG_DEVICE: ; set logical device ;AN003;
869 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
870 ;º Entry point for EMM interrupt handler º
873 ;º The interrupt vector 67H points here. º
876 ;º The AH register contains the function number and the º
877 ;º necessary parameters are passed in registers defined º
878 ;º by the Expanded Memory Specification. º
881 ;º (AH) = 0 if no error º
882 ;º (AH) = error # if error º
884 ;º other register contain information as specified by EMSº
885 ;º otherwise all registers remain unchanged º
886 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
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;
892 mov cs:[bp].IE_Saved_DI_Reg
,di ;save reg in instance table ;an000; dms;
895 SUB AH,40H
;adjust to range of fcn table
899 CMP AH,MAX_FCN
;too high?
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
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
914 JMP CS:FCN_TABLE
[DI] ;call routine handler
917 MOV AH,EMS_CODE84
;function call out of range
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;
928 pop bp ;restore instance pointer ;an000; dms;
930 IRET ;end of interrupt 67
935 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
936 ;º Entry point for EMM STATUS Function 1 º
938 ;º on entry: (AH) = '40'x º
940 ;º on exit: (AH) = status º
941 ;º all other registers preserved º
942 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
944 CMP MANAGER_STATUS
,SW_ERROR
;is manager ok?
947 MOV AH,EMS_CODE80
;indicate bad status
951 CMP CARD_STATUS
,HW_ERROR
;is card ok?
954 MOV AH,EMS_CODE81
;indicate bad status
958 XOR AH,AH ;set good return status
960 RET ;return to caller
964 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
965 ;º Entry point for GET PAGE FRAME Function 2 º
967 ;º on entry: (AH) = '41'x º
969 ;º on exit: (AH) = status º
970 ;º (BX) = segment address of page frame º
971 ;º all other registers preserved º
972 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
974 push cx ;save regs ;an000; dms;
975 push dx ; ;an000; dms;
976 push si ; ;an000; dms;
978 cmp cs:Map_Count
,4 ;enough frames? ;an000; dms;
979 jb Q_Page_Frame_Error_Exit
;no - exit with error ;an000; dms;
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;
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;
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;
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;
1000 xor ah,ah ;set good return ;an000; dms;
1001 jmp Q_Page_Exit
;exit the routine ;an000; dms;
1003 Q_Page_Frame_Error_Exit:
1005 mov ah,EMS_Code80
;signal software error ;an000; dms;
1009 pop si ;restore regs ;an000; dms;
1010 pop dx ; ;an000; dms;
1011 pop cx ; ;an000; dms;
1017 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
1018 ;º Entry point for QUERY TOTAL & UNALLOCATED PAGES Function 3 º
1020 ;º on entry: (AH) = '42'x º
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 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
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
1041 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
1042 ;º Entry point for GET HANDLE AND ALLOCATE Function 4 º
1044 ;º on entry: (AH) = '43'x º
1045 ;º (BX) = number of pages to allocate º
1047 ;º on exit: (AH) = status º
1049 ;º AX,DX Revised...all other registers preserved º
1050 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
1056 PUSH DS ;save these registers
1061 ;Remove test for BX = 0. This is @RH4
1062 ; valid under LIM 4.0
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;
1071 CMP BX,TOTAL_EMS_PAGES
;Enough total EMS pages?
1077 cli ;ints off ;an000; dms;
1078 CMP BX,FREE_PAGES
;Enough unallocated pages?
1079 sti ;ints on ;an000; dms;
1083 ;-----------------------------------------------------
1084 ; Search for a free handle @RH1 º
1085 ;-----------------------------------------------------
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 ;--------------------------------
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
1102 MOV AH,EMS_CODE85
;no available handles
1103 JMP GH_EXIT
;go to exit ;GGA
1105 ;-----------------------------------------------------
1106 ; If here then there's enough pages for request. @RH1 º
1107 ; DX = handle #, DI = ptr to hndl lookup entry @RH1 º
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
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
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
1129 GH_CALCHLUP: ;calculate entry in hndl lkup tbl @RH1
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;
1141 call EMS_Link_Set
;set up links ;an001; dms;
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;
1148 sti ;ints on ;an001; dms;
1149 xor ah,ah ;clear flag ;an000; dms;
1164 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
1165 ;º Entry point for MAP LOGICAL TO PHYSICAL PAGE Function 5 º
1167 ;º on entry: (AH) = '44'x º
1168 ;º (AL) = physical page j º
1169 ;º (BX) = logical page i º
1172 ;º on exit: (AH) = status º
1173 ;º all other registers preserved º
1174 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
1182 PUSH DS ;save these registers
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
1193 CMP DX,NUM_HANDLES
-1 ;handle within range ?
1195 MOV AH,EMS_CODE83
;handle not found
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
1204 pop dx ;restore affected regs ;an000; dms;
1205 pop ax ; ;an000; dms;
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
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
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
1222 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1223 ;³ Convert handle's logical page to ³
1224 ;³ relative page in the EMS pool (SI) ³
1225 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1226 MLP_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
1232 MLP_SCAN_PAL: ; (log p is 0 based) @RH8
1233 SHL DI,1 ;2 bytes per PAL ent
1235 MOV DI,PAGE_ALLOC_LIST
[DI] ; This loop will get @RH8
1236 LOOP MLP_SCAN_PAL
; the index of the @RH8
1237 MLP_GOT_PHYS_PG: ; desired page @RH8
1238 MOV SI,DI ;SI = page on card @RH8
1243 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1244 ;³ Get seg addr of the phys page (DI) ³
1245 MLP_GET_SEG: ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1246 XOR DI,DI ;Clear offset into mappable phys. @RH4
1247 MOV CX,MAP_COUNT
; page table. Loop for # entries. @RH4
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
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
1260 ;-------------------------------------
1261 ; Map L to P depending on memory card º
1262 ;-------------------------------------
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
1269 MLP_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
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
1278 MLP_HLST: ;If not XMA then MXO
1279 CALL W_EMSPG_HLST
;Map one logical page to physical @RH3
1281 XOR AH,AH ;Good return status..mapping
1282 ; should always be successful
1285 POP DS ;restore these registers
1299 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1300 ;³ Subroutine: WRITE TRANSLATE TABLE FOR EMS PAGE ³
1301 ;³ XMA VIRTUAL MODE ³
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). ³
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³
1319 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
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
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
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
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
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
1348 LOOP VM_WRITE
;Loop for all blocks in a page @RH1
1354 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1355 ;³ Subroutine: WRITE TRANSLATE TABLE FOR EMS PAGE ³
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. ³
1364 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1367 MOV AL,WTT_CARD_SLOT
;Put the XMA/A card into setup @RH2
1368 OR AL,SLOT_SETUP
; mode @RH2
1371 XOR AL,AL ;Set the translate table ptr by @RH2
1373 OUT DX,AL ; dividing the PC seg. addr in DI @RH2
1375 XCHG AL,AH ; by 256 (Segments per 4K block). @RH2
1377 OUT DX,AL ;High byte always 0..no banking @RH2
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
1384 MOV CX,BLOCKS_PER_PAGE
;Set up one page - loop on blocks @RH2
1385 ; per page using the auto inc regs @RH2
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
1391 MOV DX,RM_TTDATA_LO
; @RH2
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
1397 LOOP RM_WRITE
;Loop for all blocks in a page @RH1
1399 MOV AL,0 ;Reset the slot ID @RH5
1404 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1405 ;³ Subroutine: WRITE TRANSLATE TABLE FOR EMS PAGE ³
1406 ;³ Memory Expansion Option (MXO) ³
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). ³
1415 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1419 MOV AL,WTT_CARD_SLOT
;Put the MXO card into setup @RH3
1420 OR AL,SLOT_SETUP
; mode @RH3
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
1429 MOV DX,H_TTPTR_HI
; @RH3
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
1439 MOV AL,H_TT_INHIBIT
;AL = MXO TT inhibit data @RH3
1441 MOV DX,H_TTDATA
; Write to the 1 MXO TT entry. @RH3
1443 MOV AL,0 ;Reset the slot ID @RH5
1450 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1451 ;³ Subroutine: MULTIPLE MEMORY CARD SETUP ³
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. ³
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 ³
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 ³
1471 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1473 PG_NEW_CARD_ID
DW ?
;Holders for the ID and the slot # @RH5
1474 PG_NEW_CARD_SLOT
DB ?
; of the card that will be used @RH5
1475 ; in the new mapping @RH5
1476 MC_TABLE_OFFSET
DW ?
;Holder for offset into the @RH5
1477 ; multicard page mapping table @RH5
1479 MLP_MCARD_SETUP PROC
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
1490 MC_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
1500 MC_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
1511 ;-------------------------------------
1512 MC_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
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
1529 ;Examine the current card ID and @RH5
1530 ; slot used for this page @RH5
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
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
1549 MC_INH_HLST: ;Else inhibit TT @RH5
1550 CALL W_EMSPG_HLST
; entry for MXO @RH5
1552 ;-------------------------------------
1553 ; Activate (enable) the translate º
1554 ; table entry of the new card. º
1555 MC_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
1569 MC_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
1575 MC_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
1581 MC_MAP_HLST: ; DI = PC segment addr of page @RH5
1582 MOV MEMCARD_MODE
,HOLS_REAL
; SI = page's offset into card @RH5
1583 MC_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
1587 MLP_MCARD_SETUP ENDP
1589 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
1590 ;º Entry point for DEALLOCATE PAGES Function 6 º
1592 ;º on entry: (AH) = '45'x º
1595 ;º on exit: (AH) = status º
1596 ;º AX Revised...all other registers preserved º
1597 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
1599 PUSH BX ;save these registers
1607 PUSH CS ;get this code segment
1609 PUSH CS ;Set up ES for shifting (MOVSB) @RH1
1610 POP ES ; the PAL table @RH1
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;
1620 CMP DX,NUM_HANDLES
-1 ;handle within range ?
1621 JBE D_OKRANGE
;if not then...
1622 MOV AH,EMS_CODE83
;handle not found
1624 D_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
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.
1637 ;-----------------------------------------------------
1638 D_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
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
1656 PUSH DX ;Save handle id @RH1
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;
1664 push cx ;save loop count ;an000; dms;
1666 cmp cx,0 ;handle has 0 pages? ;an001; dms;
1667 je D_Depat_Exit1
;yes - don't changes ptr;an001; dms;
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;
1672 dec cx ;don't loop past last pg;an001; dms;
1677 ;the end of the allocated
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;
1689 shl si,1 ;adjust to index value ;an001; dms;
1690 mov Page_Alloc_List
[si],ax ;pt. last page to orig. ;an001; dms;
1695 pop cx ;restore loop count ;an000; dms;
1696 pop dx ;restore handle ;an000; dms;
1698 push ds ;save regs ;an000; dms;
1699 push si ; ;an000; dms;
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;
1707 pop si ;restore regs ;an000; dms;
1708 pop ds ; ;an000; dms;
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;
1714 sti ;ints on ;an000; dms;
1716 xor ah,ah ;clear flag ;an000; dms;
1732 ;====================================================================
1733 ; Deallocate_Chain - This routine deallocates a page from a
1734 ; handle and links it to the free list
1736 ; Inputs : SI - PTR to entry to deallocate
1738 ; Outputs : SI - PTR to next entry to deallocate
1740 ;====================================================================
1742 Deallocate_Chain proc
;deallocate page ;an000; dms;
1744 push ax ;save regs ;an000; dms;
1745 push bx ; ;an000; dms;
1746 push cx ; ;an000; dms;
1748 cli ;ints off ;an000; dms;
1750 mov bx,si ;alloc_ptr ;an000; dms;
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;
1757 mov ax,Page_List_Entry
;page_ptr value ;an000; dms;
1758 mov cx,cs:PAL_Free_PTR
;free_ptr ;an000; dms;
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;
1766 pop cx ;restore regs ;an000; dms;
1767 pop bx ; ;an000; dms;
1768 pop ax ; ;an000; dms;
1772 Deallocate_Chain endp
; ;an000; dms;
1774 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
1775 ;º Entry point for QUERY MEMORY MANAGER VERSION Function 7 º
1777 ;º on entry: (AH) = '46'x º
1779 ;º on exit: (AH) = status º
1780 ;º all other registers preserved º
1781 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
1783 MOV AL,EMM_VERSION
;al get version number
1784 XOR AH,AH ;good return code
1790 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
1791 ;º Entry point for SAVE MAPPING CONTEXT Function 8 º
1793 ;º on entry: (AH) = '47'x º
1794 ;º (DX) = handle assigned to the interrupt service º
1795 ;º routine (i.e. save map under this handle). º
1797 ;º on exit: (AH) = status º
1798 ;º all other registers preserved º
1799 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
1805 PUSH ES ;save these registers
1809 PUSH CS ;Get CS into ES (save area is in
1810 POP ES ; this segment)
1812 CMP DX,NUM_HANDLES
-1 ;handle within range ?
1813 JBE SM_DXINRANGE
;if not then...
1814 MOV AH,EMS_CODE83
;handle not found
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
1822 POP DX ;Restore handle ID @RH1
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
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
1835 ;-------------------------------------
1836 ; Insure save area free for this hndl º
1837 SM_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
1843 CALL SAVE_PGFRM_MAP
;Save to area pointed to by ES:DI @RH1
1844 XOR AH,AH ;Set good return code
1846 POP ES ;restore these registers
1851 RET ;return to caller
1854 ;-----------------------------------------------------------------------;
1855 ; Subroutine: SAVE PAGE FRAME MAP ;
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 ;
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. ;
1867 ; on entry: ES:DI points to save area ;
1869 ; on exit: All registers preserved ;
1870 ;-----------------------------------------------------------------------;
1872 PUSH AX ;save these registers
1878 PUSH CS ;get this segment into 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
1887 SM_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
1895 POP DS ;Recover these registers
1900 RET ;return to caller
1904 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
1905 ;º Entry point for RESTORE MAPPING CONTEXT Function 9 º
1907 ;º on entry: (AH) = '48'x º
1908 ;º (DX) = handle assigned to the interrupt service º
1909 ;º routine (i.e. handle map was saved under). º
1911 ;º on exit: (AH) = status º
1912 ;º all other registers preserved º
1913 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
1920 PUSH DS ;save these registers
1922 PUSH CS ;Get CS into DS (save area is in
1923 POP DS ; this segment)
1925 CMP DX,NUM_HANDLES
-1 ;handle within range ?
1926 JBE RM_DXINRANGE
;if not then...
1927 MOV AH,EMS_CODE83
;handle not found
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
1935 POP DX ;Restore handle ID @RH1
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
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
1948 ;-------------------------------------
1949 ; Insure save area used for this hndl º
1950 RM_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.
1956 ;-------------------------------------
1957 ; Call RESTORE_PGFRM_MAP º
1958 RM_SAVE_OK: ;-------------------------------------
1959 CALL RESTORE_PGFRM_MAP
;Restore page frame map
1960 CMP AH,0 ;Successful?
1961 JNE RM_EXIT
;No exit
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
1968 RM_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
1974 POP DS ;restore these registers
1980 RET ;return to caller
1983 ;-----------------------------------------------------------------------;
1984 ; Subroutine: RESTORE PAGE FRAME MAP ;
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 ;
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. ;
1996 ; on entry: DS:SI points to the save area ;
1998 ; on exit: (AX) = Status ;
1999 ; All other registers preserved ;
2001 ;-----------------------------------------------------------------------;
2002 RESTORE_PGFRM_MAP PROC
2009 XOR DI,DI ;Use for mappable phys page table @RH5
2010 MOV CX,map_count
;Loop for all pages in page frame @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
2024 RP_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
2030 POP DI ;Restore entry regs
2034 RET ;return to caller
2035 RESTORE_PGFRM_MAP ENDP
2038 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
2039 ;º Entry point for GET EMM HANDLE COUNT Function 12 º
2041 ;º on entry: (AH) = '4B'x º
2043 ;º on exit: (AH) = status º
2044 ;º (BX) = number of open (active) EMS handles º
2045 ;º all other registers preserved º
2046 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
2048 PUSH CX ;save these registers
2052 PUSH CS ;get this segment
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
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
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
2068 POP DS ;recover these registers
2071 RET ;return to caller
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 º
2081 ;º on exit: (AH) = status º
2082 ;º (BX) = number of pages allocated to this handle º
2083 ;º all other registers preserved º
2084 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
2086 PUSH DX ;save these registers
2090 PUSH CS ;get this segment
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
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
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;
2111 XOR AH,AH ;good return status
2113 POP DS ;recover these registers
2116 RET ;return to caller
2120 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
2121 ;º Entry point for GET ALL OPEN HANDLES AND PAGES Function 14 º
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. º
2131 ;º on exit: (AH) = status º
2132 ;º (BX) = Number of active EMS handles º
2133 ;º all other registers preserved º
2134 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
2136 PUSH CX ;save these registers
2142 PUSH CS ;get this segment
2145 MOV DI,cs:[bp].IE_Saved_DI_Reg
;restore di to its value on - gga P1501 ;an004;
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
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
2160 QHP_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
2165 XOR AH,AH ;good return status
2167 POP DS ;restore these registers
2172 RET ;return to caller
2176 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
2177 ;º Entry point for GET/SET PAGE MAP SUBFUNCTIONS Function 15 º
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 º
2184 ;º on exit: (AH) = status º
2185 ;º all other registers preserved º
2186 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
2187 SUBFCN_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
2192 MAX_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
2196 MOV DI,cs:[bp].IE_Saved_DI_Reg
;restore di to its value on
2198 CMP AL,MAX_SUBFCN
;is subfunctiion number within range?
2199 ; $IF BE ;do if yes...
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
2210 JMP CS:SUBFCN_TABLE
[BX] ;call subfunction handler
2213 ;if subfcn # is out of range then do...
2214 MOV AH,EMS_CODE8F
;function call out of range
2217 RET ;return to caller
2222 ;-----------------------------------------------------------------------;
2223 ; Subfunction 0 to GET PAGE MAP Function 15/0 ;
2225 ; on entry: (AH) = '43'x ;
2227 ; ES:DI = Destination save area ;
2229 ; on exit: (AH) = status ;
2230 ; all other registers preserved ;
2231 ;-----------------------------------------------------------------------;
2237 CALL SAVE_PGFRM_MAP
;save page frame map to ES:DI
2238 XOR AH,AH ;good return status
2241 RET ;return to caller
2245 ;-----------------------------------------------------------------------;
2246 ; Subfunction 1 to SET PAGE MAP Function 15/1 ;
2248 ; on entry: (AH) = '43'x ;
2250 ; DS:SI = Source save area ;
2252 ; on exit: (AH) = status ;
2253 ; all other registers preserved ;
2254 ;-----------------------------------------------------------------------;
2258 CALL RESTORE_PGFRM_MAP
;restore page frame map from DS:SI
2259 XOR AH,AH ;good return status
2262 RET ;return to caller
2266 ;-----------------------------------------------------------------------;
2267 ; Subfunction 2 to GET and SET PAGE MAP Function 15/2 ;
2269 ; on entry: (AH) = '43'x ;
2271 ; ES:DI = destination save area ;
2272 ; DS:SI = source save area ;
2274 ; on exit: (AH) = status ;
2275 ; all other registers preserved ;
2276 ;-----------------------------------------------------------------------;
2281 MOV DI,cs:[bp].IE_Saved_DI_Reg
;restore di to its value on
2282 ;entry into irpt handler
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
2290 RET ;return to caller
2293 ;-----------------------------------------------------------------------;
2294 ; Subfunction 3 to RETURN SIZE OF SAVE ARRAY Function 15/3 ;
2296 ; on entry: (AH) = '43'x ;
2299 ; on exit: (AH) = status ;
2300 ; (AL) = Number of bytes needed for a GET or SET ;
2301 ; all other registers preserved ;
2302 ;-----------------------------------------------------------------------;
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
2309 ;=========================================================================
2310 ; Set_Instance This routine accesses the instance table.
2312 ; Inputs : Instance_Table - Table of instances of reentrancy.
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 ;=========================================================================
2320 Set_Instance proc
;set the instance table ;an000; dms;
2322 cli ;disable interrupts ;an000; dms;
2323 push cx ; ;an000; dms;
2325 mov bp,offset
cs:Instance_Table
;get pointer to instance table ;an000; dms;
2326 mov cx,Instance_Count
;number of instances ;an000; dms;
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;
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;
2341 mov cs:[bp].IE_Alloc_Byte
,Allocated
;instance allocated ;an000; dms;
2342 clc ;signal good exit ;an000; dms;
2346 pop cx ;restore regs ;an000; dms;
2347 sti ;turn on interrupts ;an000; dms;
2349 ret ;return ;an000; dms;
2351 Set_Instance endp
; ;an000; dms;
2353 ;=========================================================================
2354 ; Reset_Instance This routine accesses the instance table.
2356 ; Inputs : BP - pointer to currently active instance entry
2358 ; Outputs : Instance_Table - Deactivated instance entry
2359 ;=========================================================================
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;
2367 ret ;return ;an000; dms;
2369 Reset_Instance endp
; ;an000; dms;
2372 ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
2373 ;º Entry point for UNSUPPORTED FUNCTION CALLS º
2374 ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
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.
2395 ; Inputs : CX (Pages needed for request)
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 ;=========================================================================
2402 EMS_Page_Contig_Chk proc
near ;determine contiguity ;an001; dms;
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;
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;
2416 EMS_Page_Contig_Main_Loop:
2418 ;;;; cmp dx,cx ;at end? ;an001; dms;
2419 ;;;; je EMS_Page_Found_Contig ;yes - found contig ;an001; dms;
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;
2429 EMS_Page_Contig_Loop:
2431 ;;;; inc dx ;inc loop counter ;an001; dms;
2432 ;;;; jmp EMS_Page_Contig_Main_Loop ;continue ;an001; dms;
2434 EMS_Page_Contig_Init_Loop:
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;
2444 EMS_Page_Not_Contig:
2446 ;;;; stc ;signal not contig ;an001; dms;
2447 ;;;; jmp EMS_Page_Contig_Exit ;exit routine ;an001; dms;
2449 EMS_Page_Found_Contig:
2451 clc ;signal contig ;an001; dms;
2452 ;;;; mov si,bx ;pass ptr to 1st. ;an001; dms;
2454 EMS_Page_Contig_Exit:
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;
2462 ret ;return to caller ;an001; dms;
2464 EMS_Page_Contig_Chk endp
;end proc ;an001; dms;
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.
2473 ; Inputs : SI - Pointer value to the beginning of pages for handle
2474 ; CX - Count of pages to be allocated
2476 ; Outputs : Adjusted unallocated list
2477 ; SI - Pointer value to beginning of pages for handle
2478 ;=========================================================================
2481 EMS_Link_Set proc
near ;set contig links ;an001; dms;
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;
2489 ;;;; cmp si,cs:PAL_Free_Ptr ;at root? ;an001; dms;
2490 ;;;; je EMS_Link_Set_Up_Root ;yes - set up links ;an001; dms;
2492 ;;;; mov di,cs:PAL_Free_Ptr ;get first free link ;an001; dms;
2494 EMS_Link_Set_Up_Search_Loop:
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;
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;
2508 EMS_Link_Set_Up_Loop:
2510 ;;;; cmp dx,cx ;at end? ;an001; dms;
2511 ;;;; je EMS_Link_Set_Up_Loop_Exit ;yes - exit ;an001; dms;
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;
2518 EMS_Link_Set_Up_Loop_Exit:
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
2527 EMS_Link_Set_Up_Root:
2529 mov di,si ;point to first link ;an001; dms;
2530 xor dx,dx ;init loop counter ;an001; dms;
2532 EMS_Link_Set_Up_Root_Loop:
2534 cmp dx,cx ;at end? ;an001; dms;
2535 je EMS_Link_Set_Up_Root_Exit
;yes - exit ;an001; dms;
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;
2542 EMS_Link_Set_Up_Root_Exit:
2544 mov cs:PAL_Free_Ptr
,di ;new free ptr ;an001; dms;
2545 jmp EMS_Link_Set_Up_Exit
;exit routine ;an001; dms;
2547 EMS_Link_Set_Up_Exit:
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;
2555 ret ;return to caller ;an001; dms;
2557 EMS_Link_Set endp
; ;an001; dms;
2562 ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
2564 ;³ LIM 4.0 functions are kept in a seperate include file, ³
2567 ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
2570 Instance_Table db Instance_Size
*Instance_Count
dup(Unallocated
) ;instance table ;an000; dms;
2572 RESIDENT: ;last address that must stay resident
2576 INCLUDE EMSINIT
.INC ;Main file for throwaway
2577 ; initialization code
2578 INCLUDE XMA1DIAG
.INC ;XMA 1 diagnostics and routines
2579 INCLUDE PS2_5060
.INC ;Diagnostics for PS/2 models 50 @RH2
2580 ; and 60. Support for XMA/A and @RH2
2585 TEMP_STACK
DB STACK_SIZE
DUP(0) ;RESERVE FOR TEMP STACK
2586 TOP_OF_STACK
DB ?
;DURING INITIALIZATION