summaryrefslogtreecommitdiff
path: root/v4.0/src/DEV/XMA2EMS/XMA2EMS.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/DEV/XMA2EMS/XMA2EMS.ASM')
-rw-r--r--v4.0/src/DEV/XMA2EMS/XMA2EMS.ASM2591
1 files changed, 2591 insertions, 0 deletions
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