There are 3 (or more) macros here.
Start
$$LA is an internal macro. The &fld can be either a label or a register, and it does the correct LA instruction.
* ---------------------------------
MACRO
&LBL $$LA ®,&FLD $$LA REVB ????
AIF ('&FLD(1,1)' NE '(').A
&LBL LA ®,0&FLD
MEXIT
.A ANOP
&LBL LA ®,&FLD
MEND
* ---------------------------------
REVB switches a branch condition. It's intended to be used as an internal macro it other macros. Look at the ERR macro to see it's use. But here are a couple samples:
* ---------------------
REVB B,Z
NOP Z
* ---------------------
REVB BE,Z
BNE Z
* ---------------------
REVB BNE,Z
BE Z
* ---------------------
REVB BH,Z
BNH Z
* ---------------------
REVB BNH,Z
BH Z
* ---------------------
Essentially, REVB either adds, or removes, the N in the branch condition.
MACRO
&LABEL REVB &COND,&TO
AIF ('&COND' NE 'B').CHANGE
&LABEL NOP &TO
MEXIT
.CHANGE LCLC &C,&A
LCLA &K
AIF ('&COND'(2,1) NE 'N').REMOVE
.*
&K SETA K'&COND.-2
&C SETC '&COND'(3,&K)
&A SETC 'B'
.* MNOTE ,'&A &C'
AGO .GO
.*
.REMOVE ANOP
&K SETA K'&COND.-1
&C SETC '&COND'(2,&K)
&A SETC 'BN'
.* MNOTE ,'&A &C'
.GO ANOP
&LABEL &A&C &TO
MEND
* ---------------------------------
ERR is used to define messages, and BAL to the err routine. In the ERR routine, there will be several options, depending on the first char in the message. It's written to minimize repeated code, yet provide options. EG:
- If the first char is blank, it writes the msg to SYSPRINT and returns.
If the first char is $ then it writes the current string being processed and then the error msg.
If the first char is blank, it writes the msg to SYSPRINT and returns.
If the first char is neither of those, it writes the msg, and abends.
(maybe) If the first char is #, it prints the registers.
MACRO
&LBL ERR &BC,&MSG
LCLC &L
&L SETC 'SYS&SYSNDX'
LCLA &N
&N SETA K'&MSG-3
&LBL REVB &BC,&L.Z
BAL R14,ERR
DC AL1(&N),C&MSG
&L.Z DS 0H
MEND
* ---------------------------------
End