]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/INC/DOSMAC.INC

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / INC / DOSMAC.INC
1 ; SCCSID = @(#)dosmac.asm 1.1 85/04/10
2 ; SCCSID = @(#)dosmac.asm 1.1 85/04/10
3 ;
4 ; Macro file for MSDOS.
5 ;
6
7 TRUE EQU 0FFFFh
8 FALSE EQU 0
9
10 SUBTTL BREAK a listing into pages and give new subtitles
11 PAGE
12 BREAK MACRO subtitle
13 SUBTTL subtitle
14 PAGE
15 ENDM
16 .xcref break
17
18 BREAK <ASMVAR - handle assembly variables once and for all>
19
20 AsmVars Macro varlist
21 IRP var,<varlist>
22 AsmVar var
23 ENDM
24 ENDM
25
26 AsmVar Macro var
27 IFNDEF var
28 var = FALSE
29 ENDIF
30 ENDM
31
32 BREAK <I_NEED: declare a variable external, if necessary, and allocate a size>
33
34 ;
35 ; declare a variable external and allocate a size
36 ;
37 AsmVar InstalledData
38 I_NEED MACRO sym,len
39 IF NOT InstalledData
40 DATA SEGMENT WORD PUBLIC 'DATA'
41 IFIDN <len>,<WORD>
42 EXTRN &sym:WORD
43 ELSE
44 IFIDN <len>,<DWORD>
45 EXTRN &sym:DWORD
46 ELSE
47 EXTRN &sym:BYTE
48 ENDIF
49 ENDIF
50 DATA ENDS
51 ENDIF
52 ENDM
53 .xcref I_need
54
55 ;
56 ; call a procedure that may be external. The call will be short.
57 ;
58 invoke MACRO name
59 .xcref
60 IF2
61 IFNDEF name
62 EXTRN name:NEAR
63 ENDIF
64 ENDIF
65 .cref
66 CALL name
67 ENDM
68 .xcref invoke
69
70 PAGE
71 ;
72 ; jump to a label that may be external. The jump will be near.
73 ;
74 transfer MACRO name
75 .xcref
76 IF2
77 IFNDEF name
78 EXTRN name:NEAR
79 ENDIF
80 ENDIF
81 .cref
82 JUMP name
83 ENDM
84 .xcref transfer
85
86 ;
87 ; get a short address in a word
88 ;
89 short_addr MACRO name
90 IFDIF <name>,<?>
91 .xcref
92 IF2
93 IFNDEF name
94 EXTRN name:NEAR
95 ENDIF
96 ENDIF
97 .cref
98 DW OFFSET DOSGROUP:name
99 ELSE
100 DW ?
101 ENDIF
102 ENDM
103 .xcref short_addr
104
105 ;
106 ; get a long address in a dword
107 ;
108 long_addr MACRO name
109 .xcref
110 IF2
111 IFNDEF name
112 EXTRN name:NEAR
113 ENDIF
114 ENDIF
115 .cref
116 DD name
117 ENDM
118 .xcref long_addr
119
120 ;
121 ; declare a PROC near or far but PUBLIC nonetheless
122 ;
123 .xcref ?frame
124 .xcref ?aframe
125 .xcref ?stackdepth
126 .xcref ?initstack
127 ?frame = 0 ; initial
128 ?aframe = 0 ; initial
129 ?stackdepth = 0 ; initial stack size
130 ?initstack = 0 ; initial stack size
131
132 procedure MACRO name,distance
133 ?frame = 0
134 ?aframe = 2 ;; remember the pushed BP
135 PUBLIC name
136 IF1
137 %OUT name... pass 1
138 ENDIF
139 IF2
140 %OUT name... pass 2
141 ENDIF
142 name PROC distance
143 ?initstack = ?stackdepth ;; beginning of procedure
144 ENDM
145 .xcref procedure
146
147 ;
148 ; end a procedure and check that stack depth is preserved
149 ;
150 EndProc MACRO name, chk
151 IFDIF <chk>,<NoCheck> ;; check the stack size
152 IF2
153 IF ?initstack NE ?stackdepth ;; is it different?
154 %OUT ***** Possible stack size error in name *****
155 ENDIF
156 ENDIF
157 ENDIF
158 name ENDP
159 ENDM
160 .xcref endproc
161 PAGE
162 ;
163 ; define a data item to be public and of an appropriate size/type
164 ;
165
166 I_AM MACRO name,size,init
167 ;; declare the object public
168 PUBLIC name
169 ;; declare the type of the object
170 IFIDN <size>,<WORD>
171 name LABEL WORD
172 I_AM_SIZE = 1
173 I_AM_LEN = 2
174 ELSE
175 IFIDN <size>,<DWORD>
176 name LABEL DWORD
177 I_AM_SIZE = 2
178 I_AM_LEN = 2
179 ELSE
180 IFIDN <size>,<BYTE>
181 name LABEL BYTE
182 I_AM_SIZE = 1
183 I_AM_LEN = 1
184 ELSE
185 name LABEL BYTE
186 I_AM_SIZE = size
187 I_AM_LEN = 1
188 ENDIF
189 ENDIF
190 ENDIF
191 ;; if no initialize then allocate blank storage
192 IFB <init>
193 DB I_AM_SIZE*I_AM_LEN DUP (?)
194 ELSE
195 IF NOT InstalledData
196 IRP itm,<init>
197 IF I_AM_LEN EQ 1
198 DB itm
199 ELSE
200 DW itm
201 ENDIF
202 I_AM_SIZE = I_AM_SIZE - 1
203 ENDM
204 IF I_AM_SIZE NE 0
205 %out ***** initialization of name not complete *****
206 ENDIF
207 ELSE
208 DB I_AM_SIZE*I_AM_LEN DUP (?)
209 ENDIF
210 ENDIF
211 ENDM
212 .xcref I_AM
213 .xcref I_AM_SIZE
214 .xcref I_AM_LEN
215 I_AM_SIZE = 0
216 I_AM_LEN = 0
217
218 PAGE
219
220 ;
221 ; define an entry in a procedure
222 ;
223 entry macro name
224 PUBLIC name
225 name:
226 endm
227 .xcref entry
228
229 BREAK <ERROR - store an error code then jump to a label>
230
231 error macro code
232 .xcref
233 MOV AL,code
234 transfer SYS_RET_ERR
235 .cref
236 ENDM
237 .xcref error
238
239 BREAK <JUMP - real jump that links up shortwise>
240 ;
241 ; given a label <lbl> either 2 byte jump to another label <lbl>_J
242 ; if it is near enough or 3 byte jump to <lbl>
243 ;
244
245 jump macro lbl
246 local a
247 .xcref
248
249 ifndef lbl&_J ;; is this the first invocation
250 a: JMP lbl
251 ELSE
252 IF (lbl&_J GE $) OR ($-lbl&_J GT 126)
253 a: JMP lbl ;; is the jump too far away?
254 ELSE
255 a: JMP lbl&_J ;; do the short one...
256 ENDIF
257 ENDIF
258 lbl&_j = a
259 .cref
260 endm
261 .xcref jump
262
263 BREAK <RETURN - return from a function>
264
265 return macro x
266 local a
267 .xcref
268 a:
269 RET
270 ret_l = a
271 .cref
272 endm
273 .xcref return
274
275 BREAK <CONDRET - conditional return>
276
277 condret macro cc,ncc
278 local a
279 .xcref
280 .xcref a
281 .cref
282 ifdef ret_l ;; if ret_l is defined
283 if (($ - ret_l) le 126) and ($ gt ret_l)
284 ;; if ret_l is near enough then
285 a: j&cc ret_l ;; a: j<CC> to ret_l
286 ret_&cc = a ;; define ret_<CC> to be a:
287 exitm
288 endif
289 endif
290 ifdef ret_&cc ;; if ret_<CC> defined
291 if (($ - ret_&cc) le 126) and ($ gt ret_&cc)
292 ;; if ret_<CC> is near enough
293 a: j&cc ret_&cc ;; a: j<CC> to ret_<CC>
294 ret_&cc = a ;; define ret_<CC> to be a:
295 exitm
296 endif
297 endif
298 j&ncc a ;; j<NCC> a:
299 return ;; return
300 a: ;; a:
301 ret_&cc = ret_l ;; define ret_<CC> to be ret_l
302 endm
303 .xcref condret
304
305 BREAK <RETZ - return if zero, links up shortwise if necessary>
306
307 retz macro
308 condret z,nz
309 endm
310 .xcref retz
311
312 BREAK <RETNZ - return if not zero, links up shortwise if necessary>
313
314 retnz macro
315 condret nz,z
316 endm
317 .xcref retnz
318
319 BREAK <RETC - return if carry set, links up shortwise if necessary>
320
321 retc macro
322 condret c,nc
323 endm
324 .xcref retc
325
326 BREAK <RETNC - return if not carry, links up shortwise if necessary>
327
328 retnc macro
329 condret nc,c
330 endm
331 .xcref retnc
332
333 BREAK <CONTEXT - set the DOS context to a particular register>
334
335 context macro r
336 PUSH SS
337 POP r
338 ASSUME r:DOSGROUP
339 endm
340 .xcref context
341
342 BREAK <SaveReg - save a set of registers>
343
344 SaveReg MACRO reglist ;; push those registers
345 IRP reg,<reglist>
346 ?stackdepth = ?stackdepth + 1
347 PUSH reg
348 ENDM
349 ENDM
350 .xcref SaveReg
351
352 BREAK <RestoreReg - unsave some registers>
353
354 RestoreReg MACRO reglist ;; pop those registers
355 IRP reg,<reglist>
356 ?stackdepth = ?stackdepth - 1
357 POP reg
358 ENDM
359 ENDM
360 .xcref RestoreReg
361
362 BREAK <Critical section macros>
363
364 EnterCrit MACRO section
365 Invoke E&section
366 ENDM
367
368 LeaveCrit MACRO section
369 Invoke L&section
370 ENDM
371
372 Break <message - display a message>
373
374 AsmVars <ShareF,Cargs,Redirector>
375
376 if debug
377 fmt MACRO typ,lev,fmts,args
378 local a,b,c
379 PUSHF
380 IFNB <typ>
381 TEST BugTyp,typ
382 JZ c
383 CMP BugLev,lev
384 JB c
385 ENDIF
386 PUSH AX
387 PUSH BP
388 MOV BP,SP
389 If (not sharef) and (not redirector)
390 Table segment
391 a db fmts,0
392 Table ends
393 MOV AX,OFFSET DOSGROUP:a
394 else
395 jmp short b
396 a db fmts,0
397 if sharef
398 b: mov ax,offset share:a
399 else
400 b: mov ax,offset netwrk:a
401 endif
402 endif
403 PUSH AX
404 cargs = 2
405 IRP item,<args>
406 IFIDN <AX>,<item>
407 MOV AX,[BP+2]
408 ELSE
409 MOV AX,item
410 ENDIF
411 PUSH AX
412 cargs = cargs + 2
413 ENDM
414 invoke PFMT
415 ADD SP,Cargs
416 POP BP
417 POP AX
418 c:
419 POPF
420 ENDM
421 else
422 fmt macro
423 endm
424 endif
425
426 Break <DOSAssume - validate assumes>
427
428 AsmVar Debug,$temp
429
430 IF debug
431 DOSAssume Macro reg,reglist,message
432 local a,b
433 IFIDN <reg>,<CS>
434 $temp = 1
435 ELSE
436 IFIDN <reg>,<SS>
437 $temp = 0
438 ELSE
439 %out ***** Invalid DOS register reg in DOSAssume *****
440 ENDIF
441 ENDIF
442 IRP r,<reglist>
443 IFIDN <r>,<DS>
444 $temp = $temp OR 2
445 ELSE
446 IFIDN <r>,<ES>
447 $temp = $temp OR 4
448 ELSE
449 %out ***** Invalid register reg in DOSAssume *****
450 ENDIF
451 ENDIF
452 ENDM
453 PUSH AX
454 MOV AX,$temp
455 PUSH AX
456 IF SHAREF
457 MOV AX,OFFSET a
458 ELSE
459 MOV AX,OFFSET DOSGroup:a
460 ENDIF
461 PUSH AX
462 Invoke SegCheck
463 POP AX
464 IF NOT SHAREF
465 Table SEGMENT
466 a DB message,0
467 Table ends
468 ELSE
469 JMP SHORT a
470 b DB message,0
471 a:
472 ENDIF
473 IRP r,<reglist>
474 ASSUME r:DOSGroup
475 ENDM
476 ENDM
477 ELSE
478 DOSAssume Macro reg,reglist,message
479 IRP r,<reglist>
480 ASSUME r:DOSGroup
481 ENDM
482 ENDM
483 ENDIF
484
485 BREAK <ASSERT - make assertions about registers>
486
487 IF DEBUG
488 Assert MACRO kind, objs, message
489 LOCAL a,b
490 IFIDN <kind>,<Z>
491 CMP objs,0
492 JZ a
493 fmt <>,<>,<message>
494 a:
495 ELSE
496 IFIDN <kind>,<NZ>
497 CMP objs,0
498 JNZ a
499 fmt <>,<>,<message>
500 a:
501 ELSE
502 PUSH AX
503 IRP obj,<objs>
504 PUSH obj
505 ENDM
506 IF SHAREF
507 MOV AX,OFFSET b
508 ELSE
509 MOV AX,OFFSET DOSGroup:b
510 ENDIF
511 PUSH AX
512 IFIDN <kind>,<ISBUF>
513 Invoke BUFCheck
514 ENDIF
515 IFIDN <kind>,<ISSFT>
516 Invoke SFTCheck
517 ENDIF
518 IFIDN <kind>,<ISDPB>
519 Invoke DPBCheck
520 ENDIF
521 POP AX
522 IF SHAREF
523 JMP SHORT a
524 b DB Message,0
525 a:
526 ELSE
527 Table segment
528 b db Message,0
529 Table ends
530 ENDIF
531 ENDIF
532 ENDIF
533 ENDM
534 ELSE
535 Assert Macro
536 ENDM
537 ENDIF
538
539 Break <CallInstall - hook to installable pieces>
540
541 CallInstall MACRO name,mpx,fn,save,restore
542 IF Installed
543 IFNB <save>
544 SaveReg <save>
545 ENDIF
546 MOV AX,(mpx SHL 8) + fn
547 INT 2Fh
548 IFNB <restore>
549 RestoreReg <restore>
550 ENDIF
551 ELSE
552 Invoke name
553 ENDIF
554 ENDM
555
556 Break <Stack frame manipulators>
557
558 localvar macro name,length
559 local a
560 ifidn <length>,<BYTE>
561 ?frame = ?frame + 1
562 a = ?frame
563 name EQU BYTE PTR [BP-a]
564 else
565 ifidn <length>,<WORD>
566 ?frame = ?frame + 2
567 a = ?frame
568 name EQU WORD PTR [BP-a]
569 else
570 ifidn <length>,<DWORD>
571 ?frame = ?frame + 4
572 a = ?frame
573 name EQU DWORD PTR [BP-a]
574 name&l EQU WORD PTR [BP-a]
575 name&h EQU WORD PTR [BP-a+2]
576 else
577 ?frame = ?frame + length
578 a = ?frame
579 name EQU BYTE PTR [BP-a]
580 endif
581 endif
582 endif
583 endm
584
585 enter macro
586 push bp
587 mov bp,sp
588 sub sp,?frame
589 endm
590
591 leave macro
592 mov sp,bp
593 pop bp
594 endm
595
596 Argvar macro name,length
597 local a
598 ifidn <length>,<BYTE>
599 a = ?aframe
600 ?aframe = ?aframe + 1
601 name EQU BYTE PTR [BP+a]
602 else
603 ifidn <length>,<WORD>
604 a = ?aframe
605 ?aframe = ?aframe + 2
606 name EQU WORD PTR [BP+a]
607 else
608 ifidn <length>,<DWORD>
609 a = ?aframe
610 ?aframe = ?aframe + 4
611 name EQU DWORD PTR [BP+a]
612 name&l EQU WORD PTR [BP+a]
613 name&h EQU WORD PTR [BP+a+2]
614 else
615 a = ?aframe
616 ?aframe = ?aframe + length
617 name EQU BYTE PTR [BP+a]
618 endif
619 endif
620 endif
621 endm
622
623 BREAK <errnz - generate compilation errors>
624
625 errnz macro x
626 if x NE 0
627 %out ***** FATAL error: x <> 0
628 foobar
629 endif
630 endm