mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-11-25 23:25:47 +00:00
311 lines
6.5 KiB
NASM
311 lines
6.5 KiB
NASM
|
;
|
|||
|
; Macro file for MSDOS.
|
|||
|
;
|
|||
|
|
|||
|
SUBTTL BREAK a listing into pages and give new subtitles
|
|||
|
PAGE
|
|||
|
BREAK MACRO subtitle
|
|||
|
SUBTTL subtitle
|
|||
|
PAGE
|
|||
|
ENDM
|
|||
|
|
|||
|
BREAK <I_NEED: declare a variable external, if necessary, and allocate a size>
|
|||
|
|
|||
|
;
|
|||
|
; declare a variable external and allocate a size
|
|||
|
;
|
|||
|
I_NEED MACRO sym,len
|
|||
|
CODE ENDS
|
|||
|
DATA SEGMENT BYTE PUBLIC 'DATA'
|
|||
|
|
|||
|
IFIDN <len>,<WORD>
|
|||
|
EXTRN &sym:WORD
|
|||
|
ELSE
|
|||
|
IFIDN <len>,<DWORD>
|
|||
|
EXTRN &sym:DWORD
|
|||
|
ELSE
|
|||
|
EXTRN &sym:BYTE
|
|||
|
ENDIF
|
|||
|
ENDIF
|
|||
|
|
|||
|
DATA ENDS
|
|||
|
CODE SEGMENT BYTE PUBLIC 'CODE'
|
|||
|
ENDM
|
|||
|
|
|||
|
;
|
|||
|
; call a procedure that may be external. The call will be short.
|
|||
|
;
|
|||
|
invoke MACRO name
|
|||
|
&.xcref
|
|||
|
add_ext name,near
|
|||
|
&.cref
|
|||
|
CALL name
|
|||
|
ENDM
|
|||
|
|
|||
|
PAGE
|
|||
|
;
|
|||
|
; jump to a label that may be external. The call will be near.
|
|||
|
;
|
|||
|
transfer MACRO name
|
|||
|
&.xcref
|
|||
|
add_ext name,near
|
|||
|
&.cref
|
|||
|
JUMP name
|
|||
|
ENDM
|
|||
|
|
|||
|
;
|
|||
|
; get a short address in a word
|
|||
|
;
|
|||
|
short_addr MACRO name
|
|||
|
IFDIF <name>,<?>
|
|||
|
&.xcref
|
|||
|
add_ext name,near
|
|||
|
&.cref
|
|||
|
DW OFFSET DOSGROUP:name
|
|||
|
ELSE
|
|||
|
DW ?
|
|||
|
ENDIF
|
|||
|
ENDM
|
|||
|
|
|||
|
;
|
|||
|
; get a long address in a dword
|
|||
|
;
|
|||
|
long_addr MACRO name
|
|||
|
&.xcref
|
|||
|
add_ext name,far
|
|||
|
&.cref
|
|||
|
DD name
|
|||
|
ENDM
|
|||
|
|
|||
|
;
|
|||
|
; declare a PROC near or far but PUBLIC nonetheless
|
|||
|
;
|
|||
|
procedure MACRO name,distance
|
|||
|
PUBLIC name
|
|||
|
name PROC distance
|
|||
|
ENDM
|
|||
|
|
|||
|
PAGE
|
|||
|
;
|
|||
|
; define a data item to be public and of an appropriate size/type
|
|||
|
;
|
|||
|
I_AM MACRO name,size
|
|||
|
PUBLIC name
|
|||
|
|
|||
|
IFIDN <size>,<WORD>
|
|||
|
name DW ?
|
|||
|
ELSE
|
|||
|
IFIDN <size>,<DWORD>
|
|||
|
name DD ?
|
|||
|
ELSE
|
|||
|
IFIDN <size>,<BYTE>
|
|||
|
name DB ?
|
|||
|
ELSE
|
|||
|
name DB size DUP (?)
|
|||
|
ENDIF
|
|||
|
ENDIF
|
|||
|
ENDIF
|
|||
|
ENDM
|
|||
|
|
|||
|
PAGE
|
|||
|
;
|
|||
|
; play games with a possible external. Create a new
|
|||
|
; macro for the symbol and text, and string it together
|
|||
|
; with a central invoker
|
|||
|
;
|
|||
|
|
|||
|
.xcref
|
|||
|
.xcref ?i
|
|||
|
.xcref def_mac
|
|||
|
.xcref ?z0
|
|||
|
.xcref add_ext
|
|||
|
.cref
|
|||
|
|
|||
|
IF1
|
|||
|
?i=0
|
|||
|
ENDIF
|
|||
|
|
|||
|
?z0 macro
|
|||
|
endm
|
|||
|
|
|||
|
;
|
|||
|
; add an external declaration to s with type t if it is not defined
|
|||
|
;
|
|||
|
add_ext macro s,t
|
|||
|
&.xcref
|
|||
|
&.xcref ?&s
|
|||
|
&.cref
|
|||
|
IFNDEF ?&s
|
|||
|
?i = ?i + 1
|
|||
|
def_mac ?z&%?i,?z&%(?i-1),s,t
|
|||
|
ENDIF
|
|||
|
endm
|
|||
|
|
|||
|
;
|
|||
|
; define a macro called that possibly externals s:t and then calls macro n
|
|||
|
;
|
|||
|
def_mac macro m,n,s,t
|
|||
|
&.xcref
|
|||
|
&.xcref ?&s
|
|||
|
&.xcref m
|
|||
|
&.cref
|
|||
|
m macro
|
|||
|
ifndef s
|
|||
|
extrn s:&t
|
|||
|
endif
|
|||
|
purge m
|
|||
|
purge ?&s
|
|||
|
n
|
|||
|
endm
|
|||
|
?&s macro
|
|||
|
&endm
|
|||
|
endm
|
|||
|
|
|||
|
;
|
|||
|
; call the macro chain
|
|||
|
;
|
|||
|
do_ext macro
|
|||
|
&.xcref
|
|||
|
expand_mac ?z%?i
|
|||
|
&.cref
|
|||
|
endm
|
|||
|
|
|||
|
PAGE
|
|||
|
expand_mac macro m
|
|||
|
m
|
|||
|
endm
|
|||
|
|
|||
|
;
|
|||
|
; define an entry in a procedure
|
|||
|
;
|
|||
|
entry macro name
|
|||
|
PUBLIC name
|
|||
|
name:
|
|||
|
endm
|
|||
|
|
|||
|
BREAK <ERROR - print a message and then jump to a label>
|
|||
|
|
|||
|
error macro code
|
|||
|
local a
|
|||
|
.xcref
|
|||
|
MOV AL,code
|
|||
|
transfer SYS_RET_ERR
|
|||
|
.cref
|
|||
|
ENDM
|
|||
|
|
|||
|
BREAK <JUMP - real jump that links up shortwise>
|
|||
|
;
|
|||
|
; given a label <lbl> either 2 byte jump to another label <lbl>_J
|
|||
|
; if it is near enough or 3 byte jump to <lbl>
|
|||
|
;
|
|||
|
|
|||
|
jump macro lbl
|
|||
|
local a
|
|||
|
.xcref
|
|||
|
a:
|
|||
|
ifndef lbl&_J ; is this the first invocation
|
|||
|
JMP lbl
|
|||
|
ELSE
|
|||
|
IF lbl&_J GE $
|
|||
|
JMP lbl
|
|||
|
ELSE
|
|||
|
IF ($-lbl&_J) GT 126 ; is the jump too far away?
|
|||
|
JMP lbl
|
|||
|
ELSE ; do the short one...
|
|||
|
JMP lbl&_J
|
|||
|
ENDIF
|
|||
|
ENDIF
|
|||
|
ENDIF
|
|||
|
endm
|
|||
|
|
|||
|
BREAK <RETURN - return from a function>
|
|||
|
|
|||
|
return macro
|
|||
|
local a
|
|||
|
.xcref
|
|||
|
a:
|
|||
|
RET
|
|||
|
ret_l = a
|
|||
|
endm
|
|||
|
|
|||
|
BREAK <CONDRET - conditional return>
|
|||
|
|
|||
|
makelab macro l,cc,ncc
|
|||
|
j&ncc a ; j<NCC> a:
|
|||
|
return ; return
|
|||
|
a: ; a:
|
|||
|
ret_&cc = ret_l ; define ret_<CC> to be ret_l
|
|||
|
endm
|
|||
|
|
|||
|
condret macro cc,ncc
|
|||
|
local a,b
|
|||
|
ifdef ret_l ; if ret_l is defined
|
|||
|
if (($ - ret_l) le 126) and ($ gt ret_l)
|
|||
|
; if ret_l is near enough then
|
|||
|
a: j&cc ret_l ; a: j<CC> to ret_l
|
|||
|
ret_&cc = a ; define ret_<CC> to be a:
|
|||
|
else
|
|||
|
makelab a,cc,ncc
|
|||
|
endif
|
|||
|
else
|
|||
|
ifdef ret_&cc ; if ret_<CC> defined
|
|||
|
if (($ - ret_&cc) le 126) and ($ gt ret_&cc)
|
|||
|
; if ret_<CC> is near enough
|
|||
|
a: j&cc ret_&cc ; a: j<CC> to ret_<CC>
|
|||
|
ret_&cc = a ; define ret_<CC> to be a:
|
|||
|
else
|
|||
|
makelab a,cc,ncc
|
|||
|
endif
|
|||
|
else
|
|||
|
makelab a,cc,ncc
|
|||
|
endif
|
|||
|
endif
|
|||
|
endm
|
|||
|
;condret macro cc,ncc
|
|||
|
; local a,b
|
|||
|
; ifdef ret_l ; if ret_l is defined
|
|||
|
; if (($ - ret_l) le 126) and ($ gt ret_l)
|
|||
|
; ; if ret_l is near enough then
|
|||
|
; a: j&cc ret_l ; a: j<CC> to ret_l
|
|||
|
; ret_&cc = a ; define ret_<CC> to be a:
|
|||
|
; exitm
|
|||
|
; endif
|
|||
|
; endif
|
|||
|
; ifdef ret_&cc ; if ret_<CC> defined
|
|||
|
; if (($ - ret_&cc) le 126) and ($ gt ret_&cc)
|
|||
|
; ; if ret_<CC> is near enough
|
|||
|
; a: j&cc ret_&cc ; a: j<CC> to ret_<CC>
|
|||
|
; ret_&cc = a ; define ret_<CC> to be a:
|
|||
|
; exitm
|
|||
|
; endif
|
|||
|
; endif
|
|||
|
; j&ncc a ; j<NCC> a:
|
|||
|
; return ; return
|
|||
|
; a: ; a:
|
|||
|
; ret_&cc = ret_l ; define ret_<CC> to be ret_l
|
|||
|
;endm
|
|||
|
|
|||
|
BREAK <RETZ - return if zero, links up shortwise if necessary>
|
|||
|
|
|||
|
retz macro
|
|||
|
condret z,nz
|
|||
|
endm
|
|||
|
|
|||
|
BREAK <RETNZ - return if not zero, links up shortwise if necessary>
|
|||
|
|
|||
|
retnz macro
|
|||
|
condret nz,z
|
|||
|
endm
|
|||
|
|
|||
|
BREAK <RETC - return if carry set, links up shortwise if necessary>
|
|||
|
|
|||
|
retc macro
|
|||
|
condret c,nc
|
|||
|
endm
|
|||
|
|
|||
|
BREAK <RETNC - return if not carry, links up shortwise if necessary>
|
|||
|
|
|||
|
retnc macro
|
|||
|
condret nc,c
|
|||
|
endm
|
|||
|
|