starbot: so close

This commit is contained in:
Vince Weaver 2021-06-12 11:37:42 -04:00
parent 01aa12e0f1
commit bdf64d1d2d
3 changed files with 413 additions and 119 deletions

View File

@ -12,13 +12,16 @@ all: starfield.dsk
$(DOS33):
cd ../../../utils/dos33fs-utils && make
starfield.dsk: $(DOS33) HELLO STARFIELD_DEMO STARFIELD_1K STARFIELD.BAS STARSMALL
starfield.dsk: $(DOS33) HELLO STARFIELD_DEMO STARFIELD_1K STARFIELD.BAS \
STARSMALL STARBOT STARBOT_LOOKUP
cp $(EMPTY_DISK)/empty.dsk starfield.dsk
$(DOS33) -y starfield.dsk SAVE A HELLO
$(DOS33) -y starfield.dsk SAVE A STARFIELD.BAS
$(DOS33) -y starfield.dsk BSAVE -a 0x1000 STARFIELD_DEMO
$(DOS33) -y starfield.dsk BSAVE -a 0x1000 STARFIELD_1K
$(DOS33) -y starfield.dsk BSAVE -a 0xc00 STARSMALL
$(DOS33) -y starfield.dsk BSAVE -a 0xc00 STARBOT_LOOKUP
$(DOS33) -y starfield.dsk BSAVE -a 0xc00 STARBOT
###
@ -63,6 +66,22 @@ STARSMALL: starsmall.o
starsmall.o: starsmall.s
ca65 -o starsmall.o starsmall.s -l starsmall.lst
###
STARBOT: starbot.o
ld65 -o STARBOT starbot.o -C $(LINKERSCRIPTS)/apple2_c00.inc
starbot.o: starbot.s
ca65 -o starbot.o starbot.s -l starbot.lst
###
STARBOT_LOOKUP: starbot_lookup.o
ld65 -o STARBOT_LOOKUP starbot_lookup.o -C $(LINKERSCRIPTS)/apple2_c00.inc
starbot_lookup.o: starbot_lookup.s
ca65 -o starbot_lookup.o starbot_lookup.s -l starbot_lookup.lst
###

View File

@ -11,9 +11,14 @@
; 170 bytes - can do sty zp,x
; 163 bytes - lose the cool HGR intro
; 161 bytes - re-arrange RNG location
; 158 bytes - ra-arrange a lot to remove need for XX
; 133 bytes -- undo opt, no lookup table, just raw divide
; 145 bytes -- init stars at beginning, so don't initially run bacward if Z=FF
; 135 bytes -- optimize divide some more
COLOR = $30
NEGATIVE = $F9
QUOTIENT = $FA
DIVISOR = $FB
DIVIDEND = $FC
@ -21,11 +26,12 @@ XX = $FD
YY = $FE
FRAME = $FF
oldx = $80
oldy = $90
star_x = $A0
star_y = $B0
star_z = $C0
star_z = $60
oldx = $70
oldy = $80
star_x = $90
star_y = $A0
;oldx = $1000
;oldy = $1040
@ -39,6 +45,8 @@ LORES = $C056 ; Enable LORES graphics
HGR2 = $F3D8
HGR = $F3E2
PLOT = $F800 ; PLOT AT Y,A (A colors output, Y preserved)
NEXTCOL = $F85F
SETCOL = $F864 ; COLOR=A
SETGR = $FB40
WAIT = $FCA8 ; delay 1/2(26+27A+5A^2) us
@ -46,59 +54,7 @@ small_starfield:
;0GR:DIMV(64,48):FORZ=1TO48:FORX=0TO64:V(X,Z)=(X*4-128)/Z+20:NEXTX,Z
jsr SETGR
; init the X/Z tables
ldy #63 ; Y==z for(z=1;z<64;z++) {
xloop:
ldx #0 ; X==x
zloop:
lda #$ff
sta QUOTIENT
; stx DIVIDEND
sty DIVISOR
txa ; DIVIDEND
div_loop:
inc QUOTIENT
sec
; lda DIVIDEND
sbc DIVISOR
; sta DIVIDEND
bpl div_loop
; write out quotient
lda QUOTIENT
pha
clc
adc #20
to_smc:
sta $5F80,X
inx
bpl zloop ; loop until 128
; reverse and write out negative parts
ldx #0
negative_loop:
pla
eor #$ff
sec
adc #20
to2_smc:
sta $5F00,X
inx
bpl negative_loop
dec to_smc+2
dec to2_smc+2
dey
bne xloop
jsr SETGR ; A is D0 after?
;===================================
; draw the stars
@ -107,6 +63,14 @@ to2_smc:
; bit LORES
; jsr SETGR
; tax
ldx #15
make_orig_stars:
jsr make_new_star
dex
bpl make_orig_stars
;===================================
; starloop
@ -115,49 +79,8 @@ big_loop:
ldx #15
star_loop:
;==============================
; get X/Z
; X=V(A(P),Z(P))
; position Z
lda star_z,X
clc
adc #$20 ; tables in $20-$5F
sta xload_smc+2
sta xload2_smc+2
; get XX
ldy star_x,X
xload_smc:
lda $5F00,Y
sta XX
bmi new_star ; if <0
cmp #40
bcs new_star ; bge >40
;==============================
; get Y/Z
; Y=V(B(P),Z(P))
; get YY
ldy star_y,X
xload2_smc:
lda $5F00,Y
sta YY
bmi new_star ; if <0
cmp #40
bcs new_star ; bge >39
;Z(P)=Z(P)-1
dec star_z,X
beq new_star ; if Z=0 new star
; draw the star
draw_star:
;===================
; erase old
;4 COLOR=0
lda #$00
@ -169,23 +92,107 @@ draw_star:
lda oldy,X
jsr PLOT ; PLOT AT Y,A
;===========================
; position Z
; lda star_z,X
; beq new_star ; should never happen
; sta DIVISOR
; DIVISOR always star_z,X
;==============================
; get Y/Z
; Y=V(B(P),Z(P))
; get YY
lda star_y,X ; get Y of star
jsr do_divide
sta YY ; YY
bmi new_star ; if <0
cmp #40
bcs new_star ; bge >39
;==============================
; get X/Z
; X=V(A(P),Z(P))
; get XX
lda star_x,X ; get X of start
jsr do_divide
; sta XX
tay
bmi new_star ; if <0
cpy #40
bcs new_star ; bge >40
;========================
; adjust Z
;Z(P)=Z(P)-1
dec star_z,X
beq new_star ; if Z=0 new star
; draw the star
draw_star:
; COLOR=15
dec COLOR
dec COLOR ; color from $00 (black) to $ff (white)
txa
ror
bcs not_far
jsr NEXTCOL
; ror
; jsr NEXTCOL
; lda #$55
; sta COLOR ; FF -> 7F
not_far:
;PLOT X,Y
; O(P)=X:Q(P)=Y
ldy XX
sty oldx,X
; ldy XX ; XX already in Y
sty oldx,X ; save for next time to erase
lda YY
sta oldy,X
lda YY ; YY
sta oldy,X ; ;save for next time to erase
jsr PLOT ; PLOT AT Y,A
; a should be F0 or 0F here?
bne done_star
; a should be F0/20 or 0F/02 here?
bne done_star ; bra
new_star:
jsr make_new_star ;
done_star:
;7NEXT
dex
bpl star_loop
lda #120
jsr WAIT ; A is 0 after
; GOTO2
beq big_loop ; bra
;===========================
; NEW STAR
;===========================
make_new_star:
;IFX<0ORX>39ORY<0ORY>39ORZ(P)<1THEN
; A(P)=RND(1)*64
; B(P)=RND(1)*64
@ -195,7 +202,8 @@ new_star:
lda $F000,Y
sta star_x,X ; random XX
lda $F001,Y
color_lookup:
lda $F100,Y
sta star_y,X ; random YY
lda $F002,Y
@ -205,21 +213,53 @@ new_star:
inc FRAME
rts
done_star:
;7NEXT
;=============================
; do divide
;=============================
; Z is in divisor
; x/y is in A
dex
bpl star_loop
do_divide:
; A was just loaded so flags still valid
php
bpl not_negative
lda #100
jsr WAIT ; A is 0 after
eor #$ff
clc
adc #1 ; invert
not_negative:
ldy #$ff ; QUOTIENT
div_loop:
iny ; inc QUOTIENT
sec
sbc star_z,X ; DIVIDEND=DIVIDEND-DIVISOR
bpl div_loop
; write out quotient
tya ; lda QUOTIENT
plp
bpl pos_add
eor #$ff
sec
bcs do_add
pos_add:
clc
do_add:
adc #20
early_out:
rts
; GOTO2
beq big_loop ; bra
; for BASIC bot load
; need this to be at $3F5
; it's at 8A, so 6B
jmp small_starfield

View File

@ -0,0 +1,235 @@
; starfield tiny -- Apple II Lores
; by Vince `deater` Weaver
; actually too fast
; 189 bytes - original
; 184 bytes - move DIVIDEND to A
; 173 bytes - move variables to 0 page. limits to 16 stars but that's fine?
; 171 bytes - adjust random # generator
; 170 bytes - can do sty zp,x
; 163 bytes - lose the cool HGR intro
; 161 bytes - re-arrange RNG location
; 158 bytes - ra-arrange a lot to remove need for XX
COLOR = $30
QUOTIENT = $FA
DIVISOR = $FB
DIVIDEND = $FC
XX = $FD
YY = $FE
FRAME = $FF
oldx = $80
oldy = $90
star_x = $A0
star_y = $B0
star_z = $C0
;oldx = $1000
;oldy = $1040
;star_x = $2000 ; should be 0, not used as we never /0
;star_y = $2040
;star_z = $2080
LORES = $C056 ; Enable LORES graphics
HGR2 = $F3D8
HGR = $F3E2
PLOT = $F800 ; PLOT AT Y,A (A colors output, Y preserved)
SETGR = $FB40
WAIT = $FCA8 ; delay 1/2(26+27A+5A^2) us
small_starfield:
;0GR:DIMV(64,48):FORZ=1TO48:FORX=0TO64:V(X,Z)=(X*4-128)/Z+20:NEXTX,Z
jsr SETGR
; init the X/Z tables
ldy #63 ; Y==z for(z=1;z<64;z++) {
xloop:
ldx #0 ; X==x
zloop:
lda #$ff
sta QUOTIENT
; stx DIVIDEND
sty DIVISOR
txa ; DIVIDEND
div_loop:
inc QUOTIENT
sec
; lda DIVIDEND
sbc DIVISOR
; sta DIVIDEND
bpl div_loop
; write out quotient
lda QUOTIENT
pha
clc
adc #20
to_smc:
sta $5F80,X
inx
bpl zloop ; loop until 128
; reverse and write out negative parts
ldx #0
negative_loop:
pla
eor #$ff
sec
adc #20
to2_smc:
sta $5F00,X
inx
bpl negative_loop
dec to_smc+2
dec to2_smc+2
dey
bne xloop
;===================================
; draw the stars
;===================================
; bit LORES
; jsr SETGR
;===================================
; starloop
;2FORP=0TO5
big_loop:
ldx #15
star_loop:
;===================
; erase old
;4 COLOR=0
lda #$00
sta COLOR
;PLOT O(P),Q(P)
ldy oldx,X
lda oldy,X
jsr PLOT ; PLOT AT Y,A
;===========================
; position Z
lda star_z,X
clc
adc #$20 ; tables in $20-$5F
sta xload_smc+2
sta xload2_smc+2
;==============================
; get Y/Z
; Y=V(B(P),Z(P))
; get YY
ldy star_y,X ; get Y of star
xload2_smc:
lda $5F00,Y ; lookup Y/Z
sta YY ; YY
bmi new_star ; if <0
cmp #40
bcs new_star ; bge >39
;==============================
; get X/Z
; X=V(A(P),Z(P))
; get XX
ldy star_x,X ; get X of start
xload_smc:
lda $5F00,Y ; lookup X/Z
tay ; XX
bmi new_star ; if <0
cpy #40
bcs new_star ; bge >40
;========================
; adjust Z
;Z(P)=Z(P)-1
dec star_z,X
beq new_star ; if Z=0 new star
; draw the star
draw_star:
; COLOR=15
dec COLOR ; color from $00 (black) to $ff (white)
;PLOT X,Y
; O(P)=X:Q(P)=Y
; ldy XX ; XX already in Y
sty oldx,X ; save for next time to erase
lda YY ; YY
sta oldy,X ; ;save for next time to erase
jsr PLOT ; PLOT AT Y,A
; a should be F0 or 0F here?
bne done_star ; bra
new_star:
;IFX<0ORX>39ORY<0ORY>39ORZ(P)<1THEN
; A(P)=RND(1)*64
; B(P)=RND(1)*64
; Z(P)=RND(1)*48+1:GOTO7
ldy FRAME
lda $F000,Y
sta star_x,X ; random XX
lda $F001,Y
sta star_y,X ; random YY
lda $F002,Y
and #$3f ; random ZZ 0..63
ora #$1 ; avoid 0
sta star_z,X
inc FRAME
done_star:
;7NEXT
dex
bpl star_loop
lda #100
jsr WAIT ; A is 0 after
; GOTO2
beq big_loop ; bra
; for BASIC bot load
; need this to be at $3F5
jmp small_starfield