tfv: add more cycle annotations

This commit is contained in:
Vince Weaver 2017-11-22 23:50:43 -05:00
parent be98d15390
commit 91df570368
7 changed files with 541 additions and 447 deletions

View File

@ -1340,7 +1340,8 @@ hlin_loop:
return 0;
}
int hlin_double(int page, int x1, int x2, int at) {
int hlin_setup(int page, int x1, int x2, int at) {
// page, y, V2, A
a=at;
y=at/2;
@ -1351,6 +1352,15 @@ int hlin_double(int page, int x1, int x2, int at) {
ram[GBASH]+=(page);
ram[GBASL]+=x1;
return 0;
}
int hlin_double(int page, int x1, int x2, int at) {
hlin_setup(page,x1,x2,at);
hlin_double_continue(x2-x1+1);
return 0;

View File

@ -24,6 +24,7 @@ void basic_print(char *string);
void basic_inverse(void);
void basic_normal(void);
int hlin(int page, int x1, int x2, int at);
int hlin_setup(int page, int x1, int x2, int at);
int hlin_continue(int width);
int hlin_double_continue(int width);
int hlin_double(int page, int x1, int x2, int at);

View File

@ -183,6 +183,17 @@ static unsigned char horizontal_lookup[7][16] = {
};
struct cycle_counts {
int flying;
int getkey;
int page_flip;
int mode7;
int multiply;
int lookup_map;
int put_sprite;
} cycles;
static void fixed_add(unsigned char x_i,unsigned char x_f,
unsigned char y_i, unsigned char y_f,
unsigned char *z_i, unsigned char *z_f) {
@ -211,14 +222,23 @@ static void fixed_mul(unsigned char x_i, unsigned char x_f,
int result3;
int result2,result1,result0;
int aa,xx,cc=0,cc2,yy;
int negate=0;
unsigned char negate;
num1h=x_i;
num1l=x_f;
if (!(num1h&0x80)) goto check_num2; // bpl check_num2
negate=0; // lda #0 2
// sta NEGATE 4
negate++; // inc negate
// lda NUM1H 4
cycles.multiply+=13;
if (!(num1h&0x80)) goto check_num2; // bpl check_num2 2nt/3
cycles.multiply--;
negate++; // inc NEGATE 6
num1l=~num1l;
num1h=~num1h;
@ -232,13 +252,15 @@ static void fixed_mul(unsigned char x_i, unsigned char x_f,
num1l&=0xff;
num1h&=0xff;
// total=26
cycles.multiply+=26;
check_num2:
num2h=y_i;
num2l=y_f;
cycles.multiply+=7;
if (!(num2h&0x80)) goto unsigned_multiply;
cycles.multiply--;
negate++;
num2l=~num2l;
@ -253,7 +275,7 @@ check_num2:
num2l&=0xff;
num2h&=0xff;
cycles.multiply+=30;
unsigned_multiply:
// if (debug) {
@ -266,7 +288,8 @@ unsigned_multiply:
aa=0; // lda #0 (sz)
result2=aa; // sta result+2
xx=16; // ldx #16 (sz)
label_l1:
cycles.multiply+=8;
multiply_mainloop:
cc=(num2h&1); //lsr NUM2+1 (szc)
num2h>>=1;
num2h&=0x7f;
@ -281,8 +304,9 @@ label_l1:
num2l|=(cc<<7);
cc=cc2;
if (cc==0) goto label_l2; // bcc L2
cycles.multiply+=15;
if (cc==0) goto shift_output; // bcc L2
cycles.multiply--;
yy=aa; // tay (sz)
cc=0; // clc
@ -295,8 +319,8 @@ label_l1:
aa=aa+cc+num1h; // adc NUM1+1
cc=!!(aa&0x100);
aa=aa&0xff;
label_l2:
cycles.multiply+=22;
shift_output:
cc2=aa&1;
aa=aa>>1;
aa&=0x7f;
@ -322,8 +346,9 @@ label_l2:
cc=cc2; // ror result+0
xx--; // dex
if (xx!=0) goto label_l1; // bne L1
cycles.multiply+=25;
if (xx!=0) goto multiply_mainloop; // bne L1
cycles.multiply--;
result3=aa&0xff; // sta result+3
@ -331,10 +356,10 @@ label_l2:
// printf("RAW RESULT = %02x:%02x:%02x:%02x\n",
// result3&0xff,result2&0xff,result1&0xff,result0&0xff);
// }
cycles.multiply+=13;
if (negate&1) {
// printf("NEGATING!\n");
cycles.multiply--;
cc=0;
aa=0;
@ -356,7 +381,7 @@ label_l2:
aa-=result3+cc;
cc=!!(aa&0x100);
result3=aa;
cycles.multiply+=50;
}
*z_i=result2&0xff;
@ -385,7 +410,7 @@ label_l2:
// a2=(result3<<24)|(result2<<16)|(result1<<8)|result0;
// printf("%d * %d = %d (0x%x)\n",s1,s2,a2,a2);
cycles.multiply+=6;
return;
}
@ -400,14 +425,18 @@ void draw_background_mode7(void) {
/* Draw Sky */
/* Originally wanted to be fancy and have sun too, but no */
color_equals(COLOR_MEDIUMBLUE);
cycles.mode7+=10;
for(ram[SCREEN_Y]=0;ram[SCREEN_Y]<6;ram[SCREEN_Y]+=2) {
hlin_double(ram[DRAW_PAGE], 0, 40, ram[SCREEN_Y]);
}
cycles.mode7+=(63+(16*40)+23)*5;
/* Draw hazy horizon */
color_equals(COLOR_GREY);
hlin_double(ram[DRAW_PAGE], 0, 40, 6);
cycles.mode7+=14+63+(16*40);
cycles.mode7+=28;
fixed_mul(ram[SPACEZ_I],ram[SPACEZ_F],
CONST_BETA_I,CONST_BETA_F,
&ram[FACTOR_I],&ram[FACTOR_F]);
@ -423,15 +452,21 @@ void draw_background_mode7(void) {
// fixed_to_double(ram[SPACEZ_I],ram[SPACEZ_F],),
// fixed_to_double(&BETA),
// fixed_to_double(ram[FACTOR_I],ram[FACTOR_F]));
cycles.mode7+=22;
for (ram[SCREEN_Y] = 8; ram[SCREEN_Y] < LOWRES_H; ram[SCREEN_Y]+=2) {
y=0;
hlin_setup(ram[DRAW_PAGE],y,0,ram[SCREEN_Y]);
cycles.mode7+=43;
// then calculate the horizontal scale, or the distance between
// space points on this horizontal line
ram[HORIZ_SCALE_I]=0;
ram[HORIZ_SCALE_F]=
horizontal_lookup[ram[SPACEZ_I]&0xf]
[(ram[SCREEN_Y]-8)/2];
cycles.mode7+=44;
if (!displayed) {
printf("HORIZ_SCALE %x %x\n",
@ -442,7 +477,7 @@ void draw_background_mode7(void) {
fixed_mul(ram[HORIZ_SCALE_I],ram[HORIZ_SCALE_F],
CONST_SCALE_I,CONST_SCALE_F,
&ram[DISTANCE_I],&ram[DISTANCE_F]);
cycles.mode7+=44;
if (!displayed) {
printf("DISTANCE %x:%x\n",ram[DISTANCE_I],ram[DISTANCE_F]);
}
@ -451,10 +486,12 @@ void draw_background_mode7(void) {
// through all points on this line
ram[DX_I]=fixed_sin[(ram[ANGLE]+8)&0xf].i; // -sin()
ram[DX_F]=fixed_sin[(ram[ANGLE]+8)&0xf].f; // -sin()
cycles.mode7+=29;
fixed_mul(ram[DX_I],ram[DX_F],
ram[HORIZ_SCALE_I],ram[HORIZ_SCALE_F],
&ram[DX_I],&ram[DX_F]);
cycles.mode7+=48;
if (!displayed) {
printf("DX %x:%x\n",ram[DX_I],ram[DX_F]);
}
@ -462,10 +499,11 @@ void draw_background_mode7(void) {
ram[DY_I]=fixed_sin[(ram[ANGLE]+4)&0xf].i; // cos()
ram[DY_F]=fixed_sin[(ram[ANGLE]+4)&0xf].f; // cos()
cycles.mode7+=29;
fixed_mul(ram[DY_I],ram[DY_F],
ram[HORIZ_SCALE_I],ram[HORIZ_SCALE_F],
&ram[DY_I],&ram[DY_F]);
cycles.mode7+=48;
if (!displayed) {
printf("DY %x:%x\n",ram[DY_I],ram[DY_F]);
}
@ -474,48 +512,62 @@ void draw_background_mode7(void) {
fixed_add(ram[DISTANCE_I],ram[DISTANCE_F],
ram[FACTOR_I],ram[FACTOR_F],
&ram[SPACEX_I],&ram[SPACEX_F]);
fixed_add(ram[DISTANCE_I],ram[DISTANCE_F],
ram[FACTOR_I],ram[FACTOR_F],
&ram[SPACEY_I],&ram[SPACEY_F]);
cycles.mode7+=26;
ram[TEMP_I]=fixed_sin[(ram[ANGLE]+4)&0xf].i; // cos
ram[TEMP_F]=fixed_sin[(ram[ANGLE]+4)&0xf].f; // cos
cycles.mode7+=29;
fixed_mul(ram[SPACEX_I],ram[SPACEX_F],
ram[TEMP_I],ram[TEMP_F],
&ram[SPACEX_I],&ram[SPACEX_F]);
cycles.mode7+=48;
fixed_add(ram[SPACEX_I],ram[SPACEX_F],
ram[CX_I],ram[CX_F],
&ram[SPACEX_I],&ram[SPACEX_F]);
ram[TEMP_I]=0xec; // -20 (LOWRES_W/2)
ram[TEMP_F]=0;
cycles.mode7+=30;
fixed_mul(ram[TEMP_I],ram[TEMP_F],
ram[DX_I],ram[DX_F],
&ram[TEMP_I],&ram[TEMP_F]);
cycles.mode7+=48;
fixed_add(ram[SPACEX_I],ram[SPACEX_F],
ram[TEMP_I],ram[TEMP_F],
&ram[SPACEX_I],&ram[SPACEX_F]);
cycles.mode7+=20;
if (!displayed) {
printf("SPACEX! %x:%x\n",
ram[SPACEX_I],ram[SPACEX_F]);
}
fixed_add(ram[DISTANCE_I],ram[DISTANCE_F],
ram[FACTOR_I],ram[FACTOR_F],
&ram[SPACEY_I],&ram[SPACEY_F]);
ram[TEMP_I]=fixed_sin[ram[ANGLE]&0xf].i;
ram[TEMP_F]=fixed_sin[ram[ANGLE]&0xf].f;
cycles.mode7+=25;
fixed_mul(ram[SPACEY_I],ram[SPACEY_F],
ram[TEMP_I],ram[TEMP_F],
&ram[SPACEY_I],&ram[SPACEY_F]);
cycles.mode7+=48;
fixed_add(ram[SPACEY_I],ram[SPACEY_F],
ram[CY_I],ram[CY_F],
&ram[SPACEY_I],&ram[SPACEY_F]);
ram[TEMP_I]=0xec; // -20 (LOWRES_W/2)
ram[TEMP_F]=0;
cycles.mode7+=30;
fixed_mul(ram[TEMP_I],ram[TEMP_F],
ram[DY_I],ram[DY_F],
&ram[TEMP_I],&ram[TEMP_F]);
cycles.mode7+=48;
fixed_add(ram[SPACEY_I],ram[SPACEY_F],
ram[TEMP_I],ram[TEMP_F],
&ram[SPACEY_I],&ram[SPACEY_F]);
cycles.mode7+=25;
if (!displayed) {
printf("SPACEY! %x:%x\n",ram[SPACEY_I],ram[SPACEY_F]);
}
@ -533,8 +585,8 @@ void draw_background_mode7(void) {
if (map_color==COLOR_DARKBLUE) ram[OVER_WATER]=1;
}
hlin_double(ram[DRAW_PAGE], ram[SCREEN_X], ram[SCREEN_X]+1,
ram[SCREEN_Y]);
hlin_double_continue(1);
cycles.mode7+=42;
// advance to the next position in space
fixed_add(ram[SPACEX_I],ram[SPACEX_F],
@ -543,19 +595,17 @@ void draw_background_mode7(void) {
fixed_add(ram[SPACEY_I],ram[SPACEY_F],
ram[DY_I],ram[DY_F],
&ram[SPACEY_I],&ram[SPACEY_F]);
cycles.mode7+=53;
}
cycles.mode7+=17;
}
displayed=1;
cycles.mode7+=6;
}
struct cycle_counts {
int flying;
int getkey;
int page_flip;
} cycles;
static int iterations=0;
@ -775,10 +825,16 @@ int flying(void) {
if (iterations==100) {
int total_cycles;
total_cycles=cycles.flying+cycles.getkey+
cycles.page_flip;
cycles.page_flip+cycles.multiply+
cycles.mode7+cycles.lookup_map+
cycles.put_sprite;
printf("Cycles: flying=%d\n",cycles.flying);
printf("Cycles: getkey=%d\n",cycles.getkey);
printf("Cycles: page_flip=%d\n",cycles.page_flip);
printf("Cycles: multiply=%d\n",cycles.multiply);
printf("Cycles: mode7=%d\n",cycles.mode7);
printf("Cycles: lookup_map=%d\n",cycles.lookup_map);
printf("Cycles: put_sprite=%d\n",cycles.put_sprite);
printf("Total = %d\n",total_cycles);
printf("Frame Rate = %.2lf fps\n",
(1000000.0 / (double)total_cycles));

View File

@ -1,3 +1,9 @@
mode7 speed fixes:
+ Don't draw sky every frame, only if needed
+ faster multiply routine
+ move multiply vars to zero page
+ leave one of multiply results in accumulator at end?
short term:
longer term:

View File

@ -550,66 +550,60 @@ draw_ship:
draw_background_mode7:
; Draw Sky
; FIXME: the sky never changes?
lda #COLOR_BOTH_MEDIUMBLUE ; MEDIUMBLUE color
sta COLOR
lda #COLOR_BOTH_MEDIUMBLUE ; MEDIUMBLUE color ; 2
sta COLOR ; 3
lda #0
sta OVER_WATER
lda #0 ; 2
sta OVER_WATER ; 3
;===========
; 10
sky_loop: ; draw line across screen
ldy #40 ; from y=0 to y=6
sty V2
ldy #0
pha
jsr hlin_double ; hlin y,V2 at A
pla
clc
adc #2
cmp #6
bne sky_loop
ldy #40 ; from y=0 to y=6 ; 2
sty V2 ; 3
ldy #0 ; 2
pha ; 3
jsr hlin_double ; hlin y,V2 at A ; 63+(X*16)
pla ; 4
clc ; 2
adc #2 ; 2
cmp #6 ; 2
bne sky_loop ; 3/2nt
;=============
; (23+63+(X*16))*5
; Draw Horizon
lda #COLOR_BOTH_GREY ; Horizon is Grey
sta COLOR
lda #6 ; draw single line at 6/7
ldy #40
sty V2 ; hlin Y,V2 at A
ldy #0
jsr hlin_double ; hlin 0,40 at 6
lda #COLOR_BOTH_GREY ; Horizon is Grey ; 2
sta COLOR ; 3
lda #6 ; draw single line at 6/7 ; 2
ldy #40 ; 2
sty V2 ; hlin Y,V2 at A ; 3
ldy #0 ; 2
jsr hlin_double ; hlin 0,40 at 6 ; 63+(X*16)
;===========
; 63+(X*16)+14
; fixed_mul(&space_z,&BETA,&factor);
lda SPACEZ_I
sta NUM1H
lda SPACEZ_F
sta NUM1L
lda SPACEZ_I ; 3
sta NUM1H ; 3
lda SPACEZ_F ; 3
sta NUM1L ; 3
lda #$ff ; BETA_I
sta NUM2H
lda #$80 ; BETA_F
sta NUM2L
lda #$ff ; BETA_I ; 2
sta NUM2H ; 3
lda #$80 ; BETA_F ; 2
sta NUM2L ; 3
;; TEST
;; lda #$0
;; sta NUM1H
;; lda #$2
;; sta NUM1L
jsr multiply ; 6
;===========
; 28
;; lda #$0
;; sta NUM2H
;; lda #$3
;; sta NUM2L
jsr multiply
lda RESULT+2
sta FACTOR_I
lda RESULT+1
sta FACTOR_F
lda RESULT+2 ; 4
sta FACTOR_I ; 4
lda RESULT+1 ; 4
sta FACTOR_F ; 4
;; SPACEZ=78 * ff80 = FACTOR=66
@ -617,329 +611,356 @@ sky_loop: ; draw line across screen
;; GOOD 4 80 * ffffffff 80 = fffffffd c0
;; BAD 4 80 * ffffffff 80 = 42 40
lda #8
sta SCREEN_Y
lda #8 ; 2
sta SCREEN_Y ; 4
;=============
; 22
screeny_loop:
ldy #0
jsr hlin_setup ; y-coord in a, x-coord in y
ldy #0 ; 2
jsr hlin_setup ; y-coord in a, x-coord in y ; 41
; sets up GBASL/GBASH
;=============
; 43
lda #0 ; horizontal_scale.i = 0
sta HORIZ_SCALE_I
lda #0 ; horizontal_scale.i = 0 ; 2
sta HORIZ_SCALE_I ; 3
;horizontal_scale.f=
; horizontal_lookup[space_z.i&0xf][(screen_y-8)/2];
lda SPACEZ_I
and #$f
asl
asl
asl
asl
sta TEMP_I
sec
lda SCREEN_Y
sbc #8
lsr
clc
adc TEMP_I
tay
lda horizontal_lookup,Y
sta HORIZ_SCALE_F
lda SPACEZ_I ; 3
and #$f ; 2
asl ; 2
asl ; 2
asl ; 2
asl ; 2
sta TEMP_I ; 3
sec ; 2
lda SCREEN_Y ; 3
sbc #8 ; 2
lsr ; 2
clc ; 2
adc TEMP_I ; 3
tay ; 2
lda horizontal_lookup,Y ; 4
sta HORIZ_SCALE_F ; 3
;============
; 44
;; brk ASM, horiz_scale = 00:73
; calculate the distance of the line we are drawing
; fixed_mul(&horizontal_scale,&scale,&distance);
lda HORIZ_SCALE_I
sta NUM1H
lda HORIZ_SCALE_F
sta NUM1L
lda #$14 ; SCALE_I
sta NUM2H
lda #$00 ; SCALE_F
sta NUM2L
jsr multiply
lda RESULT+2
sta DISTANCE_I
lda RESULT+1
sta DISTANCE_F
lda HORIZ_SCALE_I ; 3
sta NUM1H ; 4
lda HORIZ_SCALE_F ; 3
sta NUM1L ; 4
lda #$14 ; SCALE_I ; 2
sta NUM2H ; 4
lda #$00 ; SCALE_F ; 2
sta NUM2L ; 4
jsr multiply ; 6
lda RESULT+2 ; 4
sta DISTANCE_I ; 2
lda RESULT+1 ; 4
sta DISTANCE_F ; 2
;==========
; 44
;; brk ASM, distance = 08:fc
; calculate the dx and dy of points in space when we step
; through all points on this line
lda ANGLE ; dx.i=fixed_sin[(angle+8)&0xf].i; // -sin()
clc
adc #8
and #$f
asl
tay
lda fixed_sin,Y
sta DX_I
iny ; dx.f=fixed_sin[(angle+8)&0xf].f; // -sin()
lda fixed_sin,Y
sta DX_F
lda ANGLE ; dx.i=fixed_sin[(angle+8)&0xf].i; // -sin() ; 3
clc ; 2
adc #8 ; 2
and #$f ; 2
asl ; 2
tay ; 2
lda fixed_sin,Y ; 4
sta DX_I ; 3
iny ; dx.f=fixed_sin[(angle+8)&0xf].f; // -sin() ; 2
lda fixed_sin,Y ; 4
sta DX_F ; 3
;==========
; 29
; fixed_mul(&dx,&horizontal_scale,&dx);
lda HORIZ_SCALE_I
sta NUM1H
lda HORIZ_SCALE_F
sta NUM1L
lda DX_I
sta NUM2H
lda DX_F
sta NUM2L
jsr multiply
lda RESULT+2
sta DX_I
lda RESULT+1
sta DX_F
lda HORIZ_SCALE_I ; 3
sta NUM1H ; 4
lda HORIZ_SCALE_F ; 3
sta NUM1L ; 4
lda DX_I ; 3
sta NUM2H ; 4
lda DX_F ; 3
sta NUM2L ; 4
jsr multiply ; 6
lda RESULT+2 ; 4
sta DX_I ; 3
lda RESULT+1 ; 4
sta DX_F ; 3
;==========
; 48
;; ANGLE
;; brk ASM, dx = 00:00
lda ANGLE ; dy.i=fixed_sin[(angle+4)&0xf].i; // cos()
clc
adc #4
and #$f
asl
tay
lda fixed_sin,Y
sta DY_I
iny ; dy.f=fixed_sin[(angle+4)&0xf].f; // cos()
lda fixed_sin,Y
sta DY_F
lda ANGLE ; dy.i=fixed_sin[(angle+4)&0xf].i; // cos() ; 3
clc ; 2
adc #4 ; 2
and #$f ; 2
asl ; 2
tay ; 2
lda fixed_sin,Y ; 4
sta DY_I ; 3
iny ; dy.f=fixed_sin[(angle+4)&0xf].f; // cos() ; 2
lda fixed_sin,Y ; 4
sta DY_F ; 3
;==========
; 29
; fixed_mul(&dy,&horizontal_scale,&dy);
lda HORIZ_SCALE_I
sta NUM1H
lda HORIZ_SCALE_F
sta NUM1L
lda DY_I
sta NUM2H
lda DY_F
sta NUM2L
jsr multiply
lda RESULT+2
sta DY_I
lda RESULT+1
sta DY_F
lda HORIZ_SCALE_I ; 3
sta NUM1H ; 4
lda HORIZ_SCALE_F ; 3
sta NUM1L ; 4
lda DY_I ; 3
sta NUM2H ; 4
lda DY_F ; 3
sta NUM2L ; 4
jsr multiply ; 6
lda RESULT+2 ; 4
sta DY_I ; 3
lda RESULT+1 ; 4
sta DY_F ; 3
;==========
; 48
;; brk ASM, dy = 00:73
; calculate the starting position
; fixed_add(&distance,&factor,&space_x);
clc ; fixed_add(&distance,&factor,&space_y);
lda DISTANCE_F
adc FACTOR_F
sta SPACEY_F
sta SPACEX_F
lda DISTANCE_I
adc FACTOR_I
sta SPACEY_I
sta SPACEX_I
; fixed_add(&distance,&factor,&space_x);
clc ; fixed_add(&distance,&factor,&space_y); ; 2
lda DISTANCE_F ; 3
adc FACTOR_F ; 3
sta SPACEY_F ; 3
sta SPACEX_F ; 3
lda DISTANCE_I ; 3
adc FACTOR_I ; 3
sta SPACEY_I ; 3
sta SPACEX_I ; 3
;==========
; 26
;; brk space_x = 06:bc
lda ANGLE ; fixed_temp.i=fixed_sin[(angle+4)&0xf].i; // cos
clc
adc #4
and #$f
asl
tay
lda fixed_sin,Y
sta TEMP_I
iny ; fixed_temp.f=fixed_sin[(angle+4)&0xf].f; // cos
lda fixed_sin,Y
sta TEMP_F
lda ANGLE ; temp.i=fixed_sin[(angle+4)&0xf].i; // cos ; 3
clc ; 2
adc #4 ; 2
and #$f ; 2
asl ; 2
tay ; 2
lda fixed_sin,Y ; 4
sta TEMP_I ; 3
iny ; temp.f=fixed_sin[(angle+4)&0xf].f; // cos ; 2
lda fixed_sin,Y ; 4
sta TEMP_F ; 3
;==========
; 29
; fixed_mul(&space_x,&fixed_temp,&space_x);
lda SPACEX_I
sta NUM1H
lda SPACEX_F
sta NUM1L
lda TEMP_I
sta NUM2H
lda TEMP_F
sta NUM2L
jsr multiply
lda RESULT+2
sta SPACEX_I
lda RESULT+1
sta SPACEX_F
; fixed_mul(&space_x,&temp,&space_x);
lda SPACEX_I ; 3
sta NUM1H ; 4
lda SPACEX_F ; 3
sta NUM1L ; 4
lda TEMP_I ; 3
sta NUM2H ; 4
lda TEMP_F ; 3
sta NUM2L ; 4
jsr multiply ; 6
lda RESULT+2 ; 4
sta SPACEX_I ; 3
lda RESULT+1 ; 4
sta SPACEX_F ; 3
;==========
; 48
clc ; fixed_add(&space_x,&cx,&space_x); ; 2
lda SPACEX_F ; 3
adc CX_F ; 3
sta SPACEX_F ; 3
lda SPACEX_I ; 3
adc CX_I ; 3
sta SPACEX_I ; 3
lda #$ec ; temp.i=0xec; // -20 (LOWRES_W/2) ; 2
sta TEMP_I ; 3
lda #0 ; temp.f=0; ; 2
sta TEMP_F ; 3
;==========
; 30
; fixed_mul(&temp,&dx,&temp);
lda TEMP_I ; 3
sta NUM1H ; 4
lda TEMP_F ; 3
sta NUM1L ; 4
lda DX_I ; 3
sta NUM2H ; 4
lda DX_F ; 3
sta NUM2L ; 4
jsr multiply ; 6
lda RESULT+2 ; 4
sta TEMP_I ; 3
lda RESULT+1 ; 4
sta TEMP_F ; 3
;==========
; 48
clc ; fixed_add(&space_x,&cx,&space_x);
lda SPACEX_F
adc CX_F
sta SPACEX_F
lda SPACEX_I
adc CX_I
sta SPACEX_I
lda #$ec ; fixed_temp.i=0xec; // -20 (LOWRES_W/2)
sta TEMP_I
lda #0 ; fixed_temp.f=0;
sta TEMP_F
; fixed_mul(&fixed_temp,&dx,&fixed_temp);
lda TEMP_I
sta NUM1H
lda TEMP_F
sta NUM1L
lda DX_I
sta NUM2H
lda DX_F
sta NUM2L
jsr multiply
lda RESULT+2
sta TEMP_I
lda RESULT+1
sta TEMP_F
clc ; fixed_add(&space_x,&fixed_temp,&space_x);
lda SPACEX_F
adc TEMP_F
sta SPACEX_F
lda SPACEX_I
adc TEMP_I
sta SPACEX_I
;;brk ;; brk space_x = 06:bc
lda ANGLE ; fixed_temp.i=fixed_sin[angle&0xf].i;
and #$f
asl
tay
lda fixed_sin,Y
sta TEMP_I
iny ; fixed_temp.f=fixed_sin[angle&0xf].f;
lda fixed_sin,Y
sta TEMP_F
clc ; fixed_add(&space_x,&temp,&space_x); ; 2
lda SPACEX_F ; 3
adc TEMP_F ; 3
sta SPACEX_F ; 3
lda SPACEX_I ; 3
adc TEMP_I ; 3
sta SPACEX_I ; 3
;==========
; 20
; brk ; space_x = 06:bc
lda ANGLE ; temp.i=fixed_sin[angle&0xf].i; ; 3
and #$f ; 2
asl ; 2
tay ; 2
lda fixed_sin,Y ; 4
sta TEMP_I ; 3
iny ; fixed_temp.f=fixed_sin[angle&0xf].f; ; 2
lda fixed_sin,Y ; 4
sta TEMP_F ; 3
;==========
; 25
; fixed_mul(&space_y,&fixed_temp,&space_y);
lda SPACEY_I
sta NUM1H
lda SPACEY_F
sta NUM1L
lda TEMP_I
sta NUM2H
lda TEMP_F
sta NUM2L
jsr multiply
lda RESULT+2
sta SPACEY_I
lda RESULT+1
sta SPACEY_F
lda SPACEY_I ; 3
sta NUM1H ; 4
lda SPACEY_F ; 3
sta NUM1L ; 4
lda TEMP_I ; 3
sta NUM2H ; 4
lda TEMP_F ; 3
sta NUM2L ; 4
jsr multiply ; 6
lda RESULT+2 ; 4
sta SPACEY_I ; 3
lda RESULT+1 ; 4
sta SPACEY_F ; 3
;==========
; 48
clc ; fixed_add(&space_y,&cy,&space_y); ; 2
lda SPACEY_F ; 3
adc CY_F ; 3
sta SPACEY_F ; 3
lda SPACEY_I ; 3
adc CY_I ; 3
sta SPACEY_I ; 3
clc ; fixed_add(&space_y,&cy,&space_y);
lda SPACEY_F
adc CY_F
sta SPACEY_F
lda SPACEY_I
adc CY_I
sta SPACEY_I
lda #$ec ; fixed_temp.i=0xec; // -20 (LOWRES_W/2)
sta TEMP_I
lda #0 ; fixed_temp.f=0;
sta TEMP_F
lda #$ec ; temp.i=0xec; // -20 (LOWRES_W/2) ; 2
sta TEMP_I ; 3
lda #0 ; temp.f=0; ; 2
sta TEMP_F ; 3
;==========
; 30
; fixed_mul(&fixed_temp,&dy,&fixed_temp);
lda TEMP_I
sta NUM1H
lda TEMP_F
sta NUM1L
lda DY_I
sta NUM2H
lda DY_F
sta NUM2L
jsr multiply
lda RESULT+2
sta TEMP_I
lda RESULT+1
sta TEMP_F
lda TEMP_I ; 3
sta NUM1H ; 4
lda TEMP_F ; 3
sta NUM1L ; 4
lda DY_I ; 3
sta NUM2H ; 4
lda DY_F ; 3
sta NUM2L ; 4
jsr multiply ; 6
lda RESULT+2 ; 4
sta TEMP_I ; 3
lda RESULT+1 ; 4
sta TEMP_F ; 3
;==========
; 48
clc ; fixed_add(&space_y,&fixed_temp,&space_y); ; 2
lda SPACEY_F ; 3
adc TEMP_F ; 3
sta SPACEY_F ; 3
lda SPACEY_I ; 3
adc TEMP_I ; 3
sta SPACEY_I ; 3
clc ; fixed_add(&space_y,&fixed_temp,&space_y);
lda SPACEY_F
adc TEMP_F
sta SPACEY_F
lda SPACEY_I
adc TEMP_I
sta SPACEY_I
; brk ; space_y = f7:04
;;brk ;; brk space_y = f7:04
lda #0
sta SCREEN_X
lda #0 ; 2
sta SCREEN_X ; 3
;==========
; 25
screenx_loop:
jsr lookup_map ; get color in A
jsr lookup_map ; get color in A ; 6
ldy #0
sta (GBASL),Y ; plot double height
inc GBASL ; point to next pixel
ldy #0 ; 2
sta (GBASL),Y ; plot double height ; 6
inc GBASL ; point to next pixel ; 5
; Check if over water
cmp #$22 ; see if dark blue
bne not_watery
cmp #$22 ; see if dark blue ; 2
bne not_watery ; 2nt/3
lda SCREEN_Y ; only check pixel in middle of screen
cmp #38
bne not_watery
lda SCREEN_Y ; only check pixel in middle of screen ; 3
cmp #38 ; 2
bne not_watery ; 2nt/3
lda SCREEN_X ; only check pixel in middle of screen
cmp #20
bne not_watery
lda #$1 ; set over water
sta OVER_WATER
lda SCREEN_X ; only check pixel in middle of screen ; 3
cmp #20 ; 2
bne not_watery ; 2nt/3
lda #$1 ; set over water ; 2
sta OVER_WATER ; 3
;============
; 42
not_watery:
; advance to the next position in space
clc ; fixed_add(&space_x,&dx,&space_x);
lda SPACEX_F
adc DX_F
sta SPACEX_F
lda SPACEX_I
adc DX_I
sta SPACEX_I
clc ; fixed_add(&space_x,&dx,&space_x); ; 2
lda SPACEX_F ; 3
adc DX_F ; 3
sta SPACEX_F ; 3
lda SPACEX_I ; 3
adc DX_I ; 3
sta SPACEX_I ; 3
clc ; fixed_add(&space_y,&dy,&space_y);
lda SPACEY_F
adc DY_F
sta SPACEY_F
lda SPACEY_I
adc DY_I
sta SPACEY_I
clc ; fixed_add(&space_y,&dy,&space_y); ; 2
lda SPACEY_F ; 3
adc DY_F ; 3
sta SPACEY_F ; 3
lda SPACEY_I ; 3
adc DY_I ; 3
sta SPACEY_I ; 3
inc SCREEN_X ; 5
lda SCREEN_X ; 3
cmp #40 ; LOWRES width ; 2
bne screenx_loop ; 2nt/3
;=============
; 53
inc SCREEN_X
lda SCREEN_X
cmp #40 ; LOWRES width
bne screenx_loop
lda SCREEN_Y
clc
adc #2
sta SCREEN_Y
cmp #40 ; LOWRES height
beq done_screeny
jmp screeny_loop
lda SCREEN_Y ; 3
clc ; 2
adc #2 ; 2
sta SCREEN_Y ; 3
cmp #40 ; LOWRES height ; 2
beq done_screeny ; 2nt/3
jmp screeny_loop ; 3
;=============
; 17
done_screeny:
rts
rts ; 6
;====================

View File

@ -15,96 +15,96 @@ NEGATE: .byte 0
multiply:
lda #$0
sta NEGATE
lda #$0 ; 2
sta NEGATE ; 4
; Handle Signed
lda NUM1H
bpl check_num2
lda NUM1H ; 4
bpl check_num2 ; 2nt/3
inc NEGATE
inc NEGATE ; 4
clc
lda NUM1L
eor #$ff
adc #$1
sta NUM1L
clc ; 2s-complement NUM1H/NUM1L ; 2
lda NUM1L ; 4
eor #$ff ; 2
adc #$1 ; 2
sta NUM1L ; 4
lda NUM1H
eor #$ff
adc #$0
sta NUM1H
lda NUM1H ; 4
eor #$ff ; 2
adc #$0 ; 2
sta NUM1H ; 4
check_num2:
lda NUM2H
bpl unsigned_multiply
lda NUM2H ; 4
bpl unsigned_multiply ; 2nt/3
inc NEGATE
inc NEGATE ; 4
clc
lda NUM2L
eor #$ff
adc #$1
sta NUM2L
clc ; 2
lda NUM2L ; 4
eor #$ff ; 2
adc #$1 ; 2
sta NUM2L ; 4
lda NUM2H
eor #$ff
adc #$0
sta NUM2H
lda NUM2H ; 4
eor #$ff ; 2
adc #$0 ; 2
sta NUM2H ; 4
unsigned_multiply:
lda #0 ; Initialize RESULT to 0
sta RESULT+2
ldx #16 ; 16x16 multiply
lda #0 ; Initialize RESULT to 0 ; 2
sta RESULT+2 ; 4
ldx #16 ; 16x16 multiply ; 2
multiply_mainloop:
lsr NUM2H ; Shift right 16-bit NUM2
ror NUM2L ; low bit goes into carry
bcc shift_output ; 0 or 1?
tay ; If 1, add NUM1 (hi byte of RESULT is in A)
clc
lda NUM1L
adc RESULT+2
sta RESULT+2
tya
adc NUM1H
lsr NUM2H ; Shift right 16-bit NUM2 ; 6
ror NUM2L ; low bit goes into carry ; 6
bcc shift_output ; 0 or 1? ; 2nt/3
tay ; If 1, add NUM1 (hi byte RESULT in A) ; 2
clc ; 2
lda NUM1L ; 4
adc RESULT+2 ; 4
sta RESULT+2 ; 4
tya ; 2
adc NUM1H ; 4
shift_output:
ror A ; "Stairstep" shift
ror RESULT+2
ror RESULT+1
ror RESULT
dex
bne multiply_mainloop
sta RESULT+3
ror A ; "Stairstep" shift ; 2
ror RESULT+2 ; 6
ror RESULT+1 ; 6
ror RESULT ; 6
dex ; 2
bne multiply_mainloop ; 2nt/3
sta RESULT+3 ; 4
;; Negate if necessary
lda NEGATE
and #$1
beq positive
lda NEGATE ; 4
and #$1 ; 2
beq positive ; 2nt/3
clc
lda RESULT+0
eor #$ff
adc #$1
sta RESULT+0
clc ; 2
lda RESULT+0 ; 4
eor #$ff ; 2
adc #$1 ; 2
sta RESULT+0 ; 4
lda RESULT+1
eor #$ff
adc #$0
sta RESULT+1
lda RESULT+1 ; 4
eor #$ff ; 2
adc #$0 ; 2
sta RESULT+1 ; 4
lda RESULT+2
eor #$ff
adc #$0
sta RESULT+2
lda RESULT+2 ; 4
eor #$ff ; 2
adc #$0 ; 2
sta RESULT+2 ; 4
lda RESULT+3
eor #$ff
adc #$0
sta RESULT+3
lda RESULT+3 ; 4
eor #$ff ; 2
adc #$0 ; 2
sta RESULT+3 ; 4
positive:
rts
rts ; 6

View File

@ -579,19 +579,20 @@ vlin_too_slow:
; put address in GBASL/GBASH
; Ycoord in A, Xcoord in Y
hlin_setup:
sty TEMPY
tay ; y=A
lda gr_offsets,Y ; lookup low-res memory address
clc
adc TEMPY
sta GBASL
iny
lda gr_offsets,Y
adc DRAW_PAGE ; add in draw page offset
sta GBASH
rts
sty TEMPY ; 3
tay ; y=A ; 2
lda gr_offsets,Y ; lookup low-res memory address ; 4
clc ; 2
adc TEMPY ; 3
sta GBASL ; 3
iny ; 2
lda gr_offsets,Y ; 4
adc DRAW_PAGE ; add in draw page offset ; 3
sta GBASH ; 3
rts ; 6
;===========
; 35
;================================
; hlin_double:
;================================
@ -601,18 +602,16 @@ hlin_setup:
hlin_double:
;int hlin_double(int page, int x1, int x2, int at) {
jsr hlin_setup
jsr hlin_setup ; 41
sec
lda V2
sbc TEMPY
sec ; 2
lda V2 ; 3
sbc TEMPY ; 3
tax
inx
; jsr hlin_double_continue
; rts
tax ; 2
inx ; 2
;===========
; 53
; fallthrough
;=================================
@ -622,16 +621,17 @@ hlin_double:
hlin_double_continue:
ldy #0 ; 2
lda COLOR ; 3
hlin_double_loop:
ldy #0
lda COLOR
sta (GBASL),Y
inc GBASL
dex
bne hlin_double_loop
rts
sta (GBASL),Y ; 6
inc GBASL ; 5
dex ; 2
bne hlin_double_loop ; 2nt/3
rts ; 6
;=============
; 53+5+X*16+5
;================================
; hlin_single: