;.............................................................................. ; ; StyleWare Macros` ; ; Macros...: AddWord, AddLong, SubWord, SubLong ; Author...: Mike Hibbetts, (2.0 conversion Scott Lindsey) ; Date.....: June 30, 1987 ... Oct 22,1988 ; Version..: 2.0 ; ; The following is a short description of the available addressing ; modes that may be used with the math macros in m16.math. ; ; Notes: 'a', 'x', and 'y' denote the 65816 registers. ; 's' denotes that an operand is to be either pulled or pushed. ; ; For programmer based optimization, it should be noted that all zero ; page indirect indexing is done out of the 'y' register, and all other ; indexing is done out of the 'x' register. So, for example, ; ; AddLong Addr:#4,[zp]:#4,>Long ; is better coded as ; ldy #4 ; AddLong Addr:y,[zp]:y,>Long, ; (it saves on 1 'ldx') ; and ; ; SubLong Addr1:#offset1,>Long:#offset2,Addr3 ; is better coded as ; ldy #offset2 ; SubLong Addr1:#offset1,>Long:y,Addr3. ; (it saves on 3 'ldx' and costs 1 'ldy') ; ; All other optimizations have been done internally to the macros. ;............................................................................. ; ; Where ; ; P = { Addr, Addr:#offset, Addr:offset, Addr:x, Addr:y, ; [zp], [zp]:#offset, [zp]:offset, [zp]:y, zp:s ; Long, Long:#offset, Long:offset, Long:x, s }, ; ; Q = { a, x, y, #const } + P, ; ; R = { #const } + P, and ; ; T = { a, x, y } + P, ; ; all ; ; AddWord Q,R,T ; AddLong Q,R,P ; SubWord Q,R,T ; SubLong Q,R,P ; ; are allowed. ; ;----------------------------------------------------------------------------- MACRO &lab AddWord &term1,&term2,&dest &lab ; Arith 2,adc,clc,&term1,&term2,&dest MEND MACRO &lab Addw &term1,&term2,&dest &lab AddWord &term1,&term2,&dest MEND ;---------------------------------------------------------------------------- MACRO &lab AddLong &term1,&term2,&dest &lab ; Arith 4,adc,clc,&term1,&term2,&dest MEND MACRO &lab AddL &term1,&term2,&dest &lab AddLong &term1,&term2,&dest MEND ;---------------------------------------------------------------------------- MACRO &lab SubWord &term1,&term2,&dest &lab ; Arith 2,sbc,sec,&term1,&term2,&dest MEND MACRO &lab Subw &term1,&term2,&dest &lab SubWord &term1,&term2,&dest MEND ;---------------------------------------------------------------------------- MACRO &lab SubLong &term1,&term2,&dest &lab ; Arith 4,sbc,sec,&term1,&term2,&dest MEND MACRO &lab Subl &term1,&term2,&dest &lab SubLong &term1,&term2,&dest MEND ;---------------------------------------------------------------------------- MACRO Arith &length,&op1,&op2,&term1,&term2,&dest gbla &same gbla &Yinc gblc &lastX gblc &lastY gbla &OFFinc gblc &pushed &same SETA 0 &OFFinc SETA 0 &Yinc SETA 0 &pushed SETC '' &lastX SETC '' &lastY SETC '' lcla &colon lcla &stack1 lcla &pull1 lcla &pull2 lcla &zp1 lcla &zp2 lcla &zp3 lclc &addr1 lclc &off1 lclc &addr2 lclc &off2 lclc &addr3 lclc &off3 lclc &badreg &badreg SETC 'y' lclc &jump1 lclc &jump2 lclc &jump3 IF &substr(&term1,1,1)­'[' GOTO .doterm12 &zp1 seta 1 .doterm12 &colon seta &pos(':',&term1) IF &colon=0 GOTO .no1offset &off1 SETC &substr(&term1,&colon+1,&len(&term1)-&colon) &addr1 SETC &substr(&term1,1,&colon-1) GOTO .doterm21 .no1offset &addr1 SETC &term1 .doterm21 IF &substr(&term2,1,1)­'[' GOTO .doterm22 &zp2 seta 1 .doterm22 &colon seta &pos(':',&term2) IF &colon=0 GOTO .no2offset &off2 SETC &substr(&term2,&colon+1,&len(&term2)-&colon) &addr2 SETC &substr(&term2,1,&colon-1) GOTO .dodest1 .no2offset &addr2 SETC &term2 .dodest1 IF &substr(&dest,1,1)­'[' GOTO .dodest2 &zp3 seta 1 &badreg SETC 'x' .dodest2 &colon seta &pos(':',&dest) IF &colon=0 GOTO .no3offset &off3 SETC &substr(&dest,&colon+1,&len(&dest)-&colon) &addr3 SETC &substr(&dest,1,&colon-1) IF &off3­'y' GOTO .start &badreg SETC 'x' GOTO .start .no3offset &addr3 SETC &dest IF &addr3­'y' GOTO .start &badreg SETC 'x' .start IF &zp1 GOTO .loadzp1 IF &len(&off1) GOTO .withoff11 IF &addr1='a' GOTO .loadR1 IF &addr1='x' GOTO .loadx1 IF &addr1='y' GOTO .loady1 IF &addr1='s' GOTO .loads1 .; Changed 5/16/89 ÑÑMSL IF (&substr(&addr1,1,1) = '#') THEN lda #<&substr(&addr1,2,&len(&addr1)-1) ELSE lda &addr1 ENDIF .; &jump1 SETC '.load2' GOTO .loaded1 ; ----------------- .loadx1 txa GOTO .loadR1 .loady1 tya .loadR1 &jump1 SETC '.loadR2' GOTO .loaded1 ; ----------------- .loads1 IF &off2='s' GOTO .loads12 IF &off3='s' GOTO .loads12 IF &length='2' GOTO .loads11 &stack1 seta 1 .loads11 pla &jump1 SETC '.loads2' GOTO .loaded1 ; ----------------- .loads12 lda 1,s &jump1 SETC '.loads22' &pull1 seta 1 GOTO .loaded1 ; ----------------- .loadzp1 IF &len(&off1) GOTO .loadzpo1 lda &addr1 &jump1 SETC '.loadzp2' GOTO .loaded1 ; ----------------- .loadzpo1 IF &off1='y' GOTO .loadzpy1 &jump1 SETC '.loadzpo2' IF (&off2­'y') and (&off3­'y') GOTO .loadzpo12 phy &pushed SETC 'y' &jump1 SETC '.loadzpo22' .loadzpo12 ldy &off1 lda &addr1,y &lastY SETC &off1 GOTO .loaded1 ; ------------------ .loadzpy1 lda &addr1,&off1 &jump1 SETC '.loadzpy2' GOTO .loaded1 ; ------------------ .withoff11 IF &off1='x' GOTO .loffx1 IF &off1='y' GOTO .loffy1 IF &off1='s' GOTO .loffs1 &jump1 SETC '.loadoff2' IF (&off2­'x') and (&off3­'x') GOTO .withoff112 phx &pushed SETC 'x' &jump1 SETC '.loadoff22' .withoff112 ldx &off1 lda &addr1,x &lastX SETC &off1 GOTO .loaded1 ; ----------------- .loffx1 lda &addr1,x &jump1 SETC '.loffx2' GOTO .loaded1 ; ------------------- .loffy1 lda &addr1,y &jump1 SETC '.loffy2' GOTO .loaded1 ; ------------------- .loffs1 lda &addr1,s &jump1 SETC '.loffs2' .loaded1 &op2 IF &zp2 GOTO .addzp1 IF &len(&off2) GOTO .withoff12 IF &addr2='s' GOTO .adds11 IF &substr(&addr2,1,1)='#' THEN &op1 #<&substr(&addr2,2,&len(&addr2)-1) ELSE &op1 &addr2 ENDIF &jump2 SETC '.add2' GOTO .added1 ; ----------------- .adds11 STreset &pull2 seta 1 IF &pull1 GOTO .adds12 IF &stack1 GOTO .adds13 &op1 1,s &jump2 SETC '.adds21' GOTO .added1 ; ----------------- .adds12 &op1 1+&length,s &jump2 SETC '.adds22' GOTO .added1 ; ----------------- .adds13 &op1 3,s &jump2 SETC '.adds21' GOTO .added1 ; ----------------- .addzp1 IF &len(&off2) GOTO .addzpo1 &op1 &addr2 &jump2 SETC '.addzp2' GOTO .added1 ; ----------------- .addzpo1 IF &off2='y' GOTO .addzpy1 IF &len(&pushed) GOTO .addzpo12 IF &off3='y' GOTO .addzpo11 IF (&off1­'y') or (&length='2') GOTO .addzpo12 .addzpo11 phy &pushed SETC 'y' .addzpo12 DoLoad 1,y,&off2 &op1 &addr2,y &jump2 SETC '.addzpo2' GOTO .added1 ; ------------------ .addzpy1 IF &pushed­'y' GOTO .loadzpy12 ply &pushed SETC '' &lastY SETC '' .loadzpy12 &op1 &addr2,&off2 &jump2 SETC '.addzpy2' GOTO .added1 ; ------------------ .withoff12 IF &off2='x' GOTO .aoffx1 IF &off2='y' GOTO .aoffy1 IF &off2='s' GOTO .aoffs1 IF &len(&pushed) GOTO .withoff122 IF &off3='x' GOTO .withoff121 IF (&off1­'x') or (&length='2') GOTO .withoff122 .withoff121 phx &pushed SETC 'x' .withoff122 DoLoad 1,x,&off2 &op1 &addr2,x &jump2 SETC '.addoff2' GOTO .added1 ; ----------------- .aoffx1 IF &pushed­'x' GOTO .aoffx12 plx &pushed SETC '' &lastX SETC '' .aoffx12 &op1 &addr2,x &jump2 SETC '.aoffx2' GOTO .added1 ; ------------------- .aoffy1 IF &pushed­'y' GOTO .aoffy12 ply &pushed SETC '' &lastY SETC '' .aoffy12 &op1 &addr2,y &jump2 SETC '.aoffy2' GOTO .added1 ; ------------------- .aoffs1 STreset &op1 &addr2,s &jump2 SETC '.aoffs2' .added1 IF &zp3 GOTO .storezp1 IF &len(&off3) GOTO .withoff13 IF &addr3='a' GOTO .storeR1 IF &addr3='x' GOTO .storex1 IF &addr3='y' GOTO .storey1 IF &addr3='s' GOTO .stores1 sta &addr3 &jump3 SETC '.store2' GOTO .stored1 ; ------------------ .storex1 tax GOTO .storeR1 .storey1 tay .storeR1 &jump3 SETC '.error1' GOTO .stored1 ; ------------------ .stores1 STreset IF &pull1 or &pull2 GOTO .stores12 IF &stack1 GOTO .stores13 IF &length='2' GOTO .stores111 pha .stores111 pha &jump3 SETC '.stores2' GOTO .stored1 ; ----------------- .stores12 IF &stack1 GOTO .stores14 sta 1,s &jump3 SETC '.stores2' &pull1 seta 0 &pull2 seta 0 GOTO .stored1 ; ----------------- .stores13 pha &jump1 SETC '.loads22' &jump3 SETC '.stores2' GOTO .stored1 ; ----------------- .stores14 sta 3,s &jump3 SETC '.stores2' &pull1 seta 0 &pull2 seta 0 GOTO .stored1 ; ------------------ .storezp1 IF &len(&off3) GOTO .storezpo1 sta &addr3 &jump3 SETC '.storezp2' GOTO .stored1 ; ----------------- .storezpo1 IF &off3='y' GOTO .storezpy1 IF &len(&pushed) or (&length='2') GOTO .storezpo12 IF (&off1­'y') and (&off2­'y') GOTO .storezpo12 phy &pushed SETC 'y' .storezpo12 DOLoad 1,y,&off3 sta &addr3,y &jump3 SETC '.storezpo2' GOTO .stored1 ; ------------------ .storezpy1 IF &pushed­'y' GOTO .storezpy12 ply &pushed SETC '' &lastY SETC '' .storezpy12 sta &addr3,&off3 &jump3 SETC '.storezpy2' GOTO .stored1 ; ------------------ .withoff13 IF &off3='x' GOTO .soffx1 IF &off3='y' GOTO .soffy1 IF &off3='s' GOTO .soffs1 IF &len(&pushed) or (&length='2') GOTO .withoff132 IF (&off1­'x') and (&off2­'x') GOTO .withoff132 phx &pushed SETC 'x' .withoff132 DoLoad 1,x,&off3 sta &addr3,x &jump3 SETC '.storeoff2' GOTO .stored1 ; ----------------- .soffx1 IF &pushed­'x' GOTO .soffx12 plx &pushed SETC '' &lastX SETC '' .soffx12 sta &addr3,x &jump3 SETC '.soffx2' GOTO .stored1 ; ------------------- .soffy1 IF &pushed­'y' GOTO .soffy12 ply &pushed SETC '' &lastY SETC '' .soffy12 sta &addr3,y &jump3 SETC '.soffy2' GOTO .stored1 ; ------------------- .soffs1 STreset sta &addr3,s &jump3 SETC '.soffs2' .stored1 IF &length='2' GOTO .stored2 GOTO &jump1 ;-------------------------------------------------------------- .load2 HighByte lda,&addr1 GOTO .loaded2 ; ----------------- .loadR2 lda #0 GOTO .loaded2 ; ----------------- .loads2 STreset pla GOTO .loaded2 ; ----------------- .loads22 STreset lda 3,s GOTO .loaded2 ; ----------------- .loadzp2 IF &len(&pushed) GOTO .loadzp22 IF (&off2­'y') and (&off3­'y') GOTO .loadzp22 phy &pushed SETC 'y' .loadzp22 DoLoad 1,y,#2 lda &addr1,y GOTO .loaded2 ; ----------------- .loadzpo22 IF &len(&pushed) GOTO .loadzpo2 phy &pushed SETC 'y' .loadzpo2 DoLoad 2,y,&off1 lda &addr1,y GOTO .loaded2 ; ------------------ .loadzpy2 IF &pushed­'y' GOTO .loadzpy21 ply &pushed SETC '' &lastY SETC '' .loadzpy21 doY lda &addr1,&off1 GOTO .loaded2 ; ------------------ .loadoff22 IF &len(&pushed) GOTO .loadoff2 phx &pushed SETC 'x' .loadoff2 DoLoad 1,x,&off1 lda &addr1+2,x GOTO .loaded2 ; ----------------- .loffx2 IF &pushed­'x' GOTO .loffx21 plx &pushed SETC '' &lastX SETC '' .loffx21 lda &addr1+2,x GOTO .loaded2 ; ------------------- .loffy2 IF &pushed­'y' GOTO .loffy21 ply &pushed SETC '' &lastY SETC '' .loffy21 IF &Yinc GOTO .loffy22 lda &addr1+2,y GOTO .loaded2 ; ------------------- .loffy22 lda &addr1,y GOTO .loaded2 ; ------------------- .loffs2 STreset lda &addr1+2,s .loaded2 GOTO &jump2 ;------------------------------ ;------------------------------ .add2 HighByte &op1,&addr2 GOTO .added2 ; ----------------- .adds21 STreset &op1 3,s GOTO .added2 ; ----------------- .adds22 &op1 3+&length,s GOTO .added2 ; ----------------- .addzp2 IF &len(&pushed) or (&off3­'y') GOTO .addzp22 phy &pushed SETC 'y' .addzp22 DoLoad 1,y,#2 &op1 &addr2,y GOTO .added2 ; ----------------- .addzpo2 IF &len(&pushed) or (&off3­'y') GOTO .addzpo22 phy &pushed SETC 'y' .addzpo22 DoLoad 2,y,&off2 &op1 &addr2,y GOTO .added2 ; ------------------ .addzpy2 IF &pushed­'y' GOTO .addzpy22 ply &pushed SETC '' &lastY SETC '' .addzpy22 doY &op1 &addr2,&off2 GOTO .added2 ; ------------------ .addoff2 IF &len(&pushed) or (&off3­'x') GOTO .addoff22 phx &pushed SETC 'x' .addoff22 DoLoad 1,x,&off2 &op1 &addr2+2,x GOTO .added2 ; ----------------- .aoffx2 IF &pushed­'x' GOTO .aoffx22 plx &pushed SETC '' &lastX SETC '' .aoffx22 &op1 &addr2+2,x GOTO .added2 ; ------------------- .aoffy2 IF &pushed­'y' GOTO .aoffy22 ply &pushed SETC '' &lastY SETC '' .aoffy22 IF &Yinc GOTO .aoffy23 &op1 &addr2+2,y GOTO .added2 ; ------------------- .aoffy23 &op1 &addr2,y GOTO .added2 ; ------------------- .aoffs2 STreset &op1 &addr2+2,s .added2 GOTO &jump3 ;------------------------------ ;------------------------------ .error1 MNOTE 'Register cannot hold long integer.',4 GOTO .stored2 ; ------------------ .store2 HighByte sta,&addr3 GOTO .stored2 ; ------------------ .stores2 STreset sta 3,s GOTO .stored2 ; ----------------- .storezp2 DoLoad 1,y,#2 sta &addr3,y GOTO .stored2 ; ----------------- .storezpo2 DoLoad 2,y,&off3 sta &addr3,y GOTO .stored2 ; ------------------ .storezpy2 IF &pushed­'y' GOTO .storezpy22 ply &pushed SETC '' &lastY SETC '' .storezpy22 doY sta &addr3,&off3 GOTO .stored2 ; ------------------ .storeoff2 DoLoad 1,x,&off3 sta &addr3+2,x GOTO .stored2 ; ----------------- .soffx2 IF &pushed­'x' GOTO .soffx22 plx &pushed SETC '' &lastX SETC '' .soffx22 sta &addr3+2,x GOTO .stored2 ; ------------------- .soffy2 IF &pushed­'y' GOTO .soffy22 ply &pushed SETC '' &lastY SETC '' .soffy22 IF &Yinc GOTO .soffy23 sta &addr3+2,y GOTO .stored2 ; ------------------- .soffy23 sta &addr3,y GOTO .stored2 ; ------------------- .soffs2 STreset sta &addr3+2,s .stored2 IF &pull1=0 GOTO .stored210 IF &length='2' GOTO .stored205 pl&badreg .stored205 pl&badreg .stored210 IF &pull2=0 GOTO .stored220 IF &length='2' GOTO .stored215 pl&badreg .stored215 pl&badreg .stored220 MEND ;------------------------------------------------------------------------------ MACRO HighByte &oper,&loc lclc &c lclc &rest IF &substr(&loc,1,1)='#' GOTO .b &oper &loc+2 MEXIT .b &rest SETC &substr(&loc,2,&len(&loc)-1) &oper #^&rest MEND ;-------------------------------------------------------- MACRO DoLoad &half,®,&value gbla &same gbla &OFFinc IF &half='1' GOTO .c IF &substr(&value,1,1)='#' GOTO .a Check ®,&value IF &same GOTO .e ld® &value in® in® &OFFinc seta 1 MEXIT .e IF &OFFinc GOTO .done in® in® &OFFinc seta 1 MEXIT .a Check ®,&value+2 IF &same GOTO .done ld® &value+2 &OFFinc seta 1 MEXIT .c Check ®,&value IF &same GOTO .done ld® &value .done MEND ;----------------------------------------------------- MACRO doY GBLA &Yinc IF &Yinc GOTO .done &Yinc seta 1 iny iny .done MEND ;------------------------------------------------- MACRO STreset GBLC &pushed GBLC &lastX IF &len(&pushed)=0 GOTO .done IF &pushed='y' GOTO .d plx &pushed SETC '' &lastX SETC '' MEXIT .d ply &pushed SETC '' &lastY SETC '' .done MEND ;------------------------------------------------- MACRO Check ®,&string gbla &same gblc &lastX gblc &lastY lcla &search IF ®='y' GOTO .regy IF &len(&lastx)­&len(&string) GOTO .nomatchx &search seta &pos(&string,&lastx) IF &search=0 GOTO .nomatchx GOTO .match .regy IF &len(&lastY)­&len(&string) GOTO .nomatchy &search seta &pos(&string,&lasty) IF &search=0 GOTO .nomatchy .match &same seta 1 MEXIT .nomatchx &same seta 0 &lastX SETC &string MEXIT .nomatchy &same seta 0 &lastY SETC &string MEND ;------------------------------------------------------ ;............................................................... ; ; Addwl - add word quickly to long word in place ;............................................................... MACRO &lab addwl &a1,&a2 &lab ; IF (&a1='a' or &a1='A') GOTO .a lda &a1 .a clc adc &a2 sta &a2 bcc ~b&sysindex inc &a2+2 ~b&sysindex ; mend ;............................................................... ; ; Subwl - sub word quickly to long word in place ;............................................................... MACRO &lab subwl &a1,&a2 &lab ; IF (&a1='a' or &a1='A') GOTO .a lda &a2 .a sec sbc &a1 sta &a2 bcs ~b&sysindex dec &a2+2 ~b&sysindex ; mend ;------------------------------------------------------ MACRO &label Addwls &arg1,&arg2 &label AddWord &arg1,&arg2,a ldx &arg2+2 bcc ~b&sysindex inx ~b&sysindex phx pha MEND ;------------------------------------------------------ MACRO Mul2 ¶m lclc &op if &nbr(&syslist)=0 then &op setc 'a' else &op setc ¶m endif asl &op MEND ;----------------------- MACRO Mul4 ¶m lclc &op if &nbr(&syslist)=0 then &op setc 'a' else &op setc ¶m endif asl &op asl &op MEND ;----------------------- MACRO Mul8 ¶m lclc &op if &nbr(&syslist)=0 then &op setc 'a' else &op setc ¶m endif asl &op asl &op asl &op MEND ;----------------------- MACRO Mul16 ¶m lclc &op if &nbr(&syslist)=0 then &op setc 'a' else &op setc ¶m endif asl &op asl &op asl &op asl &op MEND ;----------------------- MACRO Mul32 ¶m lclc &op if &nbr(&syslist)=0 then &op setc 'a' else &op setc ¶m endif asl &op asl &op asl &op asl &op asl &op MEND ;----------------------- MACRO Div2 ¶m lclc &op if &nbr(&syslist)=0 then &op setc 'a' else &op setc ¶m endif lsr &op MEND ;----------------------- MACRO Div4 ¶m lclc &op if &nbr(&syslist)=0 then &op setc 'a' else &op setc ¶m endif lsr &op lsr &op MEND ;----------------------- MACRO Div8 ¶m lclc &op if &nbr(&syslist)=0 then &op setc 'a' else &op setc ¶m endif lsr &op lsr &op lsr &op MEND ;----------------------- MACRO Div16 ¶m lclc &op if &nbr(&syslist)=0 then &op setc 'a' else &op setc ¶m endif lsr &op lsr &op lsr &op lsr &op MEND ;----------------------- MACRO Div32 ¶m lclc &op if &nbr(&syslist)=0 then &op setc 'a' else &op setc ¶m endif lsr &op lsr &op lsr &op lsr &op lsr &op MEND ;----------------------- MACRO Inc4 ¶m lclc &op if &nbr(&syslist)=0 then &op setc 'a' else &op setc ¶m endif inc &op inc &op inc &op inc &op MEND ;----------------------- MACRO Dec4 ¶m lclc &op if &nbr(&syslist)=0 then &op setc 'a' else &op setc ¶m endif dec &op dec &op dec &op dec &op MEND ;----------------------- MACRO &lab sdiv4 &op moveword &op,a bmi ~b&sysindex lsr a lsr a bra ~c&sysindex ~b&sysindex sec ror a sec ror a ~c&sysindex moveword a,&op MEND ;------------------------------------------------------ ;------------------------------------------------------ ; XOR - renaming for eor ;------------------------------------------------------ MACRO &lab xor &op &lab eor &op MEND