hgr: work on circles

This commit is contained in:
Vince Weaver 2021-06-18 00:36:44 -04:00
parent a4d51c5fd1
commit d673644e53
4 changed files with 271 additions and 266 deletions

View File

@ -7,7 +7,7 @@ EMPTY_DISK = ../../../empty_disk
all: circles.dsk
circles.dsk: HELLO CIRCLES \
circles.dsk: HELLO CIRCLES ARCS \
BRES.BAS BRESBOT.BAS BRESCOOL.BAS \
MID.BAS MIDBOT.BAS MIDCOOL.BAS
cp $(EMPTY_DISK)/empty.dsk circles.dsk
@ -19,6 +19,7 @@ circles.dsk: HELLO CIRCLES \
$(DOS33) -y circles.dsk SAVE A MIDBOT.BAS
$(DOS33) -y circles.dsk SAVE A MIDCOOL.BAS
$(DOS33) -y circles.dsk BSAVE -a 0x0C00 CIRCLES
$(DOS33) -y circles.dsk BSAVE -a 0x0C00 ARCS
###
@ -67,7 +68,16 @@ circles.o: circles.s
###
ARCS: arcs.o
ld65 -o ARCS arcs.o -C $(LINKER_SCRIPTS)/apple2_c00.inc
arcs.o: arcs.s
ca65 -o arcs.o arcs.s -l arcs.lst
###
clean:
rm -f *~ *.o *.lst CIRCLES \
rm -f *~ *.o *.lst CIRCLES ARCS \
BRES.BAS BRESBOT.BAS BRESCOOL.BAS \
MID.BAS MIDBOT.BAS MIDCOOL.BAS

141
graphics/hgr/circles/arcs.s Normal file
View File

@ -0,0 +1,141 @@
; circles tiny -- Apple II Hires
; D0+ used by HGR routines
HGR_COLOR = $E4
HGR_PAGE = $E6
D = $F9
XX = $FA
YY = $FB
R = $FC
CX = $FD
CY = $FE
FRAME = $FF
; soft-switches
; ROM routines
HGR2 = $F3D8 ; set hires page2 and clear $4000-$5fff
HGR = $F3E2 ; set hires page1 and clear $2000-$3fff
HPLOT0 = $F457 ; plot at (Y,X), (A)
HCOLOR1 = $F6F0 ; set HGR_COLOR to value in X
COLORTBL = $F6F6
PLOT = $F800 ; PLOT AT Y,A (A colors output, Y preserved)
NEXTCOL = $F85F ; COLOR=COLOR+3
SETCOL = $F864 ; COLOR=A
SETGR = $FB40 ; set graphics and clear LO-RES screen
BELL2 = $FBE4
WAIT = $FCA8 ; delay 1/2(26+27A+5A^2) us
circles:
jsr HGR2
draw_next:
inc FRAME
ldy FRAME
; Random Color
; HCOLOR=1+RND(1)*7
lda $F000,Y
and #$7 ; mask to 0...7
tax
lda COLORTBL,X
sta HGR_COLOR
; CX
lda $F100,Y
and #$7f
sta CX
clc
adc #$40
; CY
lda $F100,Y
and #$7f
sta CY
clc
adc #$40
; R
lda $F100,Y
and #$3f
sta R
; A=40+RND(1)*200:B=40+RND(1)*100:Y=RND(1)*40
; 3X=0:D=3-2*Y:GOTO6
lda #0
sta XX
lda R
asl
sta YY
lda #3
sec
sbc YY
sta D
circle_loop:
; X=X+1
inc XX
; IF D>0 THEN Y=Y-1:D=D+4*(X-Y)+10
lda D
bmi else
dec YY
lda XX
sec
sbc YY
asl
asl
clc
adc D
adc #10
jmp store_D
else:
; ELSE D=D+4*X+6
lda XX
asl
asl
clc
adc D
adc #6
store_D:
sta D
; HPLOT CX+X,CY+Y
lda CX
clc
adc XX
tax
ldy #0
lda CY
clc
adc YY
jsr HPLOT0 ; plot at (Y,X), (A)
; HPLOT CX-X,CY+Y
; HPLOT CX+X,CY-Y
; HPLOT CX-X,CY-Y
; HPLOT CX+Y,CY+X
; HPLOT CX-Y,CY+X
; HPLOT CX+Y,CY-X
; HPLOT CX-Y,CY-X
; IFY>=XTHEN4
lda YY
cmp XX
bcs circle_loop
; GOTO1
bcc draw_next

View File

@ -1,42 +1,17 @@
; starfield tiny -- Apple II Hires
; circles tiny -- Apple II Hires
; by Vince `deater` Weaver
; 139 bytes -- lores version
; 157 bytes -- initial hires
; 155 bytes -- scale to more of full screen
; 153 bytes -- blue/orange instead of purple/green
; 149 bytes -- optimize 2nd plot arg shuffling
; 148 bytes -- optimize 1st plot arg shuffling
; 140 bytes -- turn off all range checking except Z
NUMSTARS = 27 ; 27 good, 28+ not work ($1C)
; zero page locations
star_z = $00
HGR_BITS = $1C
; 1C-40 has some things used by hires
oldx = $50
oldy = $70
star_x = $90
star_y = $B0
; D0+ used by HGR routines
HGR_COLOR = $E4
HGR_PAGE = $E6
SAVEX = $F8
TEMP = $F9
QUOTIENT = $FA
DIVISOR = $FB
DIVIDEND = $FC
XX = $FD
YY = $FE
D = $F9
XX = $FA
YY = $FB
R = $FC
CX = $FD
CY = $FE
FRAME = $FF
; soft-switches
@ -47,6 +22,7 @@ HGR2 = $F3D8 ; set hires page2 and clear $4000-$5fff
HGR = $F3E2 ; set hires page1 and clear $2000-$3fff
HPLOT0 = $F457 ; plot at (Y,X), (A)
HCOLOR1 = $F6F0 ; set HGR_COLOR to value in X
COLORTBL = $F6F6
PLOT = $F800 ; PLOT AT Y,A (A colors output, Y preserved)
NEXTCOL = $F85F ; COLOR=COLOR+3
SETCOL = $F864 ; COLOR=A
@ -54,246 +30,112 @@ SETGR = $FB40 ; set graphics and clear LO-RES screen
BELL2 = $FBE4
WAIT = $FCA8 ; delay 1/2(26+27A+5A^2) us
small_starfield:
circles:
;0GR:DIMV(64,48):FORZ=1TO48:FORX=0TO64:V(X,Z)=(X*4-128)/Z+20:NEXTX,Z
jsr HGR2 ; A is ? after
;===================================
; draw the stars
;===================================
; there are ways to skip this, but on real hardware there's
; no guarantee star_z will be in a valid state, so waste the bytes
ldx #NUMSTARS
make_orig_stars:
jsr make_new_star
dex
bpl make_orig_stars
;===================================
; starloop
;2FORP=0TO15
big_loop:
ldx #NUMSTARS
; really tried hard not to have to set this value
; hard to judge best value for this
; lda #100
; jsr WAIT
ldy #80
jsr BELL2 ; BEEP delays too
; A now 0
star_loop:
; X=FF
;===================
; erase old star
;4 COLOR=0
lda #$00 ; color to black
sta HGR_COLOR ; set HGR_COLOR to value in X
;HPLOT O(P),Q(P)
stx SAVEX
lda oldy,X
pha
lda oldx,X ; get X valu into Y
tax
pla
ldy #0
jsr HPLOT0 ; plot at (Y,X), (A)
ldx SAVEX
;===========================
; position Z
; lda star_z,X
; beq new_star ; should never happen
; sta DIVISOR
; DIVISOR always star_z,X so can hard code this in divide routine
;==============================
; get Y/Z
; Y=V(B(P),Z(P))
; get YY
lda star_y,X ; get Y of star
jsr do_divide
adc #96
; if off-screen then need new star
; cmp #192
; bcs new_star ; bge >39
; cmp #0
; bcc new_star ; if <0
sta YY ; YY
sta oldy,X ; ;save for next time to erase
;==============================
; get X/Z
; X=V(A(P),Z(P))
; get XX
lda star_x,X ; get X of start
jsr do_divide
adc #140 ; center
tay ; put XX in Y
sty oldx,X ; save for next time to erase
; if offscreen then draw new star
; 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:
; lda #$7f ; white (with green/purple highlights)
; sta HGR_COLOR ; set HGR_COLOR to value in X
dec HGR_COLOR ; smaller, but blue/orange highlights
;===========================
; actually plot the star
;HPLOT X,Y
; O(P)=X:Q(P)=Y
stx SAVEX
tya ; XX in Y
tax ; XX now in X
lda YY ; YY
ldy #0
jsr HPLOT0 ; plot at (Y,X), (A)
ldx SAVEX
jmp done_star ; bra
new_star:
jsr make_new_star ;
done_star:
;7NEXT
dex
bpl star_loop
; GOTO2
bmi 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
; Z(P)=RND(1)*48+1:GOTO7
ldy FRAME
lda $F000,Y
sta star_x,X ; random XX
color_lookup:
lda $F100,Y
sta star_y,X ; random YY
lda $F002,Y
and #$1f ; random ZZ 0..127 (can't go negative or stars move backward)
ora #$1 ; avoid 0
sta star_z,X
jsr HGR2
draw_next:
inc FRAME
ldy FRAME
rts
; Random Color
; HCOLOR=1+RND(1)*7
lda $F000,Y
and #$7 ; mask to 0...7
tax
lda COLORTBL,X
sta HGR_COLOR
;=============================
; do signed divide
; the signed part is the pain
;=============================
; Z is in divisor
; x/y is in A
do_divide:
; A was just loaded so flags still valid
php
bpl not_negative
eor #$ff ; make positive for division
clc ; is this necessary?
adc #1
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 ; FIXME: made math inaccurate to save room
; bcs do_add
pos_add:
; CX
lda $F100,Y
and #$7f
sta CX
clc
do_add:
adc #$40
; CY
lda $F100,Y
and #$7f
sta CY
clc
adc #$40
early_out:
rts
; R
lda $F100,Y
and #$3f
sta R
; A=40+RND(1)*200:B=40+RND(1)*100:Y=RND(1)*40
; for BASIC bot load
; 3X=0:D=3-2*Y:GOTO6
lda #0
sta XX
; need this to be at $3F5
; it's at 89, so 6C
jmp small_starfield
lda R
asl
sta YY
lda #3
sec
sbc YY
sta D
circle_loop:
; X=X+1
inc XX
; IF D>0 THEN Y=Y-1:D=D+4*(X-Y)+10
lda D
bmi else
dec YY
lda XX
sec
sbc YY
asl
asl
clc
adc D
adc #10
jmp store_D
else:
; ELSE D=D+4*X+6
lda XX
asl
asl
clc
adc D
adc #6
store_D:
sta D
; HPLOT CX+X,CY+Y
lda CX
clc
adc XX
tax
ldy #0
lda CY
clc
adc YY
jsr HPLOT0 ; plot at (Y,X), (A)
; HPLOT CX-X,CY+Y
; HPLOT CX+X,CY-Y
; HPLOT CX-X,CY-Y
; HPLOT CX+Y,CY+X
; HPLOT CX-Y,CY+X
; HPLOT CX+Y,CY-X
; HPLOT CX-Y,CY-X
; IFY>=XTHEN4
lda YY
cmp XX
bcs circle_loop
; GOTO1
bcc draw_next

View File

@ -0,0 +1,12 @@
MEMORY {
ZP: start = $00, size = $1A, type = rw;
RAM: start = $370, size = $8E00, file = %O;
}
SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
}