mirror of
https://github.com/deater/dos33fsprogs.git
synced 2025-03-03 12:31:32 +00:00
tfv: wasted a lot of time trying to get signed 16x16 multiply working
This commit is contained in:
parent
efb63f57b7
commit
621f808531
@ -93,6 +93,9 @@ tfv_flying.o: tfv_flying.c
|
||||
tfv_info.o: tfv_info.c
|
||||
$(CC) $(CFLAGS) -c tfv_info.c
|
||||
|
||||
tfv_multiply.o: tfv_multiply.c
|
||||
$(CC) $(CFLAGS) -c tfv_multiply.c
|
||||
|
||||
tfv_opener.o: tfv_opener.c tfv_utils.h
|
||||
$(CC) $(CFLAGS) -c tfv_opener.c
|
||||
|
||||
@ -114,8 +117,8 @@ tfv_worldmap.o: tfv_worldmap.c
|
||||
tfv.o: tfv.c gr-sim.h tfv_backgrounds.h tfv_sprites.h
|
||||
$(CC) $(CFLAGS) -c tfv.c
|
||||
|
||||
tfv: tfv.o tfv_backgrounds.o tfv_battle.o tfv_flying.o tfv_info.o tfv_opener.o tfv_sprites.o tfv_textentry.o tfv_title.o tfv_utils.o tfv_worldmap.o gr-sim.o
|
||||
$(CC) $(LFLAGS) $(SDL_LIBS) -o tfv tfv.o tfv_backgrounds.o tfv_battle.o tfv_flying.o tfv_info.o tfv_opener.o tfv_sprites.o tfv_textentry.o tfv_title.o tfv_utils.o tfv_worldmap.o gr-sim.o
|
||||
tfv: tfv.o tfv_backgrounds.o tfv_battle.o tfv_flying.o tfv_info.o tfv_multiply.o tfv_opener.o tfv_sprites.o tfv_textentry.o tfv_title.o tfv_utils.o tfv_worldmap.o gr-sim.o
|
||||
$(CC) $(LFLAGS) $(SDL_LIBS) -o tfv tfv.o tfv_backgrounds.o tfv_battle.o tfv_flying.o tfv_info.o tfv_multiply.o tfv_opener.o tfv_sprites.o tfv_textentry.o tfv_title.o tfv_utils.o tfv_worldmap.o gr-sim.o
|
||||
|
||||
###
|
||||
|
||||
|
@ -76,11 +76,6 @@ static int screen_x, screen_y;
|
||||
static char angle=0;
|
||||
|
||||
|
||||
struct fixed_type {
|
||||
char i;
|
||||
unsigned char f;
|
||||
};
|
||||
|
||||
// 1 = use reduced fixed point
|
||||
// 0 = use fancy hi-res floating point
|
||||
#if 1
|
||||
@ -204,28 +199,14 @@ static void fixed_add(struct fixed_type *x, struct fixed_type *y, struct fixed_t
|
||||
// f->f=temp&0xff;
|
||||
//}
|
||||
|
||||
static void fixed_mul(struct fixed_type *x, struct fixed_type *y, struct fixed_type *z) {
|
||||
|
||||
int a,b,c;
|
||||
|
||||
a=((x->i)<<8)+(x->f);
|
||||
b=((y->i)<<8)+(y->f);
|
||||
|
||||
c=a*b;
|
||||
|
||||
c>>=8;
|
||||
|
||||
z->i=(c>>8);
|
||||
z->f=(c&0xff);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Non-detailed version
|
||||
//
|
||||
//
|
||||
|
||||
static int displayed=0;
|
||||
|
||||
void draw_background_mode7(void) {
|
||||
|
||||
|
||||
@ -247,7 +228,13 @@ void draw_background_mode7(void) {
|
||||
// fixed_to_double(&space_z,&double_space_z);
|
||||
// double_factor=double_space_z*double_BETA;
|
||||
|
||||
fixed_mul(&space_z,&BETA,&factor);
|
||||
fixed_mul(&space_z,&BETA,&factor,0);
|
||||
|
||||
if (!displayed) {
|
||||
printf("%x %x * %x %x = %x %x\n",
|
||||
space_z.i,space_z.f,BETA.i,BETA.f,factor.i,factor.f);
|
||||
displayed=1;
|
||||
}
|
||||
|
||||
// printf("spacez=%lf beta=%lf factor=%lf\n",
|
||||
// fixed_to_double(&space_z),
|
||||
@ -265,7 +252,7 @@ void draw_background_mode7(void) {
|
||||
horizontal_lookup[space_z.i&0xf][(screen_y-8)/2];
|
||||
|
||||
// calculate the distance of the line we are drawing
|
||||
fixed_mul(&horizontal_scale,&scale,&distance);
|
||||
fixed_mul(&horizontal_scale,&scale,&distance,0);
|
||||
//fixed_to_double(&distance,&double_distance);
|
||||
|
||||
// printf("Distance=%lf, horizontal-scale=%lf\n",
|
||||
@ -275,11 +262,11 @@ void draw_background_mode7(void) {
|
||||
// through all points on this line
|
||||
dx.i=fixed_sin[(angle+8)&0xf].i; // -sin()
|
||||
dx.f=fixed_sin[(angle+8)&0xf].f; // -sin()
|
||||
fixed_mul(&dx,&horizontal_scale,&dx);
|
||||
fixed_mul(&dx,&horizontal_scale,&dx,0);
|
||||
|
||||
dy.i=fixed_sin[(angle+4)&0xf].i; // cos()
|
||||
dy.f=fixed_sin[(angle+4)&0xf].f; // cos()
|
||||
fixed_mul(&dy,&horizontal_scale,&dy);
|
||||
fixed_mul(&dy,&horizontal_scale,&dy,0);
|
||||
|
||||
// calculate the starting position
|
||||
//double_space_x =(double_distance+double_factor);
|
||||
@ -287,11 +274,11 @@ void draw_background_mode7(void) {
|
||||
// double_to_fixed(double_space_x,&space_x);
|
||||
fixed_temp.i=fixed_sin[(angle+4)&0xf].i; // cos
|
||||
fixed_temp.f=fixed_sin[(angle+4)&0xf].f; // cos
|
||||
fixed_mul(&space_x,&fixed_temp,&space_x);
|
||||
fixed_mul(&space_x,&fixed_temp,&space_x,0);
|
||||
fixed_add(&space_x,&cx,&space_x);
|
||||
fixed_temp.i=0xec; // -20 (LOWRES_W/2)
|
||||
fixed_temp.f=0;
|
||||
fixed_mul(&fixed_temp,&dx,&fixed_temp);
|
||||
fixed_mul(&fixed_temp,&dx,&fixed_temp,0);
|
||||
fixed_add(&space_x,&fixed_temp,&space_x);
|
||||
|
||||
fixed_add(&distance,&factor,&space_y);
|
||||
@ -299,11 +286,11 @@ void draw_background_mode7(void) {
|
||||
// double_to_fixed(double_space_y,&space_y);
|
||||
fixed_temp.i=fixed_sin[angle&0xf].i;
|
||||
fixed_temp.f=fixed_sin[angle&0xf].f;
|
||||
fixed_mul(&space_y,&fixed_temp,&space_y);
|
||||
fixed_mul(&space_y,&fixed_temp,&space_y,0);
|
||||
fixed_add(&space_y,&cy,&space_y);
|
||||
fixed_temp.i=0xec; // -20 (LOWRES_W/2)
|
||||
fixed_temp.f=0;
|
||||
fixed_mul(&fixed_temp,&dy,&fixed_temp);
|
||||
fixed_mul(&fixed_temp,&dy,&fixed_temp,0);
|
||||
fixed_add(&space_y,&fixed_temp,&space_y);
|
||||
|
||||
// go through all points in this screen line
|
||||
|
295
gr-sim/tfv_multiply.c
Normal file
295
gr-sim/tfv_multiply.c
Normal file
@ -0,0 +1,295 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "tfv_zp.h"
|
||||
|
||||
#if 0
|
||||
int fixed_mul(struct fixed_type *x,
|
||||
struct fixed_type *y,
|
||||
struct fixed_type *z, int debug) {
|
||||
|
||||
int a,b,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;
|
||||
}
|
||||
#else
|
||||
|
||||
|
||||
int fixed_mul(struct fixed_type *x,
|
||||
struct fixed_type *y,
|
||||
struct fixed_type *z,
|
||||
int debug) {
|
||||
|
||||
int num1h,num1l;
|
||||
int num2h,num2l;
|
||||
int result3;
|
||||
int result2,result1,result0;
|
||||
int aa,xx,cc=0,cc2,yy;
|
||||
int negative=0;
|
||||
|
||||
num1h=x->i;
|
||||
num1l=x->f;
|
||||
|
||||
if (num1h&0x80) {
|
||||
negative^=1;
|
||||
|
||||
num1l=~num1l;
|
||||
num1h=~num1h;
|
||||
|
||||
num1l&=0xff;
|
||||
num1h&=0xff;
|
||||
|
||||
num1l+=1;
|
||||
cc=!!(num1l&0x100);
|
||||
num1h+=cc;
|
||||
|
||||
num1l&=0xff;
|
||||
num1h&=0xff;
|
||||
|
||||
}
|
||||
|
||||
num2h=y->i;
|
||||
num2l=y->f;
|
||||
|
||||
if (num2h&0x80) {
|
||||
negative^=1;
|
||||
|
||||
num2l=~num2l;
|
||||
num2h=~num2h;
|
||||
|
||||
num2l&=0xff;
|
||||
num2h&=0xff;
|
||||
|
||||
num2l+=1;
|
||||
cc=!!(num2l&0x100);
|
||||
num2h+=cc;
|
||||
|
||||
num2l&=0xff;
|
||||
num2h&=0xff;
|
||||
|
||||
}
|
||||
|
||||
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 (negative) {
|
||||
// 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 0
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
struct fixed_type a,b,c;
|
||||
int i,j,k;
|
||||
|
||||
i=-32768;
|
||||
j=3;
|
||||
|
||||
a.i=i>>8;
|
||||
a.f=i&0xff;
|
||||
b.i=j>>8;
|
||||
b.f=j&0xff;
|
||||
|
||||
k=fixed_mul(&a,&b,&c,1);
|
||||
if (k!=i*j) {
|
||||
printf("Error! %d*%d=%d, %d\n",i,j,i*j,k);
|
||||
}
|
||||
|
||||
a.i=0x0;
|
||||
a.f=0x2;
|
||||
|
||||
b.i=0x0;
|
||||
b.f=0x3;
|
||||
|
||||
fixed_mul(&a,&b,&c,0);
|
||||
|
||||
a.i=0xff;
|
||||
a.f=0xff;
|
||||
|
||||
b.i=0xff;
|
||||
b.f=0xff;
|
||||
|
||||
fixed_mul(&a,&b,&c,0);
|
||||
|
||||
a.i=0xff;
|
||||
a.f=0xff;
|
||||
|
||||
b.i=0x00;
|
||||
b.f=0x01;
|
||||
|
||||
fixed_mul(&a,&b,&c,0);
|
||||
|
||||
|
||||
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,&b,&c,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);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@ -56,6 +56,15 @@ extern unsigned char ground_color;
|
||||
|
||||
extern char nameo[9];
|
||||
|
||||
struct fixed_type {
|
||||
char i;
|
||||
unsigned char f;
|
||||
};
|
||||
|
||||
|
||||
int fixed_mul(struct fixed_type *x,
|
||||
struct fixed_type *y,
|
||||
struct fixed_type *z, int debug);
|
||||
|
||||
int opening(void);
|
||||
int title(void);
|
||||
|
@ -55,6 +55,11 @@ flying_start:
|
||||
sta SPACEX_I
|
||||
sta SPACEY_I
|
||||
|
||||
lda #4
|
||||
sta SPACEZ_I
|
||||
lda #$80
|
||||
sta SPACEZ_F
|
||||
|
||||
flying_loop:
|
||||
|
||||
|
||||
@ -187,19 +192,35 @@ sky_loop: ; draw line across screen
|
||||
|
||||
; fixed_mul(&space_z,&BETA,&factor);
|
||||
lda SPACEZ_I
|
||||
sta NUM1
|
||||
lda SPACEZ_F
|
||||
sta NUM1+1
|
||||
lda SPACEZ_F
|
||||
sta NUM1
|
||||
lda #$ff ; BETA_I
|
||||
sta NUM2
|
||||
lda #$80 ; BETA_F
|
||||
sta NUM2+1
|
||||
lda #$80 ; BETA_F
|
||||
sta NUM2
|
||||
|
||||
jsr multiply
|
||||
|
||||
lda RESULT+1
|
||||
sta FACTOR_I
|
||||
lda RESULT+2
|
||||
sta FACTOR_F
|
||||
|
||||
brk ;; SPACEZ=78 * ff80 = FACTOR=66
|
||||
|
||||
;; 4 80 * ff 80 = 83 81
|
||||
|
||||
;; 4 80 * 00 00 = fc 83 81 40
|
||||
|
||||
;; 4 80 * ffffffff 80 = fffffffd c0
|
||||
;; spacez*beta=factor
|
||||
|
||||
|
||||
;; C
|
||||
;; GOOD 4 80 * ffffffff 80 = fffffffd c0
|
||||
;; BAD 4 80 * ffffffff 80 = 42 40
|
||||
|
||||
lda #8
|
||||
sta SCREEN_Y
|
||||
|
||||
@ -548,11 +569,15 @@ water_map:
|
||||
|
||||
; http://www.llx.com/~nparker/a2/mult.html
|
||||
; MULTIPLY NUM1H:NUM1L * NUM2H:NUM2L
|
||||
; NUM2 is zero in end
|
||||
|
||||
NUM1: .byte 0,0
|
||||
NUM2: .byte 0,0
|
||||
RESULT: .byte 0,0,0,0
|
||||
|
||||
; If we have 2k to spare we should check out
|
||||
; http://codebase64.org/doku.php?id=base:seriously_fast_multiplication
|
||||
|
||||
multiply:
|
||||
lda #0 ; Initialize RESULT to 0
|
||||
sta RESULT+2
|
||||
|
Loading…
x
Reference in New Issue
Block a user