;~W TACO`!ins MP/PRI=65./prm="ti:+TACO./nl/NI/NB/Y9" ;~W TACO`!ins MP/PRI=65./prm="ti:+TACO./nl/NI/NB/Y9/un" ;~!ins MP/prm="ti:+TACO./nl/ni" ;~!ins MP/prm="ti:+maclibcon/nl/ni/un" ;~!ins MP/prm="ti:=TACO111+maclibcon/ni/un" ; 1ST-- change to mc form: 5,$c-^-MC <- c-$->-3y ; change back: 5,$g;mc <;c/mc $;; ; find comments and fix: 5,$g/mc <;/c/mc <;/;/c/>$// ; This shortens up $macro lines but is not reversible ~5,$g/\$macro/c3/ /> ;/ ; This library supports the c calls to the Conroy's runtime system ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - ; currently defined symbols ; $temp$ set to maximum storage used by temps. ; $top$ set to relative zero of a file (for odt use) ; $auto$ counts local storage ; $auto. for local storage counting ; $type$ routine in main lib to type out a line to lun 5 ; $buf$ a 140. byte scratch buffer i main (for printf usage ) ; ; switch usage: ; 1-15 are internal of course ; 16 used to indicate a byte array in leta (transient use) ; 17-18 also temporary usage ; 19 optimize flag set for entire run ; 20 used to determine when to clear symbol table ; 21 also used, needed in case no auto statements ; 29 this suppresses the output from $$tim (when just debugging) ; ; ; Symbol table usage: ; ; type usage ; 1 auto variables, append (r5) arrays local ; 2 pointer or function parameter, append (r5) arrays = pointer ; 3 external to function, (not necessary global) for debugger ; 10-15 register r0-r5 equivalent (not yet implemented) ; ; ; ; string stack absolute usage ; ; 60 gets string %x (e.g. %2) to use when optimizing ; 59 gets psect name of last user .psect ; 58 gets time of compilation ; ; ; The stack is used as follows: ; ; If (stack 1) ; tos branch to on false ; nos go here one done (after elseif's etc) ; ; case (stack 2) ; tos break to label ; nos variable to test ; 3os skip over to next case test label ; 4os case or label ; ; Do while/forever (stack 2) ; tos break to ; nos jmp back to test or continue in loop label ; ; loop (stack 2) ; tos break to ; nos jmp back to test for more looping label ; 3os loop index ; 4os step amount ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - ; mov is now done internally for speed ;;; $MACRO MOV ;CHECK FOR MOV #0,X AND DO A CLR ;;; i%in -2.(r5) <#@1 #@2> <> ;;; I%IDN <#@1> #0 < clr #@2> < i%dout < mov #@1,#@2>> ;;; $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - ;;;$MACRO $$$$$$5 ;;;I%DOUT ;;;$ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO IF A = B ?? 19,17,18 ?- #@I ?- #@J BR. #@2 #@1 ; ; Note that the below causes right to left evaluation of ; relations. IF a = b and c = d or d = f ; is ; equiv to IF (a = b and (c =d and (d = f))) ; in a paren'd expression (not permitted of course) ; ?+ 16,,25 I%IDN OR,<#@4>,>> CMP. <#@{1}>,<#@{3}> B#@G #@J I%IDN OR,<#@4>,<#@H=.> I%IDN AND,<#@4>, >> $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO IFB A = B ?? 19,17,18 ?- #@I ?- #@J BR. #@2 #@1 ; ; Note that the below causes right to left evaluation of ; relations. IFB a = b and c = d or d = f ; is ; equiv to IFB (a = b and (c =d and (d = f))) ; in a paren'd expression (not permitted of course) ; ?+ 16,,25 I%IDN OR,#@4,> CMPB. #@{1},#@{3} B#@G #@J I%IDN OR,#@4,<#@H=.> I%IDN AND,#@4, > $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO O%R BR.TO #@2 BR #@1 ?+ 16 #@G=. ?+ $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO A%ND A = B ... #@2 ?? 15 BR #@F ?+ 16 #@G=. ?+ BR #@1 #@F=. $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO FI COMMENT ?+ 2 #@2=. ; #@1 ?+ 2 #@2=. $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO ELSE COMMENT ?? 6 ?+ 5 ?- #@6 JMP #@6 #@5=. ; #@1 $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO ELSEIF ... ;get nos ?+ 17,2 JMP #@H ?+ 15 #@F=. ?+ 16 IF <#@*(1"Z)> ?- #@H,2 $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO . just a short way to do functions C R0 = <#@*(1"Z)> $ENDM ; ------------------------------------------ ;specialized add and sub macros, they test for #1 and do increments ; note they only check parameter 2 (i.e. sub* a,b is backwards to ; what the sub machine code is (I can't remember why). ; at any rate, the Let statement knows this. ; they now also check for optimize setup ; $MACRO SUB* i%in -2.(r5) <#@1 #@2> <> I%IN <#@2> <#1,#1.> << DEC #@1> < DEC #@1>> < SUB #@2,#@1> $ENDM ; ------------------------------------------ $MACRO ADD* i%in -2.(r5) <#@1 #@2> <> I%IN <#@2> <#1,#1.> << INC #@1> < INC #@1>> < ADD #@2,#@1> $ENDM ; ------------------------------------------ $MACRO $" ?? 5,6 BR #@6 #@5=. .ASCIZ _#@1_ .EVEN ?- ##@5 #@6=. $ENDM ; ------------------------------------------ $MACRO $& ?- (SP)+ MOV ##@1,-(SP) ;push offset ADD R5,(SP) ;and compute address of #@1 $ENDM ; ------------------------------------------ $MACRO POP MOV (SP)+,#@{1} $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO PUSH S%SW 14 ?- #@{1} ?+ 1 I%DF <#@1> <(SP)+> < MOV #@1,-(SP)> S%SW -14 $ENDM ; ------------------------------------------ $MACRO call JSR PC,#@1 $ENDM ; ------------------------------------------ $MACRO LOOP FOR I = FROM TO "TO" ; watch out for which portions of the statement is lower case ; and the loop index must match in case with the next statement also. I%IN <#@8> <> <> > ?+ 12,,25 ?-- <#@C> ?? 10,11,13 ?-- #@2 ?-- #@A ?-- #@B ;Init loop index I%EXP <#@4> > #@A=. ; done loop? CMP. <#@{2}>,<#@{6}> ;I%IN <#@5> < > > I%IN <#@5> < > > ?+ 12,,25 B#@C #@D JMP #@B #@D=. $ENDM ; ------------------------------------------ ; New do macro, recurs with if(b) macro - needs lots of stack space. $MACRO DO WHILE(B) THIS IS THAT ; 1 2 3 4 ?? 16,17 ?-- #@G ; push the two labels such that the top is the place to break to ; and the next on stack is the loop back place ?-- #@H ; This is the loop back label #@G=. ; test the condition I%IDN <#@1> > I%IDN <#@1> > I%DF <#@1> FOREVER I%DF <#@1> FOREVER < JMP #@H ;else end while loop> I%DF <#@1> FOREVER $ENDM ; ------------------------------------------ $MACRO OD end of do loop (while or forever) ; Get next to tos (nos) ?++ 1,2 JMP #@1 ;Repeat loop ?++ 1 #@1=. ?++ $ENDM ; ------------------------------------------ $MACRO NEXT INDEX ?++ 2,4 I%R <#@2> ,<#@2>> ?++ 2,2 JMP #@2 ;back to top ?++ 2,1 ?++ ?++ #@2=. ?++ 2 I%DF <#@1> <#@2> > ?++ $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO N%EXT clr -(sp) I%EXP <#@2> > add (sp)+,#@{1} $ENDM ; ------------------------------------------ $MACRO BR. sets str 25 to inverse branch I%IN <#@1><= EQ NE LT GT GE LE CC CS><> I%IN <#@1><> $ENDM ; ------------------------------------------ $MACRO ! Simply sets str 25 to its first parm so the above fits on 2 lines. ?- <#@1>,,25 $ENDM ; ------------------------------------------ ; special case compare, checks for second arg being #0 and gens a test $MACRO CMPB. A,B I%NB <#@2>>< CMPB #@1,#@2>> $ENDM ; ------------------------------------------ ; 1 2 3 $MACRO SELECT case var of ... ;Make 2 labels ?? 1,3 ;Put no or indicator onto stack ?-- -nor- ?-- #@1 ?-- #@{2} ?-- #@3 $ENDM ; ------------------------------------------ ; 1 from stack $MACRO CASE var (label newlabel) ; ; Case construct is as follows: ; ; Multiple cases going to the same code is by using the OR parameter ; of the case statement. example: ; ; CASE 1 OR ; CASE 2 OR ; ... ; CASE N ; ; if an "or" ; if -nor- ; if label ; if not "or" ; if -nor- do nothing ; if label ; ; ; ; ?? 3,5 ;put string in 3os (3rd from top of stack) into parm-4 ?++ 4,3 #@4=. ;place new label into 3os ?-- #@3,3 ;get var into parm4 ?++ 4,2 CMP. #@4,#@{1}, BNE #@3 ;get -nor- or label if present into parm4 from 4os ?++ 4,4 S%SW -20 I%IDN <#@2> OR -nor- > ?-- #@5,4,,20 ?++ 4,4 I%IDN <#@2> OR < BR #@4> S%SW -20 I%DF <#@2> -nor- > I%SW 20 <#@4=.> ?-- -nor-,4,,20 $ENDM ; ------------------------------------------ ; 1 from stack $MACRO DEFAULT var (label newlabel) ?? 3 ;put string in 3os into parm-2 ?++ 2,3 #@2=. ;place new label into 3os ?-- #@3,3 ;get var into parm-2 ?++ 2,2 $ENDM ; ------------------------------------------ ; 1 from stack $MACRO CASEB var (label newlabel) ; ; Case construct is as follows: ; ; Multiple cases going to the same code is by using the OR parameter ; of the case statement. example: ; ; CASEB 1 OR ; CASEB 2 OR ; ... ; CASEB N ; ; if an "or" ; if -nor- ; if label ; if not "or" ; if -nor- do nothing ; if label ; ; ; ; ?? 3,5 ;put string in 3os (3rd from top of stack) into parm-4 ?++ 4,3 #@4=. ;place new label into 3os ?-- #@3,3 ;get var into parm4 ?++ 4,2 CMPB. #@4,#@{1}, BNE #@3 ;get -nor- or label if present into parm4 from 4os ?++ 4,4 S%SW -20 I%IDN <#@2> OR -nor- > ?-- #@5,4,,20 ?++ 4,4 I%IDN <#@2> OR < BR #@4> ;I%SW 20 S%SW -20 I%DF <#@2> -nor- > I%SW 20 <#@4=.> ?-- -nor-,4,,20 $ENDM ; ------------------------------------------ $MACRO ESAC VAR1 ?++ 2 ?++ 3 ?++ 4 ?++ I%NB <#@1> ,#@3,>> #@2=. #@4=. $ENDM ; ------------------------------------------ $MACRO BREAK ;get top string into parm-15 ?++ 15,1 I%NB <#@1> <#@1 <#@*(2"C)>> JMP #@F ;break I%NB <#@1> FI $ENDM ; ------------------------------------------ $MACRO PEEK ?+ 1,,#@1 [#@1] $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO C Call a c prog as: C var = name[abc] CL #@3 I%DF <#@1> < mov r0,#@1> $ENDM ;$MACRO C Call a c prog as: C var = name[abc] ;;i%idn <#@1> <:=> > ;;i%df <#@1> <:=> < mov r0,#@1>> ;$ENDM ; - - - - - $MACRO FPRINTF push r0 push r1 let r0 := sprintf[#$buf$,<#@*(1"Z)>] let r0 := put[#outr,#$buf$] pop r1 pop r0 $ENDM ; - - - - - $MACRO PRINTF mov r0,-(sp) mov r1,-(sp) C R0 = sprint[#$buf$,<#@*(1"Z)>] mov #$buf$,-(sp) jsr pc,$type$ mov (sp)+,r1 mov (sp)+,r0 $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Finally these are defined. They clobber r0 and/or r1 (mul uses r1 ; div uses both) ; BE careful with these. $MACRO MUL45 i%in -2.(r5) <#@1 #@2> <> I%IDN #@2 #-1. < neg #@1> < asl #@1>> $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO MUL%45 A * B A = A * B mov #@2,r1 mul #@1,r1 mov r1,#@1 $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO DIV45 A B A = A / B i%in -2.(r5) <#@1 #@2> <> mov #@1,r1 sxt r0 div #@2,r0 mov r0,#@1 $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - ; $MACRO FOR INIT-1 CONDITION-2 REINIT-3 ; This is a for loop like C or ratfor ; I%IN <#@2> <> <> > ?+ 2,,25 I%DIN <#@1> DO #@2 ?- <#@3> $ENDM ; - - - - - - - - - - - - - - - - - - - - - $MACRO ROF ; the ending statement in a for loop ?+ 1 I%DIN <#@1> OD $ENDM ; ------------------------------------------ $MACRO F%%D ?+ 10,1 #@1=#@A I%IN <#@2> <> << #@A=#@A+2>> < #@A=#@A+<#@2>> $ENDM ; ------------------------------------------ ; the following is called at file top with the date and time $MACRO $$TIM ?- $$$,,29 ?- <#@1 #@2>,,58 I%SW 29 <> < .ident /#@=1(1:2)#@=1(4:6)#@=1(9:9)/> I%SW 29 <> > $ENDM ; ------------------------------------------ $MACRO LETA 1 = 3 + 5 i%idn <#@=1(1:1)> # ?+ 20 let r0 = <#@K#@=1(2:Z)> mov r1,-(sp) clr -(sp) ;I%IDN <#@1> <#@3> > ;I%IDN <#@1> <#@3> > ;I%DF <#@1> <#@3> > LET (sp) = <#@*(3"Z)> let%a #@1 i%sw 16 < movb (sp)+,@(sp)+> $ENDM ; ------------------------------------------ $MACRO LET%A I%B <#@3> $ENDM ; ------------------------------------------ $MACRO ZERO i%nb <#@2> > clr #@{1} $ENDM ; ------------------------------------------ $MACRO MOVE LET <#@2> = <#@1> $ENDM ; ------------------------------------------ $MACRO optimize using rx ; here we undefine all registers except r2 ; so if user trys using r2 we will force some error. ; at least a taskbuild undefined. ; then we use %2 ourselves instead of -2.(r5) code ; this is a post optomise and only add* mul45 div45 sub* and mov ; check for these. .dsabl reg r0=%0 r1=%1 i%idn r2 <#@2> i%idn r3 <#@2> i%idn r4 <#@2> r5=%5 sp=%6 pc=%7 s%sw 19 $ENDM ; ------------------------------------------ $MACRO DMPSTR ?- <-----1-----> ?-- <-----2-----> ?+ ?++ ** $%D 1 2 3 4 5 6 7 8 9 ** $%D 10 11 12 13 14 15 16 17 18 19 ** $%D 20 21 22 23 24 25 26 27 28 29 ** $%D2 30 31 32 33 34 35 36 37 38 39 ** $%D2 40 41 42 43 44 45 46 47 48 49 ** $%D2 50 51 52 53 54 55 56 57 58 59 60 ?- <> ?-- <> ?+ ?++ $ENDM ; ------------------------------------------ ; $MACRO $%D ?+ 2,,#@1 I%NB <#@2> $ENDM ; ; ------------------------------------------ $MACRO $%D2 ?++ 2,,#@1 I%NB <#@2> $ENDM ; ; ------------------------------------------ $MACRO DMPSW ** S%%W 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ** S%%W 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 $ENDM ; ; ------------------------------------------ $MACRO S%%W I%SW <#@1> $ENDM ; ; ------------------------------------------ $MACRO DUMP nums= (0=#@#0)(1=#@#1)(2=#@#2)(3=#@#3)(4=#@#4)(5=#@#5)(6=#@#6)(7=#@#7)(8=#@#8)(9=#@#9) S%SW -9 DMPSW DMPSTR I%IN <#@1> < > $ENDM ; ; ------------------------------------------ $MACRO POKE STACK STRING ?- <#@2>,,#@1 $ENDM ;------------------------------------------------------------------------ $MACRO SETLAB LAB ;This allows one to set the label used for generating labels ?- #@1,,29 $ENDM ; ------------------------------------------ $MACRO .END ; The following trap the .end statement and verify all constructs ; have been terminated. It checks the current level of the stack ; by pushing .end and verifying that they are in position 1 of ; both stacks. ?- .END ?-- .END ?+ 5,,1 ?+ 6,,31 I%DF <#@5#@6> <.END.END> > ?+ ?++ $temp$=#@#1. I%DOUT <.END #@1> $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO STRUCT name ?- #@1 #@1=0 $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO END-STRUCT ?+ 2 I%NB <#@1> >> $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO FIELD name1,name2... ** F%%D <#@*(1"N)> $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO MEMBER name1,name2... ** F%%D <#@*(1"N)> $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO BEGIN name I%DF <#@2>
?- <#@1> ; ; allow for a name here. This is only here ; to check mismatched begin/ends ; $ENDM ; ------------------------------------------ $MACRO BEGIN$$ ?? 1,3 BR #@1 ?+ 2 ?- <#@3> #@2: JMP #@3 #@1: $ENDM ; ------------------------------------------ $MACRO END ?+ 2 I%NB <#@1> <#@2> >> $ENDM ; ------------------------------------------ $MACRO PROGRAM NAME s%sw -2 s%sw 21 ; set switch 20, auto will clear symbol table and clear 20. func sets it s%sw 20 ; The following symbol will here be set to 0 since it is not ; yet defined. However, on the second pass of the assembler, it ; will be defined so this initialization only occurs on pass 1. ; The .end statement will define it to the max temps used so ; on pass2 it will be that value and not zero. No storage is ; allocated using this symbol (no static assembler storage). It ; is used at run time to decr the stack when allocating temps and ; locals. .iif ndf $temp$ $temp$=0 ; This counter will be used to track temp usage. We will allways ; allocate at least the following. S%N 1 = -4 $top$=. S%SW 15 $auto$=$temp$ .enabl lc I%DOUT <; Mp version as of: 28-jan-81> I%NB <#@1> I%NB <#@1> < .title #@1> $ENDM ; ------------------------------------------ $MACRO ELSEIFB ... ;get nos ?+ 17,2 JMP #@H ?+ 15 #@F=. ?+ 16 IFB #@*(1_Z) ?- #@H,2 $ENDM ; ------------------------------------------ $MACRO $NOP $ENDM ; ------------------------------------------ ; Function sets up offsets according to how the Conroy save and restore ; routines allocate storage off the stack ; it also allocates storage for locals. Then it clears ; the local (auto) storage counter for the next function later on. ; ; Usage of C function compatible routines ; ; program lab |used once ; |------------ ; auto l1 l2 l3 ... | Function 1 ;FUNCTION entry[p1,p2 ...] | ; ... | code is here ; ret [value] | ; | ; |------------- ; auto l1 l2 l3 ... | Function 2 ;FUNCTION entry2[p1,p2 ...] | ; ... | code is here ; ret [value] | ; |------------- ; ; ; All variables are referenced as xxx(r5) ; and are call by value as in C. ; ; $MACRO FUNCTION A[B,C,D] IS LOCAL i%sw 10 s%sw 20 i%sw 21 s%sw 21 S%N 2 = 8 ; trace will cause the function name and argument values to be printed ; on entry. The top of the file (for odt use) is also output. The odt ; option will cause an iot trap to odt. ; trace is switch 17, (x7) odt entry is 18 (x8) I%IDN <#@3> LOCAL I%SW 17 I%SW 18 S%SW -18 $ENDM ; ------------------------------------------ $MACRO T%% ?? 19,18,17 br #@I #@J=. .ascii '#@1:%6o top=%6o' ** T%%1 <#@*(2"N)> .byte 0 .even #@I=. PRINTF ##@J ##@H,#$top$ #@*(2,Z) #@H=. $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO T%%1 .ascii ' #@1=%o' $ENDM ; ------------------------------------------ $MACRO F%UNC A,B,C,D... s%n 9 = 0 ** #@*(2,Z) ; num 9 now contains # args in this function ; .word #@#9 ;number of arguments i%sw 2 i%sw 2 i%sw 2 i%sw 2 i%sw 2 i%sw 2 ** E%%S <#@*(3"Z)> I%SW 2 #@2#@1 i%sw 2 < jsr r0,$$dsav> < jsr r0,$$csav> ; get label pointing to function record if debugger on i%sw 2 i%sw 2 < .word #@1> add #$auto$,sp $auto.=$auto$ $auto$=$temp$ $ENDM ; ------------------------------------------ ; func used to be the only macro (i.e. no Function) ; some older programs specify this macro instead - so it remains. ; it also is the only way to have a function without the name being ; declared global. ;$MACRO FUNC P1 P2 P3... Use Conroys runtime here. ; pass each argument separately to e%%s ;** E%%S <#@*(1"Z)> ; ;note that $auto$ is negative, thus we ADD to sub from stack ; save current $auto$ in $auto. for the return ; but re-init $auto$ in case there is no return statement ; note: we don't need to pop off stack storage on return since ; the frame pointer - r5 - has enough info to do it. But we ; didn't know this at first, so we still fuss with these labels. ; jsr r0,$$csav ;get stack frame ; add #$auto$,sp ;allocate space on stack for autos ; $auto.=$auto$ ; $auto$=$temp$ ;re-init ;$ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO E%%S S%N 2 = V2 + 2 #@1=#@#2. E%S #@1 2 $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO RET This version will allow any kind of expression I%NB <#@1> > < mov #@{1},r0>> I%SW 17 ; sub #$auto.,sp ;de-allocate locals (no longer necessary) i%sw 2 < jmp $$dret> < jmp $$cret> $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO R%ET clr -(sp) LET (sp) = <#@*(1"N)> mov (sp)+,r0 $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Auto is used to generate offsets which are applied to labels and ; compute how much local storage is needed to allocate from the stack ; ; Usage: AUTO a,b,c... if [n] not specified, then its 2 ; AUTO a[n],b[n],c,d... if odd values are supplied, user ; must do the allignment ; The Program statement must appear first (at least once in the program) ; it initializes $auto$. Multiple Autos are permitted. The auto's must ; be followed by a Func statement which allocates (and must be the entry) ; storage. After it allocates storage it also re-initializes $auto$ ; so a subsuquent function can re use it properly. Note that variables ; defined in this manner can be reused locally in another function with ; diffenent offsets, but nuthing is going to detect using a variable ; defined locally to another function which is intended to be redefined ; and is inadvertantly left out of a Auto statement ; $MACRO AUTO var1 var2 ... s%sw -21 ; This statement may be the first auto in a function. So we ; check and clear the symbol table if true. Function sets flag for next time I%SW 20 S%SW -20 ** AUTO% <#@*(1"N)> $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO AUTO% var [size] (size defaults to 2) I%IN <#@2> <> <> ?+ 2,,28 $auto$=$auto$-<#@2> i%idn <#@=1(1:1)> * <#@=1(2:Z)= $auto$> <#@1= $auto$> I%IDN <#@=1(1:1)> * 2> 1> $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO REGISTER var1 var2 ... s%sw -21 I%SW 20 S%SW -20 I%NB <#@1> <** <> <#@1=R4>> I%NB <#@2> <** <> <#@2=R3>> I%NB <#@3> <** <> <#@3=R2>> $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - ; This captures all psect statements so we can save the last one used. $MACRO .PSECT ?- <#@1>,,59 I%DOUT < .PSECT #@*(1,Z)> $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO D%BUG LAB NAME LAB LAB LAB... ?? 1,5,6,7,8 i%dout < .psect $$db1> #@8: ; push start of this function record ?- #@8 .word #@1,0 ;fwd and bck ptrs .word #@2 ;entry point .blkw 4 ;call count and instr cnt .word #@#9.-1 ;n parms .word #@5+2,#@6,#@7 ;ptext,ptype,pval .asciz '#@=2(1:6)' ;name of fun s%len <#@=2(1:6)> 9 ?+ 9,,58 s%n v9 = 7 - v9 .blkb #@#9. .asciz '#@=9(1:F)' ;tim of comp .even ; ; now dump symbol table and types ; ?- 1 #@5: d%sym .byte 0,0 .even ?- 2,1 #@6: d%sym .word 0 ?- 3,1 #@7: d%sym .word 0 .even ; ; clean up stack and output label so we can link these ; with all other psects containing these function debug records ; ?+ #@1: ; ; symbol table out, restore original psect (str 59 has it) ; ?+ 1,,59 i%dout < .psect #@1> $ENDM $MACRO $$$$$$4 ?+ 3,1 I%IDN <#@3> 1 < .word #@1. ;n syms> $ENDM $MACRO $$$$$$5 ?+ 3,1 ; ; first time thru we output symbol text ; second time types ; third time values ; top of stack contains 1,2,3 so we know i%idn <#@3> 1 < .asciz '#@1'> i%idn <#@3> 2 < .word #@2.> i%idn <#@3> 3 < .word #@1> $ENDM $MACRO $$$$$$6 $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO EXTERN s%sw -21 I%SW 20 S%SW -20 ** E%XTN <#@*(1"Z)> $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - $MACRO E%XTN E%S #@1 3 $ENDM ; - - - - - - - - - - - - - - - - - - - - - - - - - - - ; LST--