Category : Assembly Language Source Code
Archive   : PROC.ZIP
Filename : PROC.MAC

 
Output of file : PROC.MAC contained in archive : PROC.ZIP

.XLIST

PAGE ,132

FALSE EQU 0
TRUE EQU NOT FALSE
NUL EQU 0
BS EQU 8
HT EQU 9
TAB EQU HT
LF EQU 10
FF EQU 12
CR EQU 13
EOF EQU 26
ESC EQU 27
DEL EQU 127

@[email protected]@ STRUC
LB DB ?; x.LB = BYTE PTR x
HB DB ?; x.HB = BYTE PTR x + 1
@[email protected]@ ENDS
B EQU LB; x.B = BYTE PTR x

@[email protected]@ STRUC
LW DW ?; x.LW = WORD PTR x
HW DW ?; x.HW = WORD PTR x + 2
@[email protected]@ ENDS
W EQU LW; x.W = WORD PTR x

@[email protected]@ STRUC
D DD ?; x.D = DWORD PTR x
@[email protected]@ ENDS


@[email protected]@ MACRO;; initialize procedure & parameter controls
@[email protected]@ = 0;; where next parameter is in frame
@[email protected]@ = 0;; where first parameter is in frame
@[email protected]@ = 0;; controls partial parameter cleanup
@[email protected]@ = 0;; where latest variable is in frame
@[email protected]@ = FALSE;; define interrupt procedure flag
@[email protected]@ = FALSE;; define existence of local frame
ENDM


$PASCAL MACRO;; discard parameters upon $RET
@[email protected]@ = TRUE
ENDM


$C MACRO;; leave parameters upon $RET
@[email protected]@ = FALSE
ENDM


; begin procedure, define parameter addresses
$PROC MACRO P1, P2, P3, P4, P5, P6, P7, P8, P9, P10
PUBLIC P1
IFIDN ,
@[email protected]@ = 6;; first parameter after saved caller's frame
ELSE;; and far return address
@[email protected]@ = 4;; first parameter after saved caller's frame
ENDIF;; and near return address
@[email protected]@ = @[email protected]@;; next parm address = first parm address
P1 PROC P2;; begin procedure
IFNB ;; if parms in proc def then execute $PARM
$PARM P3 P4 P5 P6 P7 P8 P9 P10
ENDIF
ENDM


; begin interrupt procedure, define flags option
$IPROC MACRO P1, FLAGS
@[email protected]@ = TRUE;; flag interrupt procedure
@[email protected]@ = 6
P1 PROC FAR
IFNB ;; if flags parm not blank then define it
@[email protected]@ = 6
$PARM FLAGS 2
ELSE;; else set @[email protected]@ as if defined
@[email protected]@ = 8
ENDIF
ENDM


$PARM MACRO P1, P2, P3, P4, P5, P6, P7, P8, P9, P10
LOCAL PARM
IFIDN , <$LAST>;; if keyword $LAST then
IF @[email protected]@;; if pascal call then
@[email protected]@ = @[email protected]@;; define partial stack cleanup
ENDIF
IFNB ;; if more then execute $PARM
$PARM P2 P3 P4 P5 P6 P7 P8 P9
ENDIF
ELSE;; else define parameter address
PARM = @[email protected]@
P1 EQU [BP + PARM]
.XCREF PARM, P1
@[email protected]@ = @[email protected]@ + P2;; address of next parameter
IFNB ;; if more then execute $PARM
$PARM P3 P4 P5 P6 P7 P8 P9 P10
ENDIF
ENDIF
ENDM


$VAR MACRO V1, V2, V3, V4, V5, V6, V7, V8, V9, V10
LOCAL VAR
@[email protected]@ = @[email protected]@ - V2;; subtract length of current variable
VAR = @[email protected]@;; create new symbol = to current @[email protected]@
V1 EQU [BP + VAR];; frame offset for variable
.XCREF VAR, V1
IFNB ;; then another variable exists
$VAR V3 V4 V5 V6 V7 V8 V9 V10;; recursive call
ENDIF
ENDM


@[email protected]@ MACRO P1;; cosmetic macro lists value
SUB SP, P1;; of P1 in .LST file
ENDM


$SAVE MACRO
@[email protected]@ = TRUE
PUSH BP;; save caller's frame pointer
MOV BP, SP;; set up new frame pointer
IF @[email protected]@;; if local variable(s) exist
IF @[email protected]@ EQ -1 OR @[email protected]@ EQ -2;; if 1 or 2 bytes
DEC SP
IF @[email protected]@ EQ -2;; if 2 bytes
DEC SP
ENDIF
ELSE
@[email protected]@ %[email protected]@@;; make room on stack for
ENDIF;; local variable(s)
ENDIF
ENDM


@[email protected]@ MACRO P1;; cosmetic macro lists value
RET P1;; of P1 in .LST file
ENDM


@[email protected]@ MACRO;; restore frame if necessary
IF @[email protected]@;; if local frame exists
IF @[email protected]@;; if local variable(s) exist then
MOV SP, BP;; restore stack pointer
ENDIF
POP BP;; restore caller's frame pointer
ENDIF
ENDM


$RET MACRO R1;; return selected by @[email protected]@
IF @[email protected]@
$IRET R1
ELSE
$PRET R1
ENDIF
ENDM


$PRET MACRO R1;; return from procedure call
@[email protected]@
IF @[email protected]@
@[email protected]@ = @[email protected]@;; set @[email protected]@ for partial cleanup
ENDIF
IF @[email protected]@ AND @[email protected]@ NE @[email protected]@
@[email protected]@ %@[email protected]@ - @[email protected]@;; RET n
ELSE
RET
ENDIF
IFNB ;; if R1 not empty then end procedure
$TERM R1
ENDIF
ENDM


$IRET MACRO R1;; return from interrupt
@[email protected]@
IRET
IFNB ;; if R1 not empty then end procedure
$TERM R1
ENDIF
ENDM


$RETURN MACRO R1;; same as $RET
$RET R1
ENDM


$TERM MACRO R1;; end procedure
R1 ENDP
@[email protected]@;; reset macro variables
ENDM


$LIST MACRO;; does not print .LIST
.LIST
ENDM


@[email protected]@ = TRUE; define pascal calling flag

.XCREF FALSE, TRUE, BS, HT, TAB, LF, FF, CR
.XCREF EOF, ESC, @[email protected]@, LB, HB, B, @[email protected]@
.XCREF LW, HW, W, @[email protected]@, D, @[email protected]@, @[email protected]@
.XCREF @[email protected]@, @[email protected]@, @[email protected]@, @[email protected]@
.XCREF $PASCAL, @[email protected]@, $C, $PROC
.XCREF $IPROC, $PARM, $VAR, @[email protected]@, $SAVE
.XCREF @[email protected]@, @[email protected]@, $RET, $PRET, $IRET
.XCREF $RETURN, $TERM, $LIST, NUL, DEL

@[email protected]@; set up defaults for first procedure

$LIST