1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; DUMMY DATA SEGMENT THAT WILL LINK WITH THE DATA.MAC
; FILE. THIS RESOLVES ANY REFERENCES TO THE DATA SEGMENT.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DATA SEGMENT BYTE PUBLIC 'DATA' ;AN000;
HELPBUFSEG DW 0 ;AN000;
MEM_ALLOC DB 0 ;AN000;DT Memory allocated indicator
HELP_ALLOC EQU 80H ;AN000;DT Help memory allocated
BLOCK_ALLOC EQU 40H ;AN000;DT PANEL memory allocated
LVB_ALLOC EQU 20H ;AN000;DT LVB memory allocated
BLOCK_SET EQU 01H ;AN000;DT SETBLOCK done
DATA ENDS ;AN000;DATA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Define dummy segment to calculate end of program
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ZSEG SEGMENT PARA PUBLIC 'ZSEG' ;AN000;marks end of routine
ZSEG ENDS ;AN000;ZSEG will alphabetically appear
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; INITMEM.ASM
;
;
; Allocate Memory
;
; This routine will free up the required memory from DOS to make
; space for the panels, scroll, help, and input field data.
;
;
; INPUT: BX = # paragraphs to keep (in the program) ZSEG-PSP_SEG
; CX = Length of program in bytes
; DX = # paragraphs to allocate
; DS = ES = CS - 10H
;
; OUTPUT: DS:DX = segment:offset of allocated buffer
; BX = length of allocated buffer
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
EXTRN WR_MAXMEMPAR:WORD ;AN000;
EXTRN WR_MAXHELPSZ:WORD ;AN000;
EXTRN WR_DATA2SEG:WORD ;AN000;
EXTRN WR_DATA2OFF:WORD ;AN000;
EXTRN WR_DATA2LEN:WORD ;AN000;
EXTRN WR_LVBSEG:WORD ;AN000;DT
EXTRN WR_LVBOFF:WORD ;AN000;DT
EXTRN WR_LVBLEN:WORD ;AN000;DT
EXTRN WR_LVBMEM:WORD ;AN000;DT
EXTRN HRD_BUFSEG:WORD ;AN000;
EXTRN HRD_BUFOFF:WORD ;AN000;
EXTRN HRD_BUFLEN:WORD ;AN000;
;
SERVICE SEGMENT PARA PUBLIC 'SERVICE' ;AN000;segment for far routine
ASSUME CS:SERVICE,DS:DATA ;AN000;
;
PUBLIC ALLOCATE_MEMORY_CALL ;AN000;
PUBLIC DEALLOCATE_MEMORY_CALL ;AN000;
PUBLIC ALLOCATE_HELP ;AN000;
PUBLIC DEALLOCATE_HELP ;AN000;
PUBLIC ALLOCATE_BLOCK ;AN000;
PUBLIC DEALLOCATE_BLOCK ;AN000;
PUBLIC ALLOCATE_LVB ;AN000;
PUBLIC DEALLOCATE_LVB ;AN000;
;
SET_BLOCK equ 4AH ;AN000;
ALLOCATEB equ 48H ;AN000;
FREE_BLOCK equ 49H ;AN000;
;
INCLUDE STRUC.INC ;AN000;
INCLUDE MACROS.INC ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DS and AX will auto pop on ret
;
; ALLOCATE_MEMORY_CALL
;
; This first takes the memory held by the active program
; (initially all of remaining memory) and requests only the
; memory held by the running program. Next, memory is
; re-allocated to the running program - specified by WR_MAXMEMPAR
; starting from the end of the program (re/ZSEG).
;
; ENTRY:
; AX = CODE segment (PSP+100H)
;
;
; EXIT:
; if CY = 0 then,
; WR_DATA2SEG = start of allocated segment
; WR_DATA2OFF = start of allocated offset (always 0)
; WR_DATA2LEN = length of allocated block (always WR_MAXMEMPAR)
;
; if CY = 1 then an error occurred allocating memory
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ALLOCATE_MEMORY_CALL PROC FAR ;AN000;
PUSHH <AX,BX,DX,DS,ES> ;AN000;
;
TEST MEM_ALLOC,BLOCK_SET ;AN000;DT SETBLOCK done?
JNZ AM_SBDONE ;AN000;DT if so, skip it
;
MOV AH,62H ;AN000; Get the PSP segment
INT 21H ;AN000;
MOV AX,BX ;AN000;save the PSP segment of SELECT
MOV BX,ZSEG ;AN000;get last address of code (from ZSEG)
MOV ES,AX ;AN000;set PSP segment in ES
SUB BX,AX ;AN000;calc # of paragraphs in the program
MOV AH,SET_BLOCK ;AN000;setblock function number
DOSCALL ;AN000;free used memory
.IF < C > ;AC000;DT
GOTO ALLOC_RET ;AN000;DT If error, exit
.ENDIF ;AN000;DT
OR MEM_ALLOC,BLOCK_SET ;AN000;DT
;
AM_SBDONE: ;AN000;
MOV AX,DATA ;AN000;initialize data segment
MOV DS,AX ;AN000; and extra segment
;
PUSH CS ;AN000;call far procedure
CALL ALLOCATE_BLOCK_NEAR ;AN000;now allocate Panel block
.IF < C > ;AC000;DT
GOTO ALLOC_RET ;AN000;DT If error, exit
.ENDIF ;AN000;
;
PUSH CS ;AN000;call far procedure
CALL ALLOCATE_LVB_NEAR ;AN000;now allocate LVB block
.IF < C > ;AC000;DT
GOTO ALLOC_RET ;AN000;DT If error, exit
.ENDIF ;AN000;
;
PUSH CS ;AN000;call far procedure
CALL ALLOCATE_HELP_NEAR ;AN000;now allocate help
;
ALLOC_RET: ;AN000;
POPP <ES,DS,DX,BX,AX> ;AN000;
RET ;AN000;
ALLOCATE_MEMORY_CALL ENDP ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; DEALLOCATE_MEMORY_CALL
;
; This is the house-cleaning before the running program
; returns to DOS.
;
; ENTRY:
; none
;
; EXIT:
; if CY = 0 then,
; The memory after (WR_DATA2SEG) is released to DOS
; if CY = 1 then,
; An error occurred while trying to release this memory
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DEALLOCATE_MEMORY_CALL PROC FAR;AN000;
PUSHH <AX,DS,ES> ;AN000;
MOV AX,DATA ;AN000;
MOV DS,AX ;AN000;
PUSH CS ;AN000;call far procedure
CALL DEALLOCATE_BLOCK_NEAR ;AN024;now deallocate Panel block
PUSH CS ;AN000;call far procedure
CALL DEALLOCATE_LVB_NEAR ;AN024; deallocate LVB block
PUSH CS ;AN000;call far procedure
CALL DEALLOCATE_HELP_NEAR ;AN000;now deallocate help
POPP <ES,DS,AX> ;AN000;
RET ;AN000;
DEALLOCATE_MEMORY_CALL ENDP ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DS and AX will auto pop on ret
;
; ALLOCATE_HELP
;
;
; ENTRY:
; AX = CODE segment (PSP+100H)
;
;
; EXIT:
; if CY = 0 then, ok
; if CY = 1 then an error occurred allocating memory
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ALLOCATE_HELP PROC FAR ;AN000;
ALLOCATE_HELP_NEAR: ;AN000;
PUSHH <AX,BX,DX,DS,ES> ;AN000;
MOV AX,DATA ;AN000;
MOV DS,AX ;AN000;
;
TEST MEM_ALLOC,HELP_ALLOC ;AN000;DT Is help allocated
JNZ AH_RET ;AN000;DT if so, skip allocation
;now allocate help
MOV BX,WR_MAXHELPSZ ;AN000;set BX to max # of paragraphs
SHR BX,1 ;AN000;
SHR BX,1 ;AN000;
SHR BX,1 ;AN000;
SHR BX,1 ;AN000;
MOV AH,ALLOCATEB ;AN000;set allocate function number
DOSCALL ;AN000;allocate memory
.IF < NC > ;AN000;
MOV HRD_BUFSEG,AX ;AN000;save segment
MOV HELPBUFSEG,AX ;AN000;save segment
MOV HRD_BUFOFF,0 ;AN000; and offset
MOV BX,WR_MAXHELPSZ ;AN000;set BX to max # of byte
MOV HRD_BUFLEN,BX ;AN000;
OR MEM_ALLOC,HELP_ALLOC ;AN000;DT
CLC ;AN000;
.ENDIF ;AN000;
AH_RET: ;AN000;
POPP <ES,DS,DX,BX,AX> ;AN000;
RET ;AN000;
ALLOCATE_HELP ENDP ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; DEALLOCATE_HELP
;
; This is the house-cleaning before the running program
; returns to DOS.
;
; ENTRY:
; none
;
; EXIT:
; if CY = 0 then, OK
; if CY = 1 then,
; An error occurred while trying to release this memory
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DEALLOCATE_HELP PROC FAR ;AN000;
DEALLOCATE_HELP_NEAR: ;AN000;
PUSHH <AX,BX,DS,ES> ;AN000;
MOV AX,DATA ;AN000;
MOV DS,AX ;AN000;
TEST MEM_ALLOC,HELP_ALLOC ;AN000;DT Is help allocated
JZ DH_RET ;AN000;DT if not, skip deallocation
MOV AX,HELPBUFSEG ;AN000;free help segment
MOV ES,AX ;AN000;
MOV AH,FREE_BLOCK ;AN000;
DOSCALL ;AN000;
AND MEM_ALLOC,255-HELP_ALLOC ;AN000;DT
DH_RET: ;AN000;
POPP <ES,DS,BX,AX> ;AN000;
RET ;AN000;
DEALLOCATE_HELP ENDP ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DS and AX will auto pop on ret
;
; ALLOCATE_BLOCK
;
; Allocate Panel and Scroll memory.
;
; ENTRY:
; none
; EXIT:
; if CY = 0 then,
; WR_DATA2SEG = start of allocated segment
; WR_DATA2OFF = start of allocated offset (always 0)
; WR_DATA2LEN = length of allocated block (always WR_MAXMEMPAR)
;
; if CY = 1 then an error occurred allocating memory
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ALLOCATE_BLOCK PROC FAR ;AN000;
ALLOCATE_BLOCK_NEAR: ;AN000;
PUSHH <AX,BX,DX,DS,ES> ;AN000;
MOV AX,DATA ;AN000;initialize data segment
MOV DS,AX ;AN000; and extra segment
;
TEST MEM_ALLOC,BLOCK_ALLOC ;AN000;DT Is PANEL block allocated
JNZ AB_RET ;AN000;DT if so, skip allocation
;
MOV BX,WR_MAXMEMPAR ;AN000;set DX to max # of 16 byte parag's
MOV AH,ALLOCATEB ;AN000;set allocate function number
DOSCALL ;AN000;allocate memory
.IF < NC > ;AC000;DT
MOV BX,WR_MAXMEMPAR ;AN000;
SHL BX,1 ;AN000;THIS SHOULD BE REMOVED WHEN
SHL BX,1 ;AN000;THE INITIALIZE ROUTINE TREATS
SHL BX,1 ;AN000;WR_DATA2LEN AS PARAGRAPHS AND
SHL BX,1 ;AN000;NOT BYTES......
MOV WR_DATA2SEG,AX ;AN000;save segment
MOV WR_DATA2OFF,0 ;AN000;
MOV WR_DATA2LEN,BX ;AN000;
OR MEM_ALLOC,BLOCK_ALLOC ;AN000;DT PANEL block allocated
.ENDIF ;AN000;
AB_RET: ;AN000;
POPP <ES,DS,DX,BX,AX> ;AN000;
RET ;AN000;
ALLOCATE_BLOCK ENDP ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; DEALLOCATE_BLOCK
;
; This is the house-cleaning before the running program
; returns to DOS.
;
; ENTRY:
; none
;
; EXIT:
; if CY = 0 then, OK
; if CY = 1 then,
; An error occurred while trying to release this memory
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DEALLOCATE_BLOCK PROC FAR ;AN000;
DEALLOCATE_BLOCK_NEAR: ;AN000;
PUSHH <AX,BX,DS,ES> ;AN000;
MOV AX,DATA ;AN000;
MOV DS,AX ;AN000;
TEST MEM_ALLOC,BLOCK_ALLOC ;AN000;DT Is PANEL block allocated
JZ DB_RET ;AN000;DT if not, skip deallocation
MOV AX,WR_DATA2SEG ;AN000;free up allocated segment
MOV ES,AX ;AN000;
MOV AH,FREE_BLOCK ;AN000;
DOSCALL ;AN000;
AND MEM_ALLOC,255-BLOCK_ALLOC ;AN000;DT
DB_RET: ;AN000;
POPP <ES,DS,BX,AX> ;AN000;
RET ;AN000;
DEALLOCATE_BLOCK ENDP ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DS and AX will auto pop on ret
;
; ALLOCATE_LVB
;
;
; ENTRY:
; AX = none
;
;
; EXIT:
; if CY = 0 then, ok
; if CY = 1 then an error occurred allocating memory
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ALLOCATE_LVB PROC FAR ;AN000;
ALLOCATE_LVB_NEAR: ;AN000;
PUSHH <AX,BX,DX,DS,ES> ;AN000;
;
MOV AX,DATA ;AN000;
MOV DS,AX ;AN000;
;;;;;;;
TEST MEM_ALLOC,LVB_ALLOC ;AN000;DT Is LVB block allocated
JNZ ALVB_RET ;AN000;DT if so, skip allocation
;
MOV BX,WR_LVBMEM ;AN000;set BX to max # of 16 byte parag's
MOV AH,ALLOCATEB ;AN000;set allocate function number
DOSCALL ;AN000;allocate memory
.IF < NC > ;AN000;
MOV WR_LVBSEG,AX ;AN000;save segment
MOV WR_LVBOFF,0 ;AN000;and offset
SHL BX,1 ;AN000;THIS SHOULD BE REMOVED WHEN
SHL BX,1 ;AN000;THE INITIALIZE ROUTINE TREATS
SHL BX,1 ;AN000;WR_DATA2LEN AS PARAGRAPHS AND
SHL BX,1 ;AN000;NOT BYTES......
MOV WR_LVBLEN,BX ;AN000;and byte length
OR MEM_ALLOC,LVB_ALLOC ;AN000;DT LVB block allocated
.ENDIF ;AN000;
;
ALVB_RET: ;AN000;
POPP <ES,DS,DX,BX,AX> ;AN000;
RET ;AN000;
ALLOCATE_LVB ENDP ;AN000;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; DEALLOCATE_LVB
;
;
; ENTRY:
; none
;
; EXIT:
; if CY = 0 then, OK
; if CY = 1 then,
; An error occurred while trying to release this memory
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DEALLOCATE_LVB PROC FAR ;AN000;
DEALLOCATE_LVB_NEAR: ;AN000;
PUSHH <AX,BX,DS,ES> ;AN000;
MOV AX,DATA ;AN000;
MOV DS,AX ;AN000;
TEST MEM_ALLOC,LVB_ALLOC ;AN000;DT Is LVB block allocated
JZ DLVB_RET ;AN000;DT if not, skip deallocation
MOV AX,WR_LVBSEG ;AN000;free up LVB allocated segment
MOV ES,AX ;AN000;
MOV AH,FREE_BLOCK ;AN000;
DOSCALL ;AN000;
AND MEM_ALLOC,255-LVB_ALLOC ;AN000;DT
DLVB_RET: ;AN000;
POPP <ES,DS,BX,AX> ;AN000;
RET ;AN000;
DEALLOCATE_LVB ENDP ;AN000;
SERVICE ENDS ;AN000;
END ;AN000;
|