See also:
Nick Says:
As is, you only get 40 forward labels per assembly. But that could be increased with a bit of cut and paste..Conditionals are much like yours var GE var/val GT ..No need for distinguishing constants in the comparison operations
I also added:
if flag ZZ flag NZ flag CC flag NCthat generates snz, snc, sz, sc tests
and
if Reg WRegEQ Reg WRegNEthat just does a csne / cse generation
and
if var IsZero var IsNotZerogenerates a test \var construct
Note the first parameter isn't looked at in the above three constructs. The string "flag" and "Reg" could be anything. I do this because vars can be specified as Offset(DP) or Offset(SP) and the macro processor will puke if is asked to examine a parameter with a parenthesis in it! So if you tried to test for "w" or "Wreg" in the first parameter, the macro would break when you used it with "temp(DP)". The substitution works ok though so I just always use the comparison literal for making the conditional format choice.
The LOOP construct was done before I figured out the labels so it doesn't use the same method as the While, Repeat, IF, For .. Since the IP is so efficient with the Stack loading and usage, the LOOP construct is very useful.
Notice that my Until works with the Repeat. The While ends with endwhile. I didn't need to use "doif" as "if" isn't recognized as a keyword.
I've been thinking about how to do more complex conditionals. Haven't got the answer yet. How about you?? How would you implement something that allowed piecewise compounded AND's & OR's. Obviously AND's can be nested IF's but I suspect we could come with some kind of macros that could be sequenced to provide more complex conditionals. But I need to learn how to start using the darn things.
Love the IP part. Damn expensive development kit but the part is choice. Documentation is poor -- but who am I to complain. Support has not understood a couple of my Bug reports and just blew me off! But the bleeding edge is always this way...
Love your site. An amazing warehouse of very valuable information!
Thank you, Sir Newton.
Nick
; ; ; Macro idle ; .macro idle cyc .set temp,\cyc .if temp==11 nop nop jmp .+2 jmp .+2 jmp .+2 .set temp,0 .endif .if temp==10 nop jmp .+2 jmp .+2 jmp .+2 .set temp,0 .endif .if temp==9 jmp .+2 jmp .+2 jmp .+2 .set temp,0 .endif .if temp == 4 nop jmp .+2 .set temp,0 .endif .if temp == 5 nop nop jmp .+2 .set temp,0 .endif .if temp==6 jmp .+2 jmp .+2 .set temp,0 .endif .if temp == 7 nop jmp .+2 jmp .+2 .set temp,0 .endif .set fours,temp / 4 .set left,(temp && 0b11) .if left== 1 nop .endif .if left == 2 nop nop .endif .if left == 3 jmp .+2 .endif .if left == 4 nop jmp .+2 .endif .if fours push #fours decsz 1(SP) jmp .-1 inc SPL .endif .endm .macro stc ; Set Carry setb STATUS,C .endm .macro clc ; Clear Carry clrb STATUS,C .endm .macro cwje val,label csne w,\val jmp \label .endm .macro cwjne val,label cse w,\val jmp \label .endm .macro cje var,val,label mov w,\var csne w,\val jmp \label .endm .macro cjne var,val,label mov w,\var cse w,\val jmp \label .endm .macro cjb var,val,label mov w,\val cmp w,\var ;sub sc jmp \label .endm .macro cjbe var,val,label mov w,\var cmp w,\val ;sub var-val snc jmp \label .endm .macro cja var,val,label mov w,\var cmp w,\val sc jmp \label .endm .macro cjae var,val,label mov w,\val cmp w,\var snc jmp \label .endm .macro movSP dst,src push \src pop \dst .endm .macro subw dst,src mov w,\src sub \dst,w .endm .macro djnz var,label decsz \var jmp \label .endm .macro djz var,label decsnz \var jmp \label .endm .macro ijnz var,label incsz \var jmp \label .endm .macro ijz var,label incsnz \var jmp \label .endm .macro csae var,val mov w,\val cmp w,\var sc .endm .macro jb var,bit,label snb \var,\bit jmp \label .endm .macro jnb var,bit,label sb \var,\bit jmp \label .endm .macro DisableInt clrb XCFG,7 .endm .macro EnableInt setb XCFG,7 .endm .macro loadDP addr loadh \addr loadl \addr .endm .macro loadIP addr push #%lo8data(\addr) pop IPL push #%hi8data(\addr) pop IPH .endm .macro loadPRAMaddr addr clr ADDRX inc ADDRX mov w,#%hi8inst(\addr) mov ADDRH,w mov w,#%lo8inst(\addr) mov ADDRL .endm .macro pushPRAMaddr addr push #%lo8data(\addr) push #%hi8data(\addr) .endm .macro push16BitCnt cnt push #(\cnt >> 8) push #(\cnt & 0xFF) .endm .macro loop cnt push \cnt .ifndef loopcnt .set loopcnt,0 .endif .set loopcnt,loopcnt+1 .if loopcnt==1 .set retaddr1,. .endif .if loopcnt==2 .set retaddr2,. .endif .if loopcnt==3 .set retaddr3,. .endif .endm .macro endloop .if loopcnt==1 djnz 1(SP),.-(.-retaddr1) .endif .if loopcnt==2 djnz 1(SP),.-(.-retaddr2) .endif .if loopcnt==3 djnz 1(SP),.-(.-retaddr3) .endif inc SPL ;release temp counter... .set loopcnt,loopcnt-1 .endm ; ; Structured Programming Macros ; if ifelse else endif ; while endwhile ; repeat until ; for var, init, last endfor ; ; Derived from James Newton's Macros at SXLIST.COM ; .set IsZero, 1 .set IsNotZero, 2 .set EQ, 3 .set NE, 4 .set LT, 5 .set GE, 6 .set LE, 7 .set GT, 8 .set WRegEQ, 9 .set WRegNE, 10 .set ZZ, 11 .set NZ, 12 .set CC, 13 .set NC, 14 .set tst,0 .macro Reverse .set ntst,0 .if (tst==GT) .set ntst,LE .elseif (tst==LE) .set ntst,GT .elseif (tst==GE) .set ntst,LT .elseif (tst==LT) .set ntst,GE .elseif (tst==EQ) .set ntst,NE .elseif (tst==NE) .set ntst,EQ .elseif (tst==WRegEQ) .set ntst,WRegNE .elseif (tst==WRegNE) .set ntst,WRegEQ .elseif (tst==ZZ) .set ntst,NZ .elseif (tst==NZ) .set ntst,ZZ .elseif (tst==CC) .set ntst,NC .elseif (tst==NC) .set ntst,CC .elseif (tst==IsZero) .set ntst,IsNotZero .elseif (tst==IsNotZero) .set ntst,IsZero .endif .set tst,ntst .endm .macro Condition var,val .if (tst==EQ) mov w,\var csne w,\val .elseif (tst==NE) mov w,\var cse w,\val .elseif (tst==LT) mov w,\val cmp w,\var ;sub sc .elseif (tst==LE) mov w,\var cmp w,\val ;sub var-val snc .elseif (tst==GT) mov w,\var cmp w,\val sc .elseif (tst==GE) mov w,\val cmp w,\var snc .elseif (tst==WRegEQ) csne w,\val .elseif (tst==WRegNE) cse w,\val .elseif (tst==ZZ) snz .elseif (tst==NZ) sz .elseif (tst==CC) snc .elseif (tst==NC) sc .elseif (tst==IsZero) test \var snz .elseif (tst==IsNotZero) test \var sz .endif .endm doifadr = 0 doendifadr = 0 doifl = 0 .set Label7,0 .set Label6,0 .set Label5,0 .set Label4,0 .set Label3,0 .set Label2,0 .set Label1,1 .set LabelCnt,0 .macro PushLabel .set Label7,Label6 .set Label6,Label5 .set Label5,Label4 .set Label4,Label3 .set Label3,Label2 .set Label2,Label1 .ENDM .MACRO PopLabel .set Label1,Label2 .set Label2,Label3 .set Label3,Label4 .set Label4,Label5 .set Label5,Label6 .set Label6,Label7 .set Label7,99 .ENDM .macro PlantLabel .if (Label1 == 1) do1: .elseif (Label1 == 2) do2: .elseif (Label1 == 3) do3: .elseif (Label1 == 4) do4: .elseif (Label1 == 5) do5: .elseif (Label1 == 6) do6: .elseif (Label1 == 7) do7: .elseif (Label1 == 8) do8: .elseif (Label1 == 9) do9: .elseif (Label1 == 10) do10: .elseif (Label1 == 11) do11: .elseif (Label1 == 12) do12: .elseif (Label1 == 13) do13: .elseif (Label1 == 14) do14: .elseif (Label1 == 15) do15: .elseif (Label1 == 16) do16: .elseif (Label1 == 17) do17: .elseif (Label1 == 18) do18: .elseif (Label1 == 19) do19: .elseif (Label1 == 20) do20: .elseif (Label1 == 21) do21: .elseif (Label1 == 22) do22: .elseif (Label1 == 23) do23: .elseif (Label1 == 24) do24: .elseif (Label1 == 25) do25: .elseif (Label1 == 26) do26: .elseif (Label1 == 27) do27: .elseif (Label1 == 28) do28: .elseif (Label1 == 29) do29: .elseif (Label1 == 30) do30: .elseif (Label1 == 31) do31: .elseif (Label1 == 32) do32: .elseif (Label1 == 33) do33: .elseif (Label1 == 34) do34: .elseif (Label1 == 35) do35: .elseif (Label1 == 36) do36: .elseif (Label1 == 37) do37: .elseif (Label1 == 38) do38: .elseif (Label1 == 39) do39: .elseif (Label1 == 40) do40: .endif .endm .macro NewLabel .set LabelCnt,LabelCnt+1 .set Label1,LabelCnt .if (LabelCnt>39) .err 99 .endif .endm .macro PlantJmp .if (Label1 == 1) jmp do1 .elseif (Label1 == 2) jmp do2 .elseif (Label1 == 3) jmp do3 .elseif (Label1 == 4) jmp do4 .elseif (Label1 == 5) jmp do5 .elseif (Label1 == 6) jmp do6 .elseif (Label1 == 7) jmp do7 .elseif (Label1 == 8) jmp do8 .elseif (Label1 == 9) jmp do9 .elseif (Label1 == 10) jmp do10 .elseif (Label1 == 11) jmp do11 .elseif (Label1 == 12) jmp do12 .elseif (Label1 == 13) jmp do13 .elseif (Label1 == 14) jmp do14 .elseif (Label1 == 15) jmp do15 .elseif (Label1 == 16) jmp do16 .elseif (Label1 == 17) jmp do17 .elseif (Label1 == 18) jmp do18 .elseif (Label1 == 19) jmp do19 .elseif (Label1 == 20) jmp do20 .elseif (Label1 == 21) jmp do21 .elseif (Label1 == 22) jmp do22 .elseif (Label1 == 23) jmp do23 .elseif (Label1 == 24) jmp do24 .elseif (Label1 == 25) jmp do25 .elseif (Label1 == 26) jmp do26 .elseif (Label1 == 27) jmp do27 .elseif (Label1 == 28) jmp do28 .elseif (Label1 == 29) jmp do29 .elseif (Label1 == 30) jmp do30 .elseif (Label1 == 31) jmp do31 .elseif (Label1 == 32) jmp do32 .elseif (Label1 == 33) jmp do33 .elseif (Label1 == 34) jmp do34 .elseif (Label1 == 35) jmp do35 .elseif (Label1 == 36) jmp do36 .elseif (Label1 == 37) jmp do37 .elseif (Label1 == 38) jmp do38 .elseif (Label1 == 39) jmp do39 .elseif (Label1 == 40) jmp do40 .endif .endm .MACRO Repeat Label1 = . PushLabel .ENDM .MACRO Until var,cond,val .set tst,\cond Reverse Condition \var,\val PopLabel jmp .-(.-Label1) .ENDM .MACRO while p1,p2,p3 .set tst,\p2 .set Label1,. PushLabel ;Save Numeric Address of While Start reverse condition \p1,\p3 NewLabel ;Make a Label for endwhile PushLabel PlantJmp .ENDM .MACRO endwhile PopLabel ;Get Label for Beyond endwhile .set SaveLabel,Label1 PopLabel ;Get Address of WhileStart jmp .-(.-Label1) ;Jmp Back to numeric address .set Label1,SaveLabel PlantLabel ;Label for Beyond endwhile .endm .MACRO if p1,p2,p3 .set tst,\p2 doifl = doifl + 1 .IF (doifl > 4) .err 23;'Only 4 levels of nested conditions supported by doif macro' .ENDIF Reverse Condition \p1,\p3 NewLabel ;Get Label for Cond NotTrue PushLabel PlantJmp NewLabel ;Get Label for EndIf PushLabel .ENDM .MACRO Else .IF (doifl < 1) .err 24;'DoElse outside of DoIf/DoEndIf block' .ENDIF PopLabel ;Get Label for Endif .set SaveLabel,Label1 PlantJmp ;Plant Jmp to Endif PopLabel ;Get Label for Prior Cond NotTure PlantLabel .set Label1,SaveLabel PushLabel ;Again save the Label for EndIf .ENDM .MACRO ElseIf p1,p2,p3 .set tst,\p2 .IF (doifl < 1) .err 25;'DoElseIf outside of DoIf/DoEndIf block' .ENDIF PopLabel ;Get Label for Endif .set SaveLabel,Label1 PlantJmp ;Plant Jmp to Endif PopLabel ;Get Label for Prior Cond NotTure PlantLabel Reverse Condition \p1,\p3 NewLabel PlantJmp ;Plant Jmp to ElseIF, Else or Endif PushLabel .set Label1,SaveLabel PushLabel ;Again Save Label of Endif .ENDM .MACRO EndIf .IF (doifl < 1) .err 26;'DoEndIf outside of DoIf/DoEndIf block' .ENDIF doifl = doifl - 1 PopLabel ;Get Label of EndIf PlantLabel popLabel PlantLabel .ENDM .MACRO for var, startcnt, endcnt push \startcnt-1 pop \var .set SaveLabel,. inc \var .set tst,GT Condition \var,\endcnt NewLabel ;Make Label for beyond EndFor PushLabel PlantJmp .set Label1,SaveLabel PushLabel ;save start loc .endm .macro endfor PopLabel jmp .-(.-Label1) PopLabel PlantLabel .endm