;; SOUTH AUSTRALIAN INSTITUTE OF TECHNOLOGY ;; ---------------------------------------- ;; ;; SAENET PROGRAMMING SERVICES ;; --------------------------- ;; ;; ;;PROJECT DOCUMENTATION ;;--------------------- ;; ;;PROJECT NUMBER: CC016 ;; ;;PROJECT NAME: SAETAN ;; ;;DOCUMENT NAME: MACRO-11/SP INTERNAL DOCUMENTATION ;; ;;DOCUMENT VERSION: 1 ;; ;;AUTHOR: D L HERON ;; P O BOX 1, INGLE FARM, S. A., 5098, AUSTRALIA ;; ;;DATE: 11 JUL 77 ;; ;;---------------------------------------------------------------------- ;; ;; ;; SUMMARY ;; ======= ;; ;; THIS DOCUMENT IS THE INTERNAL DOCUMENTATION FOR THE MACRO-11/SP ;; STRUCTURED-PROGRAMMING MACROS. IT IS ALSO THE MASTER SOURCE FILE ;; FOR THE MACRO DEFINITIONS - SEE THE SECTION "CONVERSION TO ;; OPERATIONAL FORM". ;; ;; THE READER OF THIS DOCUMENT IS EXPECTED TO BE FULLY FAMILIAR ;; WITH ALL ASPECTS OF THE MACRO-11 LANGUAGE, AND WITH THE ;; MACRO-11/SP USER MANUAL. ;; ;;GENERAL ;;======= ;; ;; ;;INTERNAL MACROS ;;--------------- ;; ;;THERE ARE TWO TYPES OF INTERNAL MACROS: ;;$2X GROUP. THESE MACROS ('$20', '$22', '$24') PERFORM SPECIAL-PURPOSE ;;PROCESSING FOR CERTAIN USER MACROS. SEE INDIVIDUAL DESCRIPTIONS. ;; ;;$9X GROUP. THESE MACROS PERFORM UTILITY FUNCTIONS FOR ANY OTHER MACRO. ;; ;; ;;ASSEMBLY-TIME VARIABLES ;;----------------------- ;; ;;THERE ARE THREE GROUPS OF ASSEMBLY-TIME VARIABLES: ;;1. SIMPLE VARIABLES: $0, $1, ..., $12. ;;2. THE STACK: $20, $21, ..., $777 ;;3. CASE-STRUCTURE LABELS: $1000, $1001, ... ;; ;; ;;NOMENCLATURE ;;------------ ;; ;;A NUMBER OF VARIABLES ARE CALLED "SYMBOL-NUMBERS" AND "LOCAL-LABEL-NUMBERS". ;; ;;A SYMBOL-NUMBER IS A VARIABLE THAT, WHEN ITS VALUE IS CONVERTED TO OCTAL ;;CHARACTER REPRESENTATION AND PRECEDED BY A "$", FORMS AN ;;ASSEMBLY-TIME SYMBOL. FOR EXAMPLE, $0 IS THE SYMBOL-NUMBER OF THE NEXT FREE ;;SYMBOL ON THE STACK: WHEN THE STACK IS EMPTY, $0 = 20, AND $20 IS THE ;;NEXT FREE STACK LOCATION. ;; ;;SIMILARLY, A LOCAL-LABEL-NUMBER IS A VARIABLE THAT, WHEN ITS VALUE IS ;;CONVERTED TO OCTAL CHARACTER REPRESENTATION AND FOLLOWED BY A "$", FORMS ;;A LOCAL LABEL. ;; ;; ;;SIMPLE VARIABLES ;;---------------- ;; ;;$0 IS THE STACK POINTER. IT CONTAINS THE SYMBOL-NUMBER OF THE NEXT FREE ;;VARIABLE OF THE STACK. SET TO 20 BY 'MACSP'. INCREMENTED BY '$90' ;;AND DECREMENTED BY '$91'., AND MAY BE INCREMENTED BY OTHER MACROS ;;WHICH LOOK AT THE TOP ELEMENTS OF THE STACK BUT DO NOT CHANGE THEM, ;;OR DECREMENTED TO PURGE ELEMENTS FROM THE STACK. ;; ;;$1 IS THE LOCAL-LABEL-NUMBER OF THE NEXT AVAILABLE LOCAL LABEL. ;;SET TO 1 BY 'MACSP', AND INCREMENTED BY '$92'. ;; ;;$2 IS USED BY 'IFC' TO IMPLEMENT 'IF' ... 'AND'. WHEN NON-ZERO, ;;IT INDICATES THAT 'IF' ... 'AND' HAS OCCURRED WITHOUT TERMINATION YET OF THE ;;COMPOUND CONDITION; IT THEN CONTAINS THE LOCAL-LABEL-NUMBER ;;OF THE DESTINATION OF THE FALSE BRANCH. SET TO 0 BY 'MACSP', AND MANIPULATED ;;BY 'IFC'. ;; ;;$3 IS USED BY 'IFC' TO IMPLEMENT 'IF' ... 'OR', AND BY 'EXLOOP' ;;TO IMPLEMENT 'EXLOOP IF...'. WHEN NON-ZERO, IT INDICATES ;;THAT ONE OF THESE CONSTRUCTS IS BEING PROCESSED; IT THEN CONTAINS ;;THE LOCAL-LABEL-NUMBER OF THE DESTINATION OF THE TRUE BRANCH, WHICH ;;IS THE BOTTOM-OF-LOOP LABEL IN THE 'EXLOOP' CASE. SET TO 0 BY 'MACSP', ;;AND MANIPULATED BY 'IFC' AND 'EXLOOP'. ;; ;;$4 IS USED BY 'EXLOOP' AND 'IFC' TO IMPLEMENT 'EXLOOP IF...'. ;;WHEN NON-ZERO, IT INDICATES THAT 'EXLOOP IF' HAS OCCURRED WITHOUT ;;TERMINATION OF PROCESSING THE (SIMPLE OR COMPOUND) CONDITION. ;;SET TO 0 BY 'MACSP', SET TO 1 BY 'EXLOOP', SET TO 0 BY 'IFC'. ;; ;;$5, $6, AND $7 ARE WORK VARIABLES. THEY ARE UNDEFINED ON ENTRY TO ;;AND EXIT FROM ANY MACRO. EXCEPTION: THE $9X GROUP MAY NOT ;;CHANGE THEM, EXCEPT WHEN THEY ARE PASSED IN A PARAMETER. ;; ;;$8, WHEN NON-ZERO, IS THE LOCAL-LABEL-NUMBER OF THE BOTTOM OF THE CURRENT ;;LOOP. SET TO 0 BY 'MACSP', SAVED ON THE STACK AND THEN SET ;;TO ZERO BY 'LOOP', SET NON-ZERO WHEN A BOTTOM LABEL IS REQUIRED, ;;BY 'LOOP' OR 'EXLOOP'. 'REPEAT' GENERATES THE LABEL IF $8 IS NON-ZERO, ;;AND THEN UNSTACKS THE SAVED VALUE. ;; ;;$9 IS 0 WHEN 'EXLOOP' IS VALID. SET TO 1 BY 'MACSP'. SAVED ON THE STACK ;;AND THEN SET TO 0 BY 'LOOP', AND UNSTACKED BY 'REPEAT'. INCREMENTED BY ;;'PROC' (ALSO CALLED BY 'BEGIN') AND DECREMENTED BY 'END'. ;; ;;$10 IS NON-ZERO IF THE 'LIST' OPTION APPEARED ON 'MACSP'. SET BY ;;'MACSP' (INITIAL USER'S CALL ONLY) AND READ BY '$93' AND '$94'. ;; ;;$11 IS THE SYMBOL-NUMBER OF THE NEXT SPARE SYMBOL. THESE SYMBOLS ;;ARE USED BY 'CASE' ... 'CASEND', WHERE THE INDEFINITE SIZE OF THE STRUCTURE ;;MAKES LOCAL LABELS UNUSABLE. SET TO 1000 BY 'MACSP' (INITIAL CALL ONLY), ;;AND UPDATED BY 'CASE' (AND POTENTIALLY ANY MACRO WHICH NEEDS ;;SUCH SYMBOLS). ;; ;;$12 IS USED BY 'VALUE' TO ENSURE THAT NEGATIVE VALUES IN VALUE LISTS ;;(UPPER LIMITS OF VALUE RANGES) ARE PRECEDED BY A POSITIVE VALUE OF SMALLER ;;MAGNITUDE. SET TO 77777 BY 'MACSP', AND MANIPULATED BY 'VALUE'. ;; ;; ;;THE STACK ;;--------- ;; ;;BECAUSE THE CONTROL STRUCTURES CAN BE NESTED TO AN INDEFINITE DEPTH, ;;AN ASSEMBLY-TIME STACK IS USED TO RECORD NECESSARY DATA ABOUT ;;ANY STRUCTURES WHICH ARE CURRENTLY NOT COMPLETED. THE INITIAL STATEMENT ;;OF THE STRUCTURE PUSHES THE DATA ONTO THE STACK, INTERMEDIATE STATEMENTS ;;(IF ANY) ACCESS THE DATA AND UPDATE IT IF NECESSARY, AND THE FINAL STATEMENT ;;REMOVES AND READS THE DATA. BECAUSE ONLY COMPLETE STRUCTURES CAN ;;LEGALLY BE NESTED WITHIN OTHER STRUCTURES, THE INTERMEDIATE ;;STATEMENTS CAN EXPECT TO FIND THE RIGHT DATA ON TOP ;;OF THE STACK. (THE ONLY EXCEPTION TO THIS IS 'EXLOOP', WHICH CAN ;;APPEAR WITHIN OTHER STRUCTURES - $8 AND $9 TAKE CARE OF THAT SITUATION.) ;; ;;THE STACK IS IN THE VARIABLES FROM $20 UPWARDS TO $777; SEE WRITEUP ;;OF $0. DATA IS PUSHED ONTO THE STACK BY '$90' AND POPPED OFF BY '$91'. ;;THE ONLY TYPE OF DATA WHICH CAN BE ;;STACKED IS UNSIGNED NUMBERS IN THE RANGE 0 TO 7777(8). ;; ;;EACH WORD ON THE STACK IS MADE UP OF THREE FIELDS: ;; BIT 15 IS ALWAYS ZERO, SO THAT '$91' CAN EXTRACT THE DATA BY SIMPLE ;; DIVISION. ;; BITS 14 TO 3 CONTAIN THE 12-BIT POSITIVE DATA. ;; BITS 2 TO 0 CONTAIN THE STACK ENTRY TYPE. ;; ;;THE ENTRY TYPE IS USED TO CHECK THE VALIDITY OF NESTING. ;;THE TOP WORD OF THE DATA PUSHED ONTO THE STACK BY THE INITIAL ;;STATEMENT(S) OF EACH STRUCTURE HAS AN ENTRY TYPE SPECIFIC TO THAT ;;STRUCTURE. SUBSEQUENT STATEMENTS OF THE STRUCTURE DECLARE AN ;;ERROR 'N' IF THE TOP ENTRY OF THE STACK IS NOT OF THE CORRECT TYPE. ;;LOWER WORDS OF DATA PUSHED ON FOR A STRUCTURE HAVE TYPE = 0, ;;TO DISTINGUISH THEN FROM TOP WORDS; THIS REDUCES THE CHANCE OF UNDETECTED ;;ERRORS IF THE USER GETS THE STRUCTURE TOTALLY LOST. ;; ;;THE ENTRY TYPES ARE: ;; 1 - PROC/BEGIN ... END ;; 2 - LOOP/LOOPB ... REPEAT ;; 3 - CASE ... VALUE ... CASEND ;; 4 - IF/IFB/IFC ... ELSE ... FI ;; ;;REFERENCES TO STACK DATA IN DESCRIPTIONS OF INDIVIDUAL STRUCTURES ARE ;;ONLY TO THE CONTENTS OF THE 12-BIT DATA FIELD. ;; ;; ;;CONVERSION TO OPERATIONAL FORM ;;------------------------------ ;; ;;THIS FILE IS THE MASTER FILE FOR THE MACRO DEFINITIONS. ;;THE OPERATIONAL FORM OF THE MACROS IS CREATED BY DELETING ALL SUPERFLUOUS ;;COMMENT LINES FROM THIS FILE; THESE ALL START WITH ";;". ;; ;;IN RT-11 EDIT, USE: ;; .R EDIT ;; *ERMACSP.DOC$$ ;; *EWMACSP.MAC$$ ;; *9999$$ ;; *EX$$ ;; .R PIP ;; *SYSMAC.DEC/R=SYSMAC.SML ;; *SYSMAC.SML/A=MACSP.MAC,SYSMAC.DEC ;; *^C ;; ;; ;;COMMENTS BELOW ALWAYS FOLLOW THE LINE(S) TO WHICH THEY REFER. ;; ;;====================================================================== ;; ;MACRO-11/SP STRUCTURED PROGRAMMING MACROS FOR PDP-11. ;MACROS V03. JUN 77 ;; ;;====================================================================== ;; .MACRO MACSP L,I ;;IF 'L' IS NON-BLANK, IT IS TAKEN TO BE 'LIST'. ;;'PROC' CALLS 'MACSP' WITH 'I' NON-BLANK TO RE-INITIALISE MOST VARIABLES ;;AT THE START OF EACH PROCEDURE. .IF B,I ;; USER'S CALL AT START OF PROGRAM - DO THE ONCE-ONLY THINGS .MCALL IF,IFB,IFC,ELSE,FI,CALL,PROC,BEGIN,END .MCALL LOOP,LOOPB,EXLOOP,REPEAT,CASE .MCALL $20,$22,$90,$91,$92,$93,$94 $10=0 .IIF NB,L,$10=1 $11=1000 .ENDC $0=20 ;;NOTE THE 20 VALUE ALSO APPEARS IN 'PROC' $1=1 ;;$1 IS THE ONLY VARIABLE WHICH MUST BE RESET AT EACH 'PROC'; ;;THE OTHERS ARE RESET TO IMPROVE ERROR RECOVERY. $2=0 $3=0 $4=0 $8=0 $9=1 $12=77777 .ENDM ;; ;;IF/IFB/IFC ... ELSE ... FI ;;========================== ;; ;;DESCRIPTION ;;----------- ;; ;;CODE: GENERATES: ;;IF A EQ B THEN CMP A,B ;; BNE I$ ;; ... ... ;;ELSE BR J$ ;; I$: ;; ... ... ;;FI J$: ;; ;;RE-READ DESCRIPTIONS OF $2, $3 AND $4. 'IF' ... 'THEN' GENERATES ;;A TEST INSTRUCTION (EXCEPT 'IFC') AND THEN (VIA 'IFC') A "FALSE BRANCH" (IE A ;;BRANCH FOR THE NEGATED CONDITION) TO THE "FALSE DESTINATION" (I$ ABOVE). ;;IT STACKS THE VALUE 'I', AND A ZERO "ELSE FLAG". IF THERE IS NO ;;'ELSE', 'FI' FINDS 'I' ON THE STACK AND GENERATES THE FALSE DESTINATION ;;LABEL. IF THERE IS AN 'ELSE', 'ELSE' FINDS THE 'I', GENERATES THE CODE ;;SHOWN, AND STACKS 'J' FOR 'FI' TO FIND. 'ELSE' SETS THE ELSE FLAG ;;IN THE STACK ENTRY, SO THAT A SUBSEQUENT 'ELSE' WILL DECLARE AN ERROR N. ;; ;;'IF' ... 'AND' GENERATES THE TEST (IF ANY), AND THEN A FALSE BRANCH ;;TO THE FALSE DESTINATION. ;; ;;'IF' ... 'OR' GENERATES A TEST (IF ANY), AND THEN A TRUE BRANCH ;;TO THE "TRUE DESTINATION". THE SUBSEQUENT 'IF' ... 'THEN' ;;GENERATES THE TRUE DESTINATION AFTER THE FALSE BRANCH INSTRUCTION. ;; ;;CODE: GENERATES: ;;IF A EQ B AND CMP A,B ;; BNE I$ ;;IF C EQ D OR CMP C,D ;; BEQ J$ ;;IF E EQ F THEN CMP E,F ;; BNE I$ ;; J$: ;; ... ... ;;ELSE BR K$ ;; I$: ;; ... ... ;;FI K$: ;; ;;'EXLOOP IF' FITS INTO THE ABOVE LOGIC FAIRLY EASILY. IN THAT CASE ;;THE TRUE DESTINATION IS THE BOTTOM OF THE LOOP, AND 'IF' ... ;;GENERATES THE FALSE DESTINATION AFTER THE TRUE BRANCH THAT IT GENERATES. ;; ;;STACK DATA ;;---------- ;; ;;TOP WORD (PUSHED BY 'IF' ... 'THEN', UPDATED BY 'ELSE'): ;; BIT 0 SET => 'ELSE' HAS OCCURRED ;; BITS 11 TO 1 = LOCAL-LABEL-NUMBER OF THE OUTSTANDING DESTINATION ;; ;;====================================================================== ;; .MACRO IF S,Q,D,T ;;ALSO CALLED BY 'EXLOOP IF' $20 ,,, IFC , .ENDM ;; ;;====================================================================== ;; .MACRO IFB S,Q,D,T ;;ALSO CALLED BY 'EXLOOP IFB' $20 B,,, IFC , .ENDM ;; ;;====================================================================== ;; .MACRO $20 V,S,Q,D ;;CALLED BY 'IF' AND 'IFB' TO GENERATE THE REQUIRED TEST INSTRUCTION. ;;'V' : BLANK FOR WORDS (FROM 'IF'), "B" FOR BYTES (FROM 'IFB') ;;'S' : SOURCE OPERAND ;;'Q' : RELATION MNEMONIC ;;'D' : DESTINATION OPERAND. "#0" TREATED SPECIALLY. .IF DIF,, .IF DIF,, ;; WE NEED A 'CMP(B)' OR 'TST(B)' .IF IDN,,<#0> $93 .IFF $93 .ENDC .MEXIT .ENDC .ENDC $93 ;;FOR 'IN' AND 'NI' .ENDM ;; ;;====================================================================== ;; .MACRO IFC Q,T ;;ALSO CALLED BY 'IF' AND 'IFB' TO GENERATE THE CONDITIONAL BRANCH INSTRUCTION, ;;AND BY 'EXLOOP IFC' .IF IDN,, ;; BEGINNING OF 'IFX' ... ['ELSE' ...] 'FI' .IIF NE,$4,.ERROR ;U ;; CANNOT HAVE 'EXLOOP IF ... THEN' .IIF EQ,$2,$92 $2 ;; GET FALSE DESTN LABEL UNLESS 'IF' ... 'AND' HAS ALREADY DONE SO $90 $2*2,4,\$0 ;; STACK THE LABEL AND 'ELSE' FLAG = 0 $22 F,,\$2 ;; GENERATE THE FALSE BRANCH INSTRUCTION $2=0 .IIF NE,$3,$94 \$3,$: ;; GENERATE THE TRUE DESTN LABEL, IF WE HAD 'IF' ... 'OR' $3=0 .MEXIT .ENDC .IF B,T ;; NO 'THEN', 'AND' OR 'OR' .IIF EQ,$4,.ERROR ;U ;; ERROR IF NOT 'EXLOOP IFX' $4=0 $22 ,,\$3 ;; GENERATE TRUE BRANCH TO BOTTOM OF LOOP $3=0 .IIF NE,$2,$94 \$2,$: ;; GENERATE FALSE DESTN LABEL, IF WE HAD 'IF' ... 'AND' $2=0 .MEXIT .ENDC .IF IDN , .IIF EQ,$2,$92 $2 ;; GET FALSE DESTN LABEL, UNLESS ALREADY HAVE ONE $22 F,,\$2 ;; GENERATE THE FALSE BRANCH .MEXIT .ENDC .IF IDN,, .IIF EQ,$3,$92 $3 ;; GET TRUE DESTN LABEL, UNLESS ALREADY HAVE ONE $22 ,,\$3 ;; GENERATE THE TRUE BRANCH .MEXIT .ENDC .ERROR ;U ;;SOMETHING OTHER THAN 'THEN', BLANK, 'AND' OR 'OR' .ENDM ;; ;;====================================================================== ;; .MACRO $22 F,Q,L ;;CALLED BY 'IFC' TO GENERATE A CONDITIONAL BRANCH INSTRUCTION. ;;'F' : BLANK => GENERATE TRUE BRANCH ;; NON-BLANK => GENERATE FALSE BRANCH ;;'Q' : CONDITION MNEMONIC ;;'L' : CHARACTER REPRESENTATION OF DESTINATION LOCAL LABEL NUMBER $6=0 .IIF IDN,,,$6=BLT .IIF IDN,,,$6=BLE .IIF IDN,,,$6=BGE .IIF IDN,,,$6=BGT .IIF IDN,,,$6=BLO .IIF IDN,,,$6=BLOS .IIF IDN,,,$6=BHIS .IIF IDN,,,$6=BHI .IIF IDN,,,$6=BNE .IIF IDN,,,$6=BEQ ;;SEARCH THE LIST OF SPECIFIC MNEMONICS .IIF EQ,$6,$6=B'Q ;;IF NOT FOUND, TRY ADDING "B" TO THE MNEMONIC, FOR 'EQ', 'CC', ETC .IIF NE,$6&74377,.ERROR ;U ;;$6 SHOULD NOW CONTAIN A BRANCH OPCODE. ;;MAKE SURE IT LOOKS LIKE ONE. NB THIS DOESN'T DETECT ALL ERRORS. $6=$6/400&377 ;;SHIFT OPCODE TO BOTTOM BYTE OF $6 .IIF NB,F,$6=$6!1-<$6&1> ;;FLIP THE BOTTOM BIT FOR A FALSE BRANCH $93 BR,L ;;GENERATE UNCONDITIONAL BRANCH TO THE DESTN - EASY WAY TO GET THE OFFSET $94 .=.-1 ;;BACK UP A BYTE $93 <.BYTE $6> ;;PUT THE CONDITIONAL BRANCH OPCODE INTO THE HIGH BYTE OF THE INSTRUCTION .ENDM ;; ;;====================================================================== ;; .MACRO ELSE $91 $6,4,\$0-1 ;;UNSTACK LOCAL-LABEL-NUMBER AND 'ELSE' FLAG .IIF NE,$6&1,.ERROR ;N ;;ALREADY HAD 'ELSE' $93 BR,\$1 ;;BRANCH TO THE 'FI' $90 $1*2+1,4,\$0 ;;STACK THE 'FI' LOCAL-LABEL-NUMBER AND ELSE FLAG = 1 $92 ;;ADVANCE $1 $94 \$6/2,$: ;;GENERATE THE FALSE DESTN LABEL .ENDM ;; ;;====================================================================== ;; .MACRO FI $91 $6,4,\$0-1 ;;UNSTACK THE 'FI' LABEL $94 \$6/2,$: ;;GENERATE IT .ENDM ;; ;;CALL, PROC/BEGIN ... END ;;======================== ;; ;;DESCRIPTION ;;----------- ;; ;;THE PROCESSING BY 'PROC' IS STRAIGHTFORWARD. IT SCANS LEFT TO RIGHT ;;THROUGH ITS PARAMETERS, GENERATING CODE AND STACK DATA FOR ;;'END' TO FIND. 'END' SIMPLY DOES THE APPROPRIATE THINGS; THE DATA ;;IT USES ON THE MACRO STACK IS CONVENIENTLY PRESENTED IN THE REQUIRED ;;ORDER. 'BEGIN' CALLS 'PROC'. ;; ;;STACK DATA ;;---------- ;; ;;TOP WORD: ;; BIT 0 SET => 'CRITICAL' ;; BIT 1 SET => BLOCK ACQUIRED ;; BITS 11 TO 2 = COUNT OF REGISTERS TO BE RESTORED BY 'END' ;;NEXT WORD (ABSENT IF BIT 1 = 0 IN TOP WORD): ;; BITS 11 TO 0 = SIZE (BYTES) OF ACQUIRED BLOCK ;;FOLLOWED BY ONE WORD PER REGISTER TO BE RESTORED, IN ORDER OF RESTORATION: ;; BITS 11 TO 0 = REGISTER NUMBER ;; ;;====================================================================== ;; .MACRO CALL L $93 .ENDM ;; ;;====================================================================== ;; .MACRO PROC L,S,B,C ;;ALSO CALLED (WITH 'L' BLANK) BY 'BEGIN' $6=0 ;;BUILD UP TOP-OF-STACK ENTRY IN $6 .IF NB,L ;; 'PROC' NOT 'BEGIN' .IIF NE,$0-20,.ERROR ;N ;; 'PROC' MUST NOT BE NESTED IN ANYTHING MACSP ,I ;; RE-INITIALISE MOST VARIABLES $6=4 ;; INCREMENT COUNT OF REGISTERS TO BE RESTORED BY 'END' $90 7,0,\$0 ;; LAST REG TO RESTORE IS %7 - THIS WILL EFFECT THE RETURN $94 L: ;; GENERATE THE LABEL .ENDC $5=-1 ;;SET $5 TO INVALID REG NUMBER TO TRAP ERROR P .IRP R, ;; LOOP THRU REGISTER SAVE LIST .NTYPE $5,R ;; $5 = NUMBER OF REGISTER .IIF GT,$5-5,.ERROR ;T ;; CAN ONLY SAVE REGS 0 TO 5 $6=$6+4 ;; INCREMENT COUNT OF REGS TO BE RESTORED $90 $5,0,\$0 ;; STACK THE NUMBER OF THE REG TO BE RESTORED $93 ;; INSTRUCTION TO SAVE THE REG .ENDR .IF NB,B ;; BLOCK OF STORAGE WANTED .IIF LT,$5,.ERROR ;P ;; THERE MUST HAVE BEEN A REG SAVED .IIF LE,B,.ERROR ;V ;; BLOCK SIZE MUST BE POSITIVE $7=B+1/2*2 ;; $7 = BLOCK SIZE (ROUNDED UP) .IIF GT,$7-7776,.ERROR ;V ;; CAN'T GET MORE THAN 7776 BYTES (DUE TO LIMITATIONS OF MACRO STACK) $93 ;; INSTRUCTION TO PULL THE STACK POINTER BACK TO CREATE THE HOLE $93 \10600+$5 ;; INSTRUCTION TO COPY SP TO THE LAST REG IN THE SAVE LIST $90 $7,0,\$0 ;; STACK THE BLOCK SIZE $6=$6+2 ;; SET 'BLOCK ACQUIRED' FLAG IN TOP-OF-STACK WORD .ENDC .IF NB,C ;; 'CRITICAL' SPECIFIED .IIF DIF,,,.ERROR ;U ;; AND NO SPELLING MISTAKES CAN BE MADE EITHER $6=$6+1 ;; SET 'CRITICAL' FLAG IN TOP-OF-STACK WORD $93 ;; INSTRUCTION TO SAVE PS ON THE STACK $93 ;; INSTRUCTION TO SET PRIORITY 7 .ENDC $90 $6,1,\$0 ;;STACK ALL THAT INFO FOR 'END' $9=$9+1 ;;INCREMENT COUNT TO TRAP 'EXLOOP' BETWEEN HERE AND THE 'END' .ENDM ;; ;;====================================================================== ;; .MACRO BEGIN S,B,C PROC ,,, .ENDM ;; ;;====================================================================== ;; .MACRO END $9=$9-1 ;;DECREMENT 'EXLOOP' TRAPPER $91 $6,1,\$0-1 ;;POP THE GOODIES SET UP BY 'PROC' .IIF NE,$6&1,$93 ;;INSTRUCTION TO POP THE PS IF IT WAS 'CRITICAL' .IF NE,$6&2 ;; BLOCK OF STORAGE WAS ACQUIRED $91 $7,0,\$0-1 ;; POP THE SIZE $93 ;; INSTRUCTION TO SHOVE SP DOWN TO RECLAIM THE BLOCK .ENDC .REPT $6/4 ;; LOOP THRU TO RESTORE REGS $91 $5,0,\$0-1 ;; POP THE REG NUMBER $93 \12600+$5 ;; INSTRUCTION TO POP THE REG .ENDR .ENDM ;; ;;LOOP/LOOPB ... EXLOOP ... REPEAT ;;================================ ;; ;;DESCRIPTION ;;----------- ;; ;;RE-READ DESCRIPTIONS OF $4, $8 AND $9. ;; ;;A NON-COUNTED LOOP IS VERY SIMPLE. 'LOOP' STACKS AND ZEROES $8 AND $9, ;;AND THEN GENERATES THE TOP-OF-LOOP LABEL, AND STACKS ITS NUMBER ;;AND A ZERO "COUNTED-LOOP" FLAG. 'REPEAT', FINDING THE ZERO COUNTED-LOOP ;;FLAG, SIMPLY GENERATES AN UNCONDITIONAL BRANCH BACK TO THE TOP ;;OF LOOP, AND THEN THE BOTTOM-OF-LOOP LABEL IF $8 IS NON-ZERO. ;;IT THEN UNSTACKS $8 AND $9. ;; ;;FOR A COUNTED LOOP, 'LOOP' GENERATES CODE TO PUSH THE COUNT ON TOP ;;OF THE STACK (OR A 'TST' IF THE OPERAND IS "(SP)+"), AND THEN A 'BEQ' ;;TO BOTTOM OF LOOP TO PROVIDE THE ZERO TRIP (EXCEPT FOR A CONSTANT COUNT). ;;IT STACKS THE SAME DATA AS FOR NON-COUNTED LOOPS EXCEPT THAT THE ;;COUNTED-LOOP FLAG IS SET. 'REPEAT', FINDING THE COUNTED-LOOP FLAG SET, ;;GENERATES CODE TO DECREMENT THE COUNT AND BRANCH BACK TO THE TOP OF LOOP ;;IF THE COUNT IS NOT EXHAUSTED, AND THEN (AFTER THE BOTTOM-OF-LOOP LABEL ;;IF REQUIRED) POP THE COUNT OFF THE STACK. ;; ;;'LOOPB' GENERATES CODE TO GET THE OPERAND ON TOP OF THE STACK, WITH ;;ZERO IN THE HIGH BYTE, AND THEN CALLS 'LOOP' WITH OPERAND "-(%7)" TO ;;PERFORM THE REST OF THE PROCESSING. ;; ;;AN UNCONDITIONAL 'EXLOOP' GENERATES A BRANCH TO THE LABEL REMEMBERED IN $8, ;;HAVING FIRST SET $8 IF IT IS ZERO. A CONDITIONAL 'EXLOOP' SETS $3 AND $4 ;;FOR 'IFC' TO FIND, AND THEN CALLS ITS FIRST PARAMETER, BLINDLY TRUSTING ;;THAT IT IS ONE OF 'IF', 'IFB' AND 'IFC'. ;; ;;STACK DATA ;;---------- ;; ;;TOP WORD: ;; BIT 0 SET => COUNTED LOOP ;; BITS 11 TO 1 = LOCAL-LABEL-NUMBER OF TOP-OF-LOOP LABEL ;;NEXT WORD: ;; BITS 11 TO 0 = SAVED VALUE OF $9 ;;NEXT WORD: ;; BITS 11 TO 0 = SAVED VALUE OF $8 ;; ;;====================================================================== ;; .MACRO LOOP S ;;ALSO CALLED BY 'LOOPB', WITH PARAMETER '-(%7)' - THE USER ;;REALLY SHOULD NOT SPECIFY THAT AS A SOURCE OPERAND!! $90 $8,0,\$0 $8=0 ;;STACK AND ZERO $8 (BOTTOM LABEL) $90 $9,0,\$0 $9=0 ;;STACK AND ZERO $9 (EXLOOP TRAPPER) $5=0 ;;CLEAR THE 'COUNTED-LOOP' FLAG .IF NB,S ;; COUNTED LOOP .NTYPE $5,S ;; $5 = TYPE OF LOOP COUNT OPERAND .IF EQ,$5-26 ;; COUNT IS '(SP)+', WE DON'T NEED TO PUSH IT ONTO THE STACK $93 ;; INSTRUCTION TO TEST FOR ZERO COUNT .IFF .IIF NE,$5-47,$93 ;; PUSH COUNT ON STACK, UNLESS 'LOOPB' HAS ALREADY DONE SO .ENDC .IF EQ,$5-27 ;; COUNT IS '#EXPRESSION' $94 <$94 $5=,^>,S,# ;; $5 = EXPRESSION VALUE (THE ABOVE STRIPS THE "#" OFF) .IIF EQ,$5,.ERROR ;Z ;; CANNOT HAVE EXPRESSION = 0 .IFF ;; COUNT IS A VARIABLE $92 $8 ;; WE NEED A BOTTOM LABEL $93 BEQ,\$8 ;; INSTRUCTION TO PROVIDE THE ZERO TRIP .ENDC $5=1 ;; SET THE 'COUNTED-LOOP' FLAG .ENDC $90 $1*2+$5,2,\$0 ;;STACK TOP LABEL AND 'COUNTED-LOOP' FLAG $94 \$1,$: ;;GENERATE THE TOP LABEL $92 ;;ADVANCE $1 .ENDM ;; ;;====================================================================== ;; .MACRO LOOPB S .NTYPE $5,S .IF EQ,$5&7-6 ;; OPERAND IS REFERENCED VIA SP - SPECIAL TREATMENT NEEDED .IIF NE,$5-26,$93 ;; INSTRUCTION TO PUSH OPERAND ON TOP OF STACK UNLESS IT'S ALREADY THERE $93 ;; INSTRUCTION TO CLEAR THE HIGH BYTE OF THE TOP WORD OF THE STACK .IFF ;; NOT REFERENCED VIA SP - GENERATE BETTER CODE $93 ;; INSTRUCTION TO CREATE A ZERO TOP WORD ON THE STACK $93 ;; INSTRUCTION TO MOVE THE OPERAND TO THE LOW BYTE OF THE TOP WORD .ENDC LOOP -(%7) ;;CALL 'LOOP' TO DO THE REST, WITH A MAGIC PARAMETER .ENDM ;; ;;====================================================================== ;; .MACRO EXLOOP I,S,Q,D,T .IIF NE,$9,.ERROR ;N ;;CANNOT EXLOOP IF WE HAVE SOME UN-'END'ED 'BEGIN'S .IIF EQ,$8,$92 $8 ;;WE NEED A BOTTOM LABEL - GET IT UNLESS SOMEONE ELSE HAS ALREADY .IF B,I ;; UNCONDITIONAL 'EXLOOP' $93 BR,\$8 ;; SO WE NEED AN UNCONDITIONAL BRANCH TO THE BOTTOM .IFF $4=1 ;; SET FLAG FOR 'IFC' $3=$8 ;; TRUE DESTINATION IS BOTTOM OF LOOP I S Q D T ;; CALL 'IFX' TO DO THE REST .ENDC .ENDM ;; ;;====================================================================== ;; .MACRO REPEAT $91 $6,2,\$0-1 ;;POP TOP LABEL AND 'COUNTED LOOP' FLAG .IF NE,$6&1 ;; COUNTED LOOP $93 ;; INSTRUCTION TO DECREMENT THE LOOP COUNT $93 BNE,\$6/2 ;; INSTRUCTION TO GO BACK IF THE COUNT HAS NOT EXPIRED .IFF ;; NON-COUNTED LOOP $93 BR,\$6/2 ;; UNCONDITIONAL BRANCH BACK TO TOP .IFTF ;; FOR EITHER TYPE OF LOOP .IIF NE,$8,$94 \$8,$: ;; GENERATE THE BOTTOM LABEL, IF ONE IS WANTED .IFT ;; MEANWHILE, BACK AT THE COUNTED LOOP... $93 ;; INSTRUCTION TO POP THE COUNT WORD OFF THE STACK AT LOOP EXIT .ENDC $91 $9,0,\$0-1 ;;UNSTACK $9 ... $91 $8,0,\$0-1 ;;... AND $8 .ENDM ;; ;;CASE ... VALUE ... CASEND ;;========================= ;; ;;DESCRIPTION ;;----------- ;; ;;CODE: GENERATES: ;;CASE R0,3 CMP R0,#3 ;; BHI X ;; ASL R0 ;; ADD PC,R0 ;; ADD 4(R0),PC ;; $I=. ;OFFSET TABLE ;; L0: .WORD $J-$I ;OFFSET FOR VALUE 0 ;; L1: .WORD $J-$I ;OFFSET FOR VALUE 1 ;; L2: .WORD $J-$I ;OFFSET FOR VALUE 2 ;; L3: .WORD $J-$I ;OFFSET FOR VALUE 3 ;; X: ;; $J=. ;; ... ... ;;VALUE <0,2> JMP $K ;; Y=. ;; .=L0 ;; .WORD Y-$I ;; .=L2 ;; .WORD Y-$I ;; .=Y ;; ... ... ;;VALUE JMP $K ;; $J=. ;; ... ... ;;CASEND $K=. ;; ;;RE-READ DESCRIPTIONS OF $11 AND $12. THE ABOVE EXAMPLE SHOWS ;;TYPICAL PROCESSING, EXCLUDING 'PACKED' AND VALUE RANGES. THE LABELS ;;L0 TO L3, X AND Y ARE FOR ILLUSTRATION ONLY; THEY ARE NOT GENERATED. ;;THREE SYMBOLS - SHOWN AS $I, $J AND $K - ARE GENERATED PER STRUCTURE ;;(BY '=.' RATHER THAN BY ':' TO AVOID LOCAL-LABEL PROBLEMS FOR A CONTAINING ;;'IF' ... 'FI' OR 'LOOP' ... 'REPEAT'). $I IS THE ADDRESS OF THE OFFSET ;;TABLE. $J IS THE ADDRESS OF THE UNSELECTED-VALUE CODE. ;;$K IS THE ADDRESS OF THE 'CASEND'. J = I+1 AND K = I+2; $11 SUPPLIES ;;THE VALUE OF I. ;; ;;$J MAY BE RE-ASSIGNED, AS SHOWN. IT IS SET TO THE DEFAULT VALUE (THE ;;OUT-OF-RANGE CODE STRAIGHT AFTER THE 'CASE') BY 'CASE', BUT IT IS MOVED ;;BY 'VALUE' WITH NO LIST, SO THAT AT THE END OF PASS 1 IT POINTS TO THE ;;CODE AFTER THE LAST LIST-LESS 'VALUE'. THEN ON PASS 2 ALL OFFSET TABLE ;;ENTRIES ARE SET TO THE DESIRED UNSELECTED-VALUE OFFSET. ;; ;;A 'VALUE' STATEMENT WITH A LIST GOES BACK AND PATCHES THE OFFSET TABLE ;;ENTRY(S) WHICH CORRESPOND TO THE VALUES IN ITS LIST, TO SET THEM TO THE OFFSET ;;FROM $I TO THE CODE WHICH WILL FOLLOW. BOTH VARIETIES OF 'VALUE' ;;FIRST GENERATE A 'JMP' TO THE 'CASEND' (IE $K). ;; ;;HENCE AT THE END OF ASSEMBLY THE OFFSET TABLE ENTRIES CONTAIN, FOR ;;EACH VALUE IN THE VALID RANGE, THE OFFSET TO THE APPROPRIATE CODE. ;;THE 'CASE' CODE FIRST DIVERTS OUT-OF-RANGE VALUES TO THE CODE AFTER THE ;;'CASE' STATEMENT (IF THE OFFSET TABLE IS TOO LARGE FOR A BRANCH, ;;IT GENERATES A BRANCH ROUND A 'JMP'). 'CASE' THEN MULTIPLIES THE OPERAND ;;BY 2 TO PRODUCE AN INDEX INTO THE WORD TABLE, AND THEN ADDS PC. ;;BECAUSE THERE ARE 4 BYTES BETWEEN THAT INSTRUCTION AND THE ZERO-INDEX ;;ENTRY OF THE OFFSET TABLE, THE REGISTER THEN POINTS 4 BYTES BEFORE ;;THE REQUIRED OFFSET. THE SECOND 'ADD' THEREFORE ADDS THE OFFSET TO PC, ;;WHICH POINTS TO $I AT THE TIME OF PERFORMING THE ADDITION. THIS EFFECTS ;;THE TRANSFER OF CONTROL. ;; ;;THE 'PACKED' OPTION USES A TABLE OF BYTES, EACH CONTAINING THE OFFSET IN ;;WORDS FROM $I TO THE APPROPRIATE CODE. 'CASE' GENERATES DIFFERENT ;;BUT SIMILAR CODE TO HANDLE THE COMPRESSED OFFSETS, AND 'VALUE' HAS TO PATCH ;;BYTES RATHER THAN WORDS. ;; ;;VALUE RANGES ARE HANDLED BY PATCHING A SUCCESSION OF WORDS/BYTES ;;AFTER THE ONE WHICH WAS PATCHED IN RESPONSE TO THE LOW LIMIT ;;OF THE RANGE. $12 REMEMBERS EACH POSITIVE VALUE IN THE VALUE ;;LIST, SO THAT WHEN PROCESSING A NEGATIVE VALUE, 'VALUE' CAN SEE ;;WHAT THE LOW LIMIT OF THE RANGE WAS. $12 IS SET TO 77777 AFTER PROCESSING ;;A NEGATIVE VALUE, AND AT THE END OF THE LIST, TO DETECT TWO ;;SUCCESSIVE NEGATIVE VALUES OR A LEADING NEGATIVE VALUE. ;; ;;STACK DATA ;;---------- ;; ;;TOP WORD: ;; BIT 0 SET => 'PACKED' ;; BITS 11 TO 1 = SYMBOL NUMBER BASE, "I": ;; I = SYMBOL-NUMBER OF $I ;; I+1 = SYMBOL-NUMBER OF $J ;; I+2 = SYMBOL-NUMBER OF $K ;;NEXT WORD: ;; BITS 11 TO 0 = LIMIT OF VALID VALUES ;; ;;====================================================================== ;; .MACRO CASE R,L,P ;;BECAUSE 'CASE' AND 'VALUE' ARE VERY LARGE MACROS, AND FAIRLY ;;INFREQUENTLY-USED, 'CASE' IS A DUMMY WHICH JUST .MCALLS THE OTHERS, ;;AND THEN CALLS '$24' TO DO THE 'CASE' PROCESSING. .MCALL $24,VALUE,CASEND $24 ,,

.ENDM ;; ;;====================================================================== ;; .MACRO $24 R,L,P .IIF LE,L,.ERROR ;V .IIF GT,L-7777,.ERROR ;V ;;THE LIMIT VALUE MUST BE IN THE RANGE 1..7777 $93 ;;INSTRUCTION TO COMPARE VARIABLE WITH ITS LIMIT $5=$11*2 ;;BUILD UP THE TOP-OF-STACK ENTRY IN $5 .IF B,P ;; NOT 'PACKED' .IF LE,L-172 ;; THEN WE CAN BRANCH DIRECTLY ROUND THE CODE + OFFSET TABLE $93 .IFF ;; OTHERWISE WE BRANCH ROUND A JUMP $93 $93 .ENDC $93 ;; INSTRUCTION TO MULTIPLY THE VARIABLE BY TWO, TO ADDRESS THE OFFSET TABLE $93 ;; INSTRUCTION TO SET R POINTING 4 BYTES BEFORE THE REQUIRED OFFSET $93 ;; INSTRUCTION TO ADD THE OFFSET TO PC TO EFFECT THE TRANSFER $94 $,\$11,=. ;; GENERATE LABEL OF OFFSET TABLE $94 $6=$,\$11+1,-. ;; $6 = OFFSET TO UNSELECTED-VALUE CODE .REPT L+1 ;; GENERATE OFFSET TABLE $93 <.WORD $6> .ENDR .IFF ;; 'PACKED' OPTION .IIF DIF,

,,.ERROR ;U ;; AND YOU GOTTA SPELL IT RIGHT, SEE .IF LE,L-357 ;; SAME AS FOR NON-PACKED, EXCEPT BYTE OFFSETS ;; CHANGE THE NUMBERS SOMEWHAT $93 .IFF $93 $93 .ENDC $93 ;; INSTRUCTION TO SET R POINTING 14 BYTES BEFORE THE REQUIRED (OFFSET/2) $93 ;; INSTRUCTION TO GET THE (OFFSET/2) $93 ;; INSTRUCTION TO REMOVE THE NASTY SIGN-EXTENSION $93 ;; INSTRUCTION TO MULTIPLY BY TWO TO GET THE OFFSET IN BYTES $93 ;; INSTRUCTION TO ADD THE OFFSET TO PC TO EFFECT THE TRANSFER $94 $,\$11,=. $94 $6=$,\$11+1,-. .REPT L+1 $93 <.BYTE $6/2> .ENDR .EVEN $5=$5+1 ;; SET THE 'PACKED' FLAG .ENDC $94 $,\$11+1,=. ;;GENERATE THE DEFAULT UNSELECTED-VALUE DESTINATION. ;;THIS WILL BE CHANGED BY A 'VALUE' STATEMENT WITH NO LIST $90 ,0,\$0 ;;STACK THE LIMIT VALUE $90 $5,3,\$0 ;;STACK SYMBOL NUMBER BASE AND 'PACKED' FLAG $11=$11+3 ;;ADVANCE $11 - WE USE 3 SYMBOLS PER STRUCTURE .ENDM ;; ;;====================================================================== ;; .MACRO VALUE L $91 $5,3,\$0-1 ;;UNSTACK SYMBOL NUMBER BASE AND 'PACKED' FLAG $94 $6=$,\$5/2+2 ;;$6 = BOTTOM SYMBOL $93 ;;INSTRUCTION TO TRANSFER TO THE 'CASEND' .IF IDN,,<> ;; NO VALUE LIST $0=$0+1 ;; REPAIR THE STACK POINTER $94 $,\$5/2+1,=. ;; MOVE THE UNSELECTED-VALUE LABEL DOWN TO HERE .IFF ;; THERE IS A VALUE LIST $91 $7,0,\$0-1 ;; UNSTACK LIMIT VALUE TO $7 $0=$0+2 ;; REPAIR THE STACK POINTER $94 $6=.-$,\$5/2 ;; $6 = OFFSET FROM TOP OF OFFSET TABLE BACK TO HERE .IRP V, ;; LOOP THRU THE VALUE LIST .IF GE,V ;; POSITIVE VALUE - INDIVIDUAL ITEM, OR BOTTOM OF A RANGE .IIF GT,V-$7,.ERROR ;R ;; MUST NOT BE GREATER THAN LIMIT .IF EQ,$5&1 ;; NOT 'PACKED' $94 .=V*2+$,\$5/2 ;; '.' = OFFSET TABLE LOCATION FOR THIS VALUE $93 <.WORD $6> ;; PATCH IN THE OFFSET .IFF ;; 'PACKED' $94 .=V+$,\$5/2 $93 <.BYTE $6/2> ;; SIMILAR FOR 'PACKED' OFFSET TABLE .ENDC $12=V ;; REMEMBER THIS VALUE, IN CASE WE HAVE A RANGE .IFF ;; NEGATIVE VALUE - TOP OF A RANGE .IIF GT,--$7,.ERROR ;R ;; MAGNITUDE MUST BE NO BIGGER THAN LIMIT .IIF LE,--$12,.ERROR ;R ;; BUT MUST BE BIGGER THAN PREVIOUS ENTRY IN LIST .REPT --$12 ;; LOOP THRU RANGE VALUES ABOVE THE LOW ;; LIMIT OF THE RANGE, WHICH HAS ALREADY BEEN DONE .IF EQ,$5&1 ;; NOT 'PACKED' $93 <.WORD $6> ;; GENERATE ANOTHER WORD .IFF ;; 'PACKED' $93 <.BYTE $6/2> ;; GENERATE ANOTHER BYTE .ENDC .ENDR $12=77777 ;; RESET $12 TO AN UNBEATABLE VALUE .ENDC .ENDR $12=77777 ;; RESET $12 AGAIN, IN CASE THE LAST LIST ENTRY WAS POSITIVE $94 .=$6+$,\$5/2 ;; RESET '.' BACK TO WHERE THE 'VALUE' STATEMENT IS .ENDC .ENDM ;; ;;====================================================================== ;; .MACRO CASEND $91 $5,3,\$0-1 ;;POP THE SYMBOL NUMBER BASE $94 $,\$5/2+2,=. ;;GENERATE THE BOTTOM SYMBOL $0=$0-1 ;;KNOCK THE LIMIT OFF THE STACK .ENDM ;; ;;UTILITY MACROS ;;============== ;; ;; .MACRO $90 V,T,X ;;PUSHES A DATA VALUE ONTO THE STACK ;;'V' : VALUE TO BE PUSHED. MUST BE IN RANGE 0 TO 7777 ;;'T' : STACK ENTRY TYPE, IN THE RANGE 0 TO 7 ;;'X' : "\$0" - THIS SUPPLIES THE SYMBOL NUMBER OF THE TOP OF STACK $'X=V*10+T ;;SET STACK VARIABLE TO NEW VALUE $0=$0+1 ;;INCREMENT STACK POINTER .ENDM ;; ;;====================================================================== ;; .MACRO $91 V,T,X ;;POPS A VALUE FROM THE STACK ;;'V' : VARIABLE TO RECEIVE THE VALUE ;;'T' : REQUIRED ENTRY TYPE - ERROR N IF THE TYPE DOESN'T MATCH ;;'X' : "\$0-1" - THIS SUPPLIES THE SYMBOL NUMBER OF THE TOP OF STACK $0=$0-1 ;;DECREMENT THE STACK POINTER .IIF LT,$0-20,.ERROR ;N ;;STACK UNDERFLOW .IIF NE,$'X&7-T,.ERROR ;N ;;ENTRY TYPE NOT WHAT THE CALLER EXPECTED V=$'X/10 ;;RETURN THE VALUE .ENDM ;; ;;====================================================================== ;; .MACRO $92 D ;;INCREMENTS THE NUMBER OF THE NEXT AVAILABLE LOCAL LABEL. ;;'D' : IF NON-BLANK, THE NAME OF THE VARIABLE TO RECEIVE THE ;; VALUE OF $1 BEFORE IT'S INCREMENTED .IIF NB,D,D=$1 $1=$1+1 ;;SIMPLY INCREMENT $1. IF KEEN, WE COULD CHECK FOR ;;OVERFLOW (BUT THE ASSEMBLER DOES THAT FOR US), OR AVOID THE ;;RANGE FROM 64$ ON, WHERE OTHER MACROS AUTOMATICALLY GENERATE LOCAL ;;LABELS; HOWEVER IT IS UNKNOWN TO REACH 64$ IN PRACTICAL CODE. .ENDM ;; ;;====================================================================== ;; .MACRO $93 I,L ;;GENERATES AND PERHAPS LISTS AN INSTRUCTION. ;;'I' : INSTRUCTION TO BE GENERATED ;;'L' : IF NON-BLANK, THE LOCAL LABEL NUMBER (IN CHARS) OF THE DESTINATION ;; OF THIS INSTRUCTION; THIS CAUSES A "$" TO BE APPENDED TO ;; PRODUCE THE CORRECT LOCAL LABEL. .IIF NE,$10,.LIST MEB .IF B,L I .IFF I L'$ .ENDC .IIF NE,$10,.NLIST MEB .ENDM ;; ;;====================================================================== ;; .MACRO $94 L,M,R ;;GENERATES AND PERHAPS LISTS A LABEL OR DIRECT ASSIGNMENT STATEMENT ;;'L', 'M', 'R' : LEFT, MIDDLE AND RIGHT PARTS OF THE STATEMENT .IIF NE,$10,.LIST ME ;;PUSHED RIGHT OVER TO PRODUCE ONLY A BLANK LINE ON THE LISTING. L''M''R .IIF NE,$10,.NLIST ME .ENDM