#include #include //#define FIXED_IMPLEMENTATION 0 //#define FIXED_IMPLEMENTATION 1 //#define FIXED_IMPLEMENTATION 2 #define FIXED_IMPLEMENTATION 3 #if FIXED_IMPLEMENTATION==0 int fixed_mul(int x_i,int x_f, int y_i,int y_f, int *z_i,int *z_f, int debug) { short a,b; int c; a=((x_i)<<8)+(x_f); b=((y_i)<<8)+(y_f); c=a*b; if (debug) { printf("%x:%x (%d) * %x:%x (%d) = %x (%d)\n", x_i,x_f,a, y_i,y_f,b, c,c); } c>>=8; *z_i=(c>>8); *z_f=(c&0xff); return a*b; } #endif #if FIXED_IMPLEMENTATION==1 int fixed_mul(int x_i,int x_f, int y_i, int y_f, int *z_i, int *z_f, int debug) { int num1h,num1l; int num2h,num2l; int result3; int result2,result1,result0; int aa,xx,cc=0,cc2,yy; int negate=0; num1h=x_i; num1l=x_f; if (!(num1h&0x80)) goto check_num2; // bpl check_num2 negate++; // inc negate num1l=~num1l; num1h=~num1h; num1l&=0xff; num1h&=0xff; num1l+=1; cc=!!(num1l&0x100); num1h+=cc; num1l&=0xff; num1h&=0xff; check_num2: num2h=y_i; num2l=y_f; if (!(num2h&0x80)) goto unsigned_multiply; negate++; num2l=~num2l; num2h=~num2h; num2l&=0xff; num2h&=0xff; num2l+=1; cc=!!(num2l&0x100); num2h+=cc; num2l&=0xff; num2h&=0xff; unsigned_multiply: if (debug) { printf("Using %02x:%02x * %02x:%02x\n",num1h,num1l,num2h,num2l); } result0=0; result1=0; //label_multiply: aa=0; // lda #0 (sz) result2=aa; // sta result+2 xx=16; // ldx #16 (sz) label_l1: cc=(num2h&1); //lsr NUM2+1 (szc) num2h>>=1; num2h&=0x7f; // if (num2_neg) { // num2h|=0x80; // } cc2=(num2l&1); // ror NUM2 (szc) num2l>>=1; num2l&=0x7f; num2l|=(cc<<7); cc=cc2; if (cc==0) goto label_l2; // bcc L2 yy=aa; // tay (sz) cc=0; // clc aa=num1l; // lda NUM1 (sz) aa=aa+cc+result2; // adc RESULT+2 (svzc) cc=!!(aa&0x100); aa&=0xff; result2=aa; // sta RESULT+2 aa=yy; // tya aa=aa+cc+num1h; // adc NUM1+1 cc=!!(aa&0x100); aa=aa&0xff; label_l2: cc2=aa&1; aa=aa>>1; aa&=0x7f; aa|=cc<<7; cc=cc2; // ror A cc2=result2&1; result2=result2>>1; result2&=0x7f; result2|=(cc<<7); cc=cc2; // ror result+2 cc2=result1&1; result1=result1>>1; result1&=0x7f; result1|=cc<<7; cc=cc2; // ror result+1 cc2=result0&1; result0=result0>>1; result0&=0x7f; result0|=cc<<7; cc=cc2; // ror result+0 xx--; // dex if (xx!=0) goto label_l1; // bne L1 result3=aa&0xff; // sta result+3 if (debug) { printf("RAW RESULT = %02x:%02x:%02x:%02x\n", result3&0xff,result2&0xff,result1&0xff,result0&0xff); } if (negate&1) { // printf("NEGATING!\n"); cc=0; aa=0; aa-=result0+cc; cc=!!(aa&0x100); result0=aa; aa=0; aa-=result1+cc; cc=!!(aa&0x100); result1=aa; aa=0; aa-=result2+cc; cc=!!(aa&0x100); result2=aa; aa=0; aa-=result3+cc; cc=!!(aa&0x100); result3=aa; } *z_i=result2&0xff; *z_f=result1&0xff; result3&=0xff; result2&=0xff; result1&=0xff; result0&=0xff; if (debug) { printf("%02x:%02x * %02x:%02x = %02x:%02x:%02x:%02x\n", num1h,num1l,y_i,y_f, result3&0xff,result2&0xff,result1&0xff,result0&0xff); // printf("%02x%02x * %02x%02x = %02x%02x%02x%02x\n", // num1h,num1l,y_i,y_f, // result3,result2,result1,result0); } int a2; // int s1,s2; // s1=(num1h<<8)|(num1l); // s2=(y_i<<8)|(y_f); a2=(result3<<24)|(result2<<16)|(result1<<8)|result0; // printf("%d * %d = %d (0x%x)\n",s1,s2,a2,a2); return a2; } #endif #if FIXED_IMPLEMENTATION==2 // Description: Unsigned 16-bit multiplication with unsigned 32-bit result. // Input: 16-bit unsigned value in T1 // 16-bit unsigned value in T2 // Carry=0: Re-use T1 from previous multiplication (faster) // Carry=1: Set T1 (slower) // // Output: 32-bit unsigned value in PRODUCT // Clobbered: PRODUCT, X, A, C // Allocation setup: T1,T2 and PRODUCT preferably on Zero-page. // square1_lo, square1_hi, square2_lo, square2_hi must be // page aligned. Each table are 512 bytes. Total 2kb. // // Table generation: I:0..511 // square1_lo = <((I*I)/4) // square1_hi = >((I*I)/4) // square2_lo = <(((I-255)*(I-255))/4) // square2_hi = >(((I-255)*(I-255))/4) static unsigned char square1_lo[512]; static unsigned char square1_hi[512]; static unsigned char square2_lo[512]; static unsigned char square2_hi[512]; static int table_ready=0; static void init_table(void) { int i; for(i=0;i<512;i++) { square1_lo[i]=((i*i)/4)&0xff; square1_hi[i]=(((i*i)/4)>>8)&0xff; square2_lo[i]=( ((i-255)*(i-255))/4)&0xff; square2_hi[i]=(( ((i-255)*(i-255))/4)>>8)&0xff; // printf("%d %x:%x %x:%x\n",i,square1_hi[i],square1_lo[i], // square2_hi[i],square2_lo[i]); } table_ready=1; // 3 * 2 // 3+2 = 5 // 3-2 = 1 // (25 - 1) = 24/4 = 6 // int num1l,num2l,a1,a2; // num1l=7; // num2l=9; // printf("Trying %d*%d\n",num1l,num2l); // a1=square1_lo[num1l+num2l]; // printf("((%d+%d)^2)/4: %d\n",num1l,num2l,a1); // a2=square2_lo[((~num1l)&0xff)+num2l]; // printf("((%d-%d)^2)/4: %d\n",num1l,num2l,a2); // printf("%d*%d=%d\n",num1l,num2l,a1-a2); } static unsigned int product[4]; int fixed_mul_unsigned(int x_i,int x_f, int y_i, int y_f, int *z_i, int *z_f, int debug) { // T2 = BBbb // >T1 * T1 * >T2 = DDdd // // AAaa // BBbb // CCcc // + DDdd // ---------- // PRODUCT! // ; Setup T1 if changed int c=0; int a,x; int sm1a,sm3a,sm5a,sm7a; int sm2a,sm4a,sm6a,sm8a; int sm1b,sm3b,sm5b,sm7b; int sm2b,sm4b,sm6b,sm8b; int _AA,_BB,_CC,_DD,_aa,_bb,_cc,_dd; if (!table_ready) init_table(); // printf("\t\t\tMultiplying %2x:%2x * %2x:%2x\n",x_i,x_f,y_i,y_f); /* Set up self-modifying code */ if (c==0) { a=(x_f)&0xff; // lda T1+0 ; 3 sm1a=a; // sta sm1a+1 ; 3 sm3a=a; // sta sm3a+1 ; 3 sm5a=a; // sta sm5a+1 ; 3 sm7a=a; // sta sm7a+1 ; 3 a=(~a)&0xff; // eor #$ff ; 2 sm2a=a; // sta sm2a+1 ; 3 sm4a=a; // sta sm4a+1 ; 3 sm6a=a; // sta sm6a+1 ; 3 sm8a=a; // sta sm8a+1 ; 3 a=(x_i)&0xff; // lda T1+1 ; 3 sm1b=a; // sta sm1b+1 ; 3 sm3b=a; // sta sm3b+1 ; 3 sm5b=a; // sta sm5b+1 ; 3 sm7b=a; // sta sm7b+1 ; 3 a=(~a)&0xff; // eor #$ff ; 2 sm2b=a; // sta sm2b+1 ; 3 sm4b=a; // sta sm4b+1 ; 3 sm6b=a; // sta sm6b+1 ; 3 sm8b=a; // sta sm8b+1 ; 3 } /* Perform T1_hi * T2 = BBbb */ x=(y_i)&0xff; // ldx T2+1 ; 3 c=1; // sec ; 2 //sm5a: a=square1_lo[sm5a+x]; // lda square1_lo,x ; 4 //sm6a: a+=(~(square2_lo[sm6a+x]))+c; // sbc square2_lo,x ; 4 c=!(a&0x100); a&=0xff; _bb=a; // sta _bb+1 ; 3 // printf("\t\t\t\tbb=%x c=%d\n",_bb,c); //sm7a: a=square1_hi[sm7a+x]; // lda square1_hi,x ; 4 //sm8a: a+=(~(square2_hi[sm8a+x]))+c; // sbc square2_hi,x ; 4 c=!(a&0x100); a&=0xff; _BB=a; // sta _BB+1 /* Perform >T1 * >T2 = DDdd */ c=1; // sec ; 2 //sm5b: a=square1_lo[sm5b+x]; // lda square1_lo,x ; 4 //sm6b: a+=(~(square2_lo[sm6b+x]))+c; // sbc square2_lo,x ; 4 c=!(a&0x100); a&=0xff; _dd=a; // sta _dd+1 ; 3 //sm7b: a=square1_hi[sm7b+x]; // lda square1_hi,x ; 4 //sm8b: a+=(~(square2_hi[sm8b+x]))+c; // sbc square2_hi,x ; 4 c=!(a&0x100); a&=0xff; product[3]=a; // sta PRODUCT+3 ; 3 _DD=a; /*********************************************/ /* Add the separate multiplications together */ /*********************************************/ // product[0]=_aa; if (debug) printf("product[0]=0.%02x\n",_aa); // product[1]=_AA+_bb+(_cc) if (debug) printf("product[1]=%02x+%02x+0=",_AA,_bb); c=0; // clc ; 2 //_AA: a=_AA; // lda #0 ; 2 //_bb: a+=(c+_bb); // adc #0 ; 2 c=!!(a&0x100); a&=0xff; product[1]=a; // sta PRODUCT+1 ; 3 if (debug) printf("%x.%02x\n",c,a); // product[2]=_BB+_CC+c if (debug) printf("product[2]=%02x+%02x+%d=",_BB,_CC,c); //_BB: a=_BB; // lda #0 ; 2 //_CC: a+=(c+_CC); // adc #0 ; 2 c=!!(a&0x100); a&=0xff; product[2]=a; // sta PRODUCT+2 ; 3 if (debug) printf("%x.%02x\n",c,a); // product[3]=_DD+c if (debug) printf("product[3]=%02x+%d=",_DD,c); if (c==0) goto urgh2; // bcc :+ ; 2nt/3 product[3]++; // inc PRODUCT+3 ; 5 product[3]&=0xff; c=0; // clc ; 2 urgh2: if (debug) printf("%x.%02x\n",c,product[3]); // product[1]=_AA+_bb+_cc if (debug) printf("product[1]=%02x+%02x+%d=",product[1],_cc,c); //_cc: a=_cc; // lda #0 ; 2 a+=c+product[1]; // adc PRODUCT+1 ; 3 c=!!(a&0x100); a&=0xff; product[1]=a; // sta PRODUCT+1 ; 3 if (debug) printf("%x.%02x\n",c,product[1]); // product[2]=_BB+_CC+_dd+c if (debug) printf("product[2]=%02x+%02x+%d=",product[2],_dd,c); //_dd: a=_dd; // lda #0 ; 2 a+=c+product[2]; // adc PRODUCT+2 ; 3 c=!!(a&0x100); a&=0xff; product[2]=a; // sta PRODUCT+2 ; 3 if (debug) printf("%x.%02x\n",c,product[2]); // product[3]=_DD+c if (debug) printf("product[3]=%02x+%d=",product[3],c); if (c==0) goto urgh; // bcc :+ ; 2nt/3 product[3]++; // inc PRODUCT+3 ; 5 product[3]&=0xff; urgh: if (debug) printf("%x.%02x\n",c,product[3]); *z_i=product[1]; *z_f=product[0]; // printf("Result=%02x:%02x\n",*z_i,*z_f); if (debug) { printf(" AAaa %02x:%02x\n",_AA,_aa); printf(" BBbb %02x:%02x\n",_BB,_bb); printf(" CCcc %02x:%02x\n",_CC,_cc); printf("DDdd %02x:%02x\n",_DD,_dd); } return (product[3]<<24)|(product[2]<<16)|(product[1]<<8)|product[0]; // rts ; 6 } /* signed */ int fixed_mul(int x_i,int x_f, int y_i, int y_f, int *z_i, int *z_f, int debug) { int a,c; fixed_mul_unsigned(x_i,x_f,y_i,y_f,z_i,z_f,debug); // jsr multiply_16bit_unsigned ; 6 a=(x_i&0xff); // lda T1+1 ; 3 if ((a&0x80)==0) goto x_positive; // bpl :+ ; 3/2nt if (debug) printf("Before: %02x:%02x:%02x:%02x\n",product[3],product[2],product[1],product[0]); // a=0xff; // lda #$ff ; 2 // c=1; // sec ; 2 // a=product[0]^a; // eor product[0]; 3 // a&=0xff; // a+=0+c; // adc #0 ; 2 // c=!!(a&0x100); // a&=0xff; // product[0]=a; // sta product[0]; 3 // a=0xff; // lda #$ff ; 2 // a=product[1]^a; // eor product[0]; 3 // a&=0xff; // a+=0+c; // adc #0 ; 2 // c=!!(a&0x100); // a&=0xff; // product[1]=a; // sta product[0]; 3 // a=0xff; // a=product[2]^a; // eor product[0]; 3 // a&=0xff; // a+=0+c; // adc #0 ; 2 // c=!!(a&0x100); // a&=0xff; // product[2]=a; // sta product[0]; 3 // a=0xff; // a=product[3]^a; // eor product[0]; 3 // a&=0xff; // a+=0+c; // adc #0 ; 2 // c=!!(a&0x100); // a&=0xff; // product[3]=a; // sta product[0]; 3 // product[1]^=a; // product[2]^=a; // product[3]^=a; c=1; // sec ; 2 a=product[2]; // lda PRODUCT+2 ; 3 a+=(~y_f)+c; // sbc T2+0 ; 3 c=!(a&0x100); a&=0xff; product[2]=a; // sta PRODUCT+2 ; 3 a=product[3]; // lda PRODUCT+3 ; 3 a+=(~y_i)+c; // sbc T2+1 ; 3 c=!(a&0x100); a&=0xff; product[3]=a; // sta PRODUCT+3 ; 3 if (debug) printf("After: %02x:%02x:%02x:%02x\n",product[3],product[2],product[1],product[0]); x_positive: a=(y_i&0xff); // lda T2+1 ; 3 if ((a&0x80)==0) goto y_positive; // bpl :+ ; 3/2nt if (debug) printf("Before: %02x:%02x:%02x:%02x\n",product[3],product[2],product[1],product[0]); // a=0xff; // lda #$ff ; 2 // c=1; // sec ; 2 // a=product[0]^a; // eor product[0]; 3 // a&=0xff; // a+=0+c; // adc #0 ; 2 // c=!!(a&0x100); // a&=0xff; // product[0]=a; // sta product[0]; 3 // a=0xff; // lda #$ff ; 2 // a=product[1]^a; // eor product[0]; 3 // a&=0xff; // a+=0+c; // adc #0 ; 2 // c=!!(a&0x100); // a&=0xff; // product[1]=a; // sta product[0]; 3 // a=0xff; // a=product[2]^a; // eor product[0]; 3 // a&=0xff; // a+=0+c; // adc #0 ; 2 // c=!!(a&0x100); // a&=0xff; // product[2]=a; // sta product[0]; 3 // a=0xff; // a=product[3]^a; // eor product[0]; 3 // a&=0xff; // a+=0+c; // adc #0 ; 2 // c=!!(a&0x100); // a&=0xff; // product[3]=a; // sta product[0]; 3 c=1; // sec ; 2 a=product[2]; // lda PRODUCT+2 ; 3 a+=(~x_f)+c; // sbc T1+0 ; 3 c=!(a&0x100); a&=0xff; product[2]=a; // sta PRODUCT+2 ; 3 a=product[3]; // lda PRODUCT+3 ; 3 a+=(~x_i)+c; // sbc T1+1 ; 3 c=!(a&0x100); a&=0xff; product[3]=a; // sta PRODUCT+3 ; 3 if (debug) printf("After: %02x:%02x:%02x:%02x\n",product[3],product[2],product[1],product[0]); y_positive: *z_i=product[2]; *z_f=product[1]; return (product[3]<<24)|(product[2]<<16)|(product[1]<<8)|product[0]; // rts ; 6 } #endif #if FIXED_IMPLEMENTATION==3 // Description: Unsigned 16-bit multiplication with unsigned 32-bit result. // Input: 16-bit unsigned value in T1 // 16-bit unsigned value in T2 // Carry=0: Re-use T1 from previous multiplication (faster) // Carry=1: Set T1 (slower) // // Output: 32-bit unsigned value in PRODUCT // Clobbered: PRODUCT, X, A, C // Allocation setup: T1,T2 and PRODUCT preferably on Zero-page. // square1_lo, square1_hi, square2_lo, square2_hi must be // page aligned. Each table are 512 bytes. Total 2kb. // // Table generation: I:0..511 // square1_lo = <((I*I)/4) // square1_hi = >((I*I)/4) // square2_lo = <(((I-255)*(I-255))/4) // square2_hi = >(((I-255)*(I-255))/4) static unsigned char square1_lo[512]; static unsigned char square1_hi[512]; static unsigned char square2_lo[512]; static unsigned char square2_hi[512]; static int table_ready=0; static void init_table(void) { int i; for(i=0;i<512;i++) { square1_lo[i]=((i*i)/4)&0xff; square1_hi[i]=(((i*i)/4)>>8)&0xff; square2_lo[i]=( ((i-255)*(i-255))/4)&0xff; square2_hi[i]=(( ((i-255)*(i-255))/4)>>8)&0xff; // printf("%d %x:%x %x:%x\n",i,square1_hi[i],square1_lo[i], // square2_hi[i],square2_lo[i]); } table_ready=1; // 3 * 2 // 3+2 = 5 // 3-2 = 1 // (25 - 1) = 24/4 = 6 // int num1l,num2l,a1,a2; // num1l=7; // num2l=9; // printf("Trying %d*%d\n",num1l,num2l); // a1=square1_lo[num1l+num2l]; // printf("((%d+%d)^2)/4: %d\n",num1l,num2l,a1); // a2=square2_lo[((~num1l)&0xff)+num2l]; // printf("((%d-%d)^2)/4: %d\n",num1l,num2l,a2); // printf("%d*%d=%d\n",num1l,num2l,a1-a2); } static unsigned int product[4]; int fixed_mul(int x_i,int x_f, int y_i, int y_f, int *z_i, int *z_f, int debug) { //int fixed_mul_unsigned(int x_i,int x_f, // int y_i, int y_f, // int debug) { // T2 = BBbb // >T1 * T1 * >T2 = DDdd // // AAaa // BBbb // CCcc // + DDdd // ---------- // PRODUCT! // ; Setup T1 if changed int c=0; int a,x; int sm1a,sm3a,sm5a,sm7a; int sm2a,sm4a,sm6a,sm8a; int sm1b,sm3b,sm5b;//,sm7b; int sm2b,sm4b,sm6b;//,sm8b; int _AA,_BB,_CC;//,_DD; int /* _aa,*/ _bb,_cc,_dd; if (!table_ready) init_table(); // printf("\t\t\tMultiplying %2x:%2x * %2x:%2x\n",x_i,x_f,y_i,y_f); /* Set up self-modifying code */ if (c==0) { a=(x_f)&0xff; // lda T1+0 ; 3 sm1a=a; // sta sm1a+1 ; 3 sm3a=a; // sta sm3a+1 ; 3 sm5a=a; // sta sm5a+1 ; 3 sm7a=a; // sta sm7a+1 ; 3 a=(~a)&0xff; // eor #$ff ; 2 sm2a=a; // sta sm2a+1 ; 3 sm4a=a; // sta sm4a+1 ; 3 sm6a=a; // sta sm6a+1 ; 3 sm8a=a; // sta sm8a+1 ; 3 a=(x_i)&0xff; // lda T1+1 ; 3 sm1b=a; // sta sm1b+1 ; 3 sm3b=a; // sta sm3b+1 ; 3 sm5b=a; // sta sm5b+1 ; 3 // sm7b=a; // sta sm7b+1 ; 3 a=(~a)&0xff; // eor #$ff ; 2 sm2b=a; // sta sm2b+1 ; 3 sm4b=a; // sta sm4b+1 ; 3 sm6b=a; // sta sm6b+1 ; 3 // sm8b=a; // sta sm8b+1 ; 3 } /* Perform T1_hi * T2 = BBbb */ x=(y_i)&0xff; // ldx T2+1 ; 3 c=1; // sec ; 2 //sm5a: a=square1_lo[sm5a+x]; // lda square1_lo,x ; 4 //sm6a: a+=(~(square2_lo[sm6a+x]))+c; // sbc square2_lo,x ; 4 c=!(a&0x100); a&=0xff; _bb=a; // sta _bb+1 ; 3 // printf("\t\t\t\tbb=%x c=%d\n",_bb,c); //sm7a: a=square1_hi[sm7a+x]; // lda square1_hi,x ; 4 //sm8a: a+=(~(square2_hi[sm8a+x]))+c; // sbc square2_hi,x ; 4 c=!(a&0x100); a&=0xff; _BB=a; // sta _BB+1 /* Perform >T1 * >T2 = DDdd */ c=1; // sec ; 2 //sm5b: a=square1_lo[sm5b+x]; // lda square1_lo,x ; 4 //sm6b: a+=(~(square2_lo[sm6b+x]))+c; // sbc square2_lo,x ; 4 c=!(a&0x100); a&=0xff; _dd=a; // sta _dd+1 ; 3 //sm7b: // a=square1_hi[sm7b+x]; // lda square1_hi,x ; 4 //sm8b: // a+=(~(square2_hi[sm8b+x]))+c; // sbc square2_hi,x ; 4 // c=!(a&0x100); // a&=0xff; // product[3]=a; // sta PRODUCT+3 ; 3 // _DD=a; /*********************************************/ /* Add the separate multiplications together */ /*********************************************/ // product[0]=_aa; // if (debug) printf("product[0]=0.%02x\n",_aa); // product[1]=_AA+_bb+(_cc) if (debug) printf("product[1]=%02x+%02x+0=",_AA,_bb); c=0; // clc ; 2 //_AA: a=_AA; // lda #0 ; 2 //_bb: a+=(c+_bb); // adc #0 ; 2 c=!!(a&0x100); a&=0xff; product[1]=a; // sta PRODUCT+1 ; 3 if (debug) printf("%x.%02x\n",c,a); // product[2]=_BB+_CC+c if (debug) printf("product[2]=%02x+%02x+%d=",_BB,_CC,c); //_BB: a=_BB; // lda #0 ; 2 //_CC: a+=(c+_CC); // adc #0 ; 2 c=!!(a&0x100); a&=0xff; product[2]=a; // sta PRODUCT+2 ; 3 if (debug) printf("%x.%02x\n",c,a); // product[3]=_DD+c // if (debug) printf("product[3]=%02x+%d=",_DD,c); // if (c==0) goto urgh2; // bcc :+ ; 2nt/3 // product[3]++; // inc PRODUCT+3 ; 5 // product[3]&=0xff; c=0; // clc ; 2 //urgh2: // if (debug) printf("%x.%02x\n",c,product[3]); // product[1]=_AA+_bb+_cc // if (debug) printf("product[1]=%02x+%02x+%d=",product[1],_cc,c); //_cc: a=_cc; // lda #0 ; 2 a+=c+product[1]; // adc PRODUCT+1 ; 3 c=!!(a&0x100); a&=0xff; product[1]=a; // sta PRODUCT+1 ; 3 if (debug) printf("%x.%02x\n",c,product[1]); // product[2]=_BB+_CC+_dd+c if (debug) printf("product[2]=%02x+%02x+%d=",product[2],_dd,c); //_dd: a=_dd; // lda #0 ; 2 a+=c+product[2]; // adc PRODUCT+2 ; 3 c=!!(a&0x100); a&=0xff; product[2]=a; // sta PRODUCT+2 ; 3 if (debug) printf("%x.%02x\n",c,product[2]); // product[3]=_DD+c // if (debug) printf("product[3]=%02x+%d=",product[3],c); // if (c==0) goto urgh; // bcc :+ ; 2nt/3 // product[3]++; // inc PRODUCT+3 ; 5 // product[3]&=0xff; //urgh: // if (debug) printf("%x.%02x\n",c,product[3]); // printf("Result=%02x:%02x\n",*z_i,*z_f); // if (debug) { // printf(" AAaa %02x:%02x\n",_AA,_aa); // printf(" BBbb %02x:%02x\n",_BB,_bb); // printf(" CCcc %02x:%02x\n",_CC,_cc); // printf("DDdd %02x:%02x\n",_DD,_dd); // } // return 0; //(product[3]<<24)|(product[2]<<16)|(product[1]<<8)|product[0]; // rts ; 6 //} /* signed */ //int fixed_mul(int x_i,int x_f, // int y_i, int y_f, // int *z_i, int *z_f, // int debug) { // int a,c; // fixed_mul_unsigned(x_i,x_f,y_i,y_f,debug); // jsr multiply_16bit_unsigned ; 6 a=(x_i&0xff); // lda T1+1 ; 3 if ((a&0x80)==0) goto x_positive; // bpl :+ ; 3/2nt if (debug) printf("Before: %02x:%02x:%02x:%02x\n",product[3],product[2],product[1],product[0]); c=1; // sec ; 2 a=product[2]; // lda PRODUCT+2 ; 3 a+=(~y_f)+c; // sbc T2+0 ; 3 c=!(a&0x100); a&=0xff; product[2]=a; // sta PRODUCT+2 ; 3 // a=product[3]; // lda PRODUCT+3 ; 3 // a+=(~y_i)+c; // sbc T2+1 ; 3 // c=!(a&0x100); // a&=0xff; // product[3]=a; // sta PRODUCT+3 ; 3 if (debug) printf("After: %02x:%02x:%02x:%02x\n",product[3],product[2],product[1],product[0]); x_positive: a=(y_i&0xff); // lda T2+1 ; 3 if ((a&0x80)==0) goto y_positive; // bpl :+ ; 3/2nt if (debug) printf("Before: %02x:%02x:%02x:%02x\n",product[3],product[2],product[1],product[0]); c=1; // sec ; 2 a=product[2]; // lda PRODUCT+2 ; 3 a+=(~x_f)+c; // sbc T1+0 ; 3 c=!(a&0x100); a&=0xff; product[2]=a; // sta PRODUCT+2 ; 3 // a=product[3]; // lda PRODUCT+3 ; 3 // a+=(~x_i)+c; // sbc T1+1 ; 3 // c=!(a&0x100); // a&=0xff; // product[3]=a; // sta PRODUCT+3 ; 3 if (debug) printf("After: %02x:%02x:%02x:%02x\n",product[3],product[2],product[1],product[0]); y_positive: *z_i=product[2]; *z_f=product[1]; // return (product[3]<<24)|(product[2]<<16)|(product[1]<<8)|product[0]; return 0; // rts ; 6 } #endif int main(int argc, char **argv) { int a_i,b_i,c_i; int a_f,b_f,c_f; // short x,y; int l,k,i,j; printf("Some tests\n"); #if 0 x=-32768; y=3; a_i=x>>8; a_f=x&0xff; b_i=y>>8; b_f=y&0xff; printf("\tTrying %d*%d=%d (0x%x)\n",x,y,x*y,x*y); k=fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0); if (k!=x*y) { printf("\t\tError! got %d (0x%x)\n",k,k); exit(1); } else { printf("\t\tProperly calculated %d\n",k); } a_i=0x0; a_f=0x7; b_i=0x0; b_f=0x9; x=7; y=9; printf("\tTrying %d*%d=%d (0x%x)\n",x,y,x*y,x*y); k=fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0); if (k!=x*y) { printf("\t\tError! got %d (0x%x)\n",k,k); exit(1); } else { printf("\t\tProperly calculated %d (0x%x)\n",k,k); } a_i=0x0; a_f=0x2; b_i=0x0; b_f=0x3; x=2; y=3; printf("\tTrying %d*%d=%d (0x%x)\n",x,y,x*y,x*y); k=fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0); if (k!=x*y) { printf("\t\tError! got %d (0x%x)\n",k,k); exit(1); } else { printf("\t\tProperly calculated %d (0x%x)\n",k,k); } a_i=0xff; a_f=0xff; b_i=0xff; b_f=0xff; x=0xffff; y=0xffff; printf("\tTrying %d*%d=%d (0x%x)\n",x,y,x*y,x*y); k=fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0); if (k!=x*y) { printf("\t\tError! got %d (0x%x)\n",k,k); exit(1); } else { printf("\t\tProperly calculated %d (0x%x)\n",k,k); } a_i=0xff; a_f=0xff; b_i=0x00; b_f=0x01; x=0xffff; y=0x1; printf("\tTrying %d*%d=%d (0x%x)\n",x,y,x*y,x*y); k=fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0); if (k!=x*y) { printf("\t\tError! got %d (0x%x)\n",k,k); exit(1); } else { printf("\t\tProperly calculated %d (0x%x)\n",k,k); } a_i=0x00; a_f=0xff; b_i=0x00; b_f=0x01; x=0xff; y=0x1; printf("\tTrying %d*%d=%d (0x%x)\n",x,y,x*y,x*y); k=fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0); if (k!=x*y) { printf("\t\tError! got %d (0x%x)\n",k,k); exit(1); } else { printf("\t\tProperly calculated %d (0x%x)\n",k,k); } for(i=-32768;i<32768;i++) { for(j=-32768;j<32768;j++) { a_i=i>>8; a_f=i&0xff; b_i=j>>8; b_f=j&0xff; k=fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0); if (k!=i*j) { printf("WRONG! %x*%x = %x not %x\n", i,j,i*j,k); printf(" %d * %d = %d not %d\n",i,j,i*j,k); exit(1); } } if (i%256==0) printf("%x\n",i); } #endif for(i=-32768;i<32768;i++) { for(j=-32768;j<32768;j++) { a_i=i>>8; a_f=i&0xff; b_i=j>>8; b_f=j&0xff; fixed_mul(a_i,a_f,b_i,b_f,&c_i,&c_f,0); k=((i*j)>>8)&0xffff; l=(c_i<<8)|(c_f); if (k!=l) { printf("WRONG! %x*%x = %x, %x not %02x:%02x\n", i,j,i*j,k,c_i,c_f); printf(" %d * %d = %d not %d\n",i,j,l,k); exit(1); } } if (i%256==0) printf("%x\n",i); } return 0; }