]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DEV/RAMDRIVE/EMM.INC

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DEV / RAMDRIVE / EMM.INC
1 BREAK <EMM control sector layout>
2
3 ;
4 ; The EMM control sector is a 1024 byte record which ALWAYS occupies the
5 ; very first 1024 bytes of "extra" memory that needs to be managed. Its
6 ; function is to provide a method to allocate available "extra" memory
7 ; to programs which desire to use it and avoid program conflicts that
8 ; would occur if two different programs attempted to use the same piece
9 ; of "extra" memory.
10 ;
11
12 ;
13 ; The EMM_CTRL structure defines the offsets into the 1024 byte control
14 ; sector of the various fields. The EMM_REC structure defines a sub-structure
15 ; contained within the EMM_CTRL structure which represents a particular
16 ; piece of allocated "extra" memory (an allocation record).
17 ;
18
19 ; Layout of each EMM record.
20
21 EMM_REC STRUC
22 EMM_FLAGS DW 0
23 EMM_SYSTEM DW 0
24 EMM_BASE DD ? ; 24 bit address of start of region
25 EMM_KSIZE DW ? ; Size of region in kbytes
26 EMM_REC ENDS
27
28 ; EMM_FLAGS Bits
29 EMM_ALLOC EQU 0000000000000001B ; Zero -> record is free
30 EMM_ISDRIVER EQU 0000000000000010B ; 1 -> driver is installed
31 ; for this region
32
33 ; EMM_SYSTEM Values
34 EMM_EMM EQU 0 ; Allocated to EMM
35 EMM_MSDOS EQU 1
36 EMM_XENIX EQU 2
37 EMM_APPLICATION EQU 3
38
39 ; Layout of EMM control 1024 byte record
40
41 EMM_CTRL STRUC
42 EMM_VER DB 50 DUP(?)
43 EMM_TOTALK DW ? ; EXCLUDING the 1k of this record
44 EMM_AVAILK DW ? ; Amount of above NOT allocated
45 DB SIZE EMM_REC DUP(?) ; NULL (0th) RECORD
46 EMM_RECORD DB (1024 - 50 - 4 - 10 - (SIZE EMM_REC)) DUP(?)
47 ; EMM_REC structures
48 EMM_TAIL_SIG DB 10 DUP(?)
49 EMM_CTRL ENDS
50
51 EMM_NUMREC EQU (1024 - 50 - 4 - 10 - (SIZE EMM_REC)) / (SIZE EMM_REC)
52
53
54 ;
55 ; The current initial (no "extra" memory allocated) EMM_CTRL sector is
56 ;
57 ; EMM_CONTROL LABEL BYTE
58 ; DB "MICROSOFT EMM CTRL VERSION 1.00 CONTROL BLOCK "
59 ; DW EXTMEM_TOTALK - 1
60 ; DW EXTMEM_TOTALK - 1
61 ; ; NULL 0th record
62 ; DW EMM_ALLOC + EMM_ISDRIVER
63 ; DW EMM_EMM
64 ; DW EXTMEM_LOW + 1024
65 ; DW EXTMEM_HIGH
66 ; DW 0
67 ; ;**
68 ; DB 950 DUP(0)
69 ; DB "ARRARRARRA"
70 ;
71 ; Where EXTMEM_LOW:EXTMEM_HIGH is the 32 bit address of the first byte
72 ; of the EMM_CTRL sector (first byte of "extra" memory) and EXTMEM_TOTALK
73 ; is the size in K of the available "extra" memory. One is subtracted
74 ; from EXTMEM_TOTALK because the sizes in the EMM_CTRL record DO NOT
75 ; include the 1k taken up by the EMM_CTRL sector.
76 ;
77 ; The reason for the existance of the NULL 0th record is to facilitate
78 ; the computation of EMM_BASE for the first EMM_REC allocation record
79 ; created.
80 ;
81 ; The EMM_REC structures CANNOT be sparse. In other words if one sets
82 ; up a scan of the EMM_REC structures in the EMM_CTRL sector, as soon as
83 ; an EMM_REC structure WITHOUT the EMM_ALLOC bit set in its flag word
84 ; is encountered it is not necessary to scan further because it IS KNOWN
85 ; that all of the EMM_REC structures after the first one with EMM_ALLOC
86 ; clear also have EMM_ALLOC clear. What this means is that EMM_CTRL
87 ; memory CANNOT BE deallocated. Once an EMM_REC structure has its
88 ; EMM_ALLOC bit set, there is NO correct program operation which
89 ; can clear the bit UNLESS it IS KNOWN that the next EMM_REC structure
90 ; has its EMM_ALLOC bit clear or the EMM_REC structure is the last one.
91 ;
92 ;
93 ; USING THE EMM_CTRL SECTOR:
94 ;
95 ; A program which wishes to use the EMM_CTRL sector to access "extra"
96 ; memory should work as follows:
97 ;
98 ; Figure out how much memory you wish to allocate
99 ;
100 ; Figure out the location and size of the "extra" memory in the system
101 ;
102 ; IF (the first 1024 bytes of "extra" memory DO NOT contain a valid
103 ; EMM_CTRL record determined by checking for the existence of the
104 ; correct EMM_VER and EMM_TAIL_SIG strings)
105 ; Write a correct initial EMM_CTRL sector to the first 1024
106 ; bytes of extra memory. Be sure to fill in EMM_TOTALK,
107 ; EMM_AVAILK and EMM_BASE in the 0th record.
108 ;
109 ; Set up a scan of the EMM_REC structures in the EMM_CTRL sector.
110 ; NOTE: You can skip the NULL 0th record if you want since it has
111 ; known value.
112 ;
113 ; FOR (i=0;i<EMM_NUMREC;i++)
114 ; IF ( this EMM_REC has EMM_ALLOC clear)
115 ; IF ( EMM_AVAILK < amount I want to alloc)
116 ; ERROR insufficient memory
117 ; EMM_AVAILK = EMM_AVAILK - amount I want to alloc
118 ; EMM_FLAGS = EMM_ALLOC + EMM_ISDRIVER
119 ; EMM_KSIZE = amount I want to alloc
120 ; EMM_SYSTEM = appropriate value
121 ; EMM_BASE = EMM_BASE of PREVIOUS EMM_REC +
122 ; (1024 * EMM_KSIZE of PREVIOUS EMM_REC)
123 ; break
124 ; ELSE
125 ; address next EMM_REC structure
126 ;
127 ; IF (i >= EMM_NUMREC)
128 ; ERROR no free EMM_REC structures
129 ;
130 ;
131 ; You can now see why we need that NUL 0th EMM_REC structure. In order to
132 ; perform this step
133 ;
134 ; EMM_BASE = EMM_BASE of PREVIOUS EMM_REC +
135 ; (1024 * EMM_KSIZE of PREVIOUS EMM_REC)
136 ;
137 ; when the very first EMM_REC is allocated we must have a "previous EMM_REC"
138 ; structure to point at.
139 ;
140 ; The above code is rather simplistic in that all it does is do a simple
141 ; allocation. The EMM_ISDRIVER bit allows us to do some more sophisticated
142 ; things. In particular in the case of a RAMDrive type of program it is
143 ; desirable to "re-find" the same RAMDrive area in "extra" memory when the
144 ; system is re-booted. The EMM_ISDRIVER bit is used to help us do this.
145 ;
146 ; The EMM_ISDRIVER bit means "there is presently a piece of code in the
147 ; system which is using this memory". If we find an EMM_REC structure
148 ; which has its EMM_ALLOC bit set, but the EMM_ISDRIVER bit is clear
149 ; it means that the piece of code that originally allocated
150 ; the memory is gone and we may want to "re-find" this memory by
151 ; setting the EMM_ISDRIVER bit again. A RAMDrive program would have
152 ; slightly different code than the above:
153 ;
154 ; FOR (i=0;i<EMM_NUMREC;i++)
155 ; IF ( this EMM_REC has EMM_ALLOC clear)
156 ; IF ( EMM_AVAILK < amount I want to alloc)
157 ; ERROR insufficient memory
158 ; EMM_AVAILK = EMM_AVAILK - amount I want to alloc
159 ; EMM_FLAGS = EMM_ALLOC + EMM_ISDRIVER
160 ; EMM_KSIZE = amount I want to alloc
161 ; EMM_SYSTEM = appropriate value
162 ; EMM_BASE = EMM_BASE of PREVIOUS EMM_REC +
163 ; (1024 * EMM_KSIZE of PREVIOUS EMM_REC)
164 ; break
165 ; ELSE
166 ; IF ((EMM_SYSTEM == my value for EMM_SYSTEM) &&
167 ; (EMM_ISDRIVER is clear))
168 ; deal with differences between amount
169 ; I want to allocate and EMM_KSIZE
170 ; Set EMM_ISDRIVER
171 ; EMM_BASE is the base address of this piece
172 ; of memory and EMM_KSIZE is its size.
173 ; break
174 ; address next EMM_REC structure
175 ;
176 ; In this way we "re-find" memory that was previosly allocated (presumably
177 ; by us, or a related program).
178 ;
179 ; NOTE THAT THIS USE OF EMM_ISDRIVER REQUIRES SOME MECHANISM FOR CLEARING
180 ; EMM_ISDRIVER WHEN THE CODE OF INTEREST IS REMOVED FROM THE SYSTEM.
181 ; In the case of a RAMDrive program the code is removed whenever the system
182 ; is re-booted. For this reason a RAMDrive program will need code that is
183 ; invoked whenever a system re-boot is detected. What this code does is
184 ; scan the EMM_REC structures in the EMM_CTRL sector turning off the
185 ; EMM_ISDRIVER bits:
186 ;
187 ; FOR (i=0;i<EMM_NUMREC;i++)
188 ; IF ( this EMM_REC has EMM_ALLOC clear)
189 ; break
190 ; ELSE IF (EMM_SYSTEM == my value for EMM_SYSTEM)
191 ; clear EMM_ISDRIVER bit
192 ; address next EMM_REC
193 ;
194 ; Note that this code clears ALL of the ISDRIVER bits for EMM_SYSTEM
195 ; values of a certain value. This means there is a GLOBAL piece of
196 ; re-boot code for ALL of the programs using a particular EMM_SYSTEM
197 ; value. An alternative is to have each EMM_CTRL user clear the
198 ; EMM_ISDRIVER bits ONLY for those EMM_REC structures that it allocated.
199 ; This requires that the program keep a record of which EMM_REC structures
200 ; it is responsible for:
201 ;
202 ; FOR each of my EMM_REC structures
203 ; INDEX this EMM_REC structure in the EMM_CTRL sector
204 ; Clear EMM_ISDRIVER
205 ;
206 ; NOTE about this step:
207 ;
208 ; deal with differences between amount
209 ; I want to allocate and EMM_KSIZE
210 ;
211 ; in the above code. There are a lot of options here depending on the desired
212 ; behavior. If the NEXT EMM_REC structure has EMM_ALLOC clear, then it may
213 ; be possible for me to grow or shrink the block I found by adjusting
214 ; EMM_KSIZE and EMM_AVAILK. If the NEXT EMM_REC structure has EMM_ALLOC
215 ; set, then I am forced to either adjust the amount I want to allocate
216 ; to match EMM_KSIZE, or skip this EMM_REC without setting EMM_ISDRIVER.
217 ;
218 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
219 ; for rom 1nt15 extended memory interface
220 emm_int equ 15h
221 emm_size equ 88h
222 emm_blkm equ 87h
223 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;