summaryrefslogtreecommitdiff
path: root/v4.0/src/DEV/SMARTDRV/EMM.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/DEV/SMARTDRV/EMM.ASM')
-rw-r--r--v4.0/src/DEV/SMARTDRV/EMM.ASM223
1 files changed, 223 insertions, 0 deletions
diff --git a/v4.0/src/DEV/SMARTDRV/EMM.ASM b/v4.0/src/DEV/SMARTDRV/EMM.ASM
new file mode 100644
index 0000000..ff61ab0
--- /dev/null
+++ b/v4.0/src/DEV/SMARTDRV/EMM.ASM
@@ -0,0 +1,223 @@
1BREAK <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
21EMM_REC STRUC
22EMM_FLAGS DW 0
23EMM_SYSTEM DW 0
24EMM_BASE DD ? ; 24 bit address of start of region
25EMM_KSIZE DW ? ; Size of region in kbytes
26EMM_REC ENDS
27
28; EMM_FLAGS Bits
29EMM_ALLOC EQU 0000000000000001B ; Zero -> record is free
30EMM_ISDRIVER EQU 0000000000000010B ; 1 -> driver is installed
31 ; for this region
32
33; EMM_SYSTEM Values
34EMM_EMM EQU 0 ; Allocated to EMM
35EMM_MSDOS EQU 1
36EMM_XENIX EQU 2
37EMM_APPLICATION EQU 3
38
39; Layout of EMM control 1024 byte record
40
41EMM_CTRL STRUC
42EMM_VER DB 50 DUP(?)
43EMM_TOTALK DW ? ; EXCLUDING the 1k of this record
44EMM_AVAILK DW ? ; Amount of above NOT allocated
45 DB SIZE EMM_REC DUP(?) ; NULL (0th) RECORD
46EMM_RECORD DB (1024 - 50 - 4 - 10 - (SIZE EMM_REC)) DUP(?)
47 ; EMM_REC structures
48EMM_TAIL_SIG DB 10 DUP(?)
49EMM_CTRL ENDS
50
51EMM_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
220emm_int equ 15h
221emm_size equ 88h
222emm_blkm equ 87h
223;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;