gr: some more graphics work

This commit is contained in:
Vince Weaver 2021-02-28 22:22:14 -05:00
parent bc976718a5
commit dbeb4a5388
7 changed files with 451 additions and 73 deletions

View File

@ -6,10 +6,11 @@ LINKERSCRIPTS = ../../../linker_scripts
all: plasma.dsk all: plasma.dsk
plasma.dsk: HELLO PLASMA PLASMA_TINY PLASMA_BOT WIRES WIRES_BOT plasma.dsk: HELLO PLASMA PLASMA_128 PLASMA_TINY PLASMA_BOT WIRES WIRES_BOT
cp empty.dsk plasma.dsk cp empty.dsk plasma.dsk
$(DOS33) -y plasma.dsk SAVE A HELLO $(DOS33) -y plasma.dsk SAVE A HELLO
$(DOS33) -y plasma.dsk BSAVE -a 0x300 PLASMA $(DOS33) -y plasma.dsk BSAVE -a 0x70 PLASMA
$(DOS33) -y plasma.dsk BSAVE -a 0x70 PLASMA_128
$(DOS33) -y plasma.dsk BSAVE -a 0xC00 PLASMA_TINY $(DOS33) -y plasma.dsk BSAVE -a 0xC00 PLASMA_TINY
$(DOS33) -y plasma.dsk BSAVE -a 0x36B PLASMA_BOT $(DOS33) -y plasma.dsk BSAVE -a 0x36B PLASMA_BOT
$(DOS33) -y plasma.dsk BSAVE -a 0xC00 WIRES $(DOS33) -y plasma.dsk BSAVE -a 0xC00 WIRES
@ -23,13 +24,22 @@ HELLO: hello.bas
### ###
PLASMA: plasma.o PLASMA: plasma.o
ld65 -o PLASMA plasma.o -C $(LINKERSCRIPTS)/apple2_300.inc ld65 -o PLASMA plasma.o -C ./apple2_70_zp.inc
plasma.o: plasma.s plasma.o: plasma.s
ca65 -o plasma.o plasma.s -l plasma.lst ca65 -o plasma.o plasma.s -l plasma.lst
### ###
PLASMA_128: plasma_128.o
ld65 -o PLASMA_128 plasma_128.o -C ./apple2_70_zp.inc
plasma_128.o: plasma_128.s
ca65 -o plasma_128.o plasma_128.s -l plasma_128.lst
###
PLASMA_BOT: plasma_bot.o PLASMA_BOT: plasma_bot.o
ld65 -o PLASMA_BOT plasma_bot.o -C ./apple2_36b.inc ld65 -o PLASMA_BOT plasma_bot.o -C ./apple2_36b.inc
@ -67,4 +77,4 @@ wires_bot.o: wires_bot.s
### ###
clean: clean:
rm -f *~ *.o *.lst PLASMA PLASMA_TINY PLASMA_BOT WIRES WIRES_BOT rm -f *~ *.o *.lst PLASMA PLASMA_128 PLASMA_TINY PLASMA_BOT WIRES WIRES_BOT

View File

@ -0,0 +1,12 @@
MEMORY {
ZP: start = $70, size = $90, type = rw;
RAM: start = $70, 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 = ro;
}

View File

@ -18,13 +18,39 @@
; 141 -- smc DRAW_PAGE ; 141 -- smc DRAW_PAGE
; 139 -- from qkumba, remove php/plp ; 139 -- from qkumba, remove php/plp
; 138 -- from qkumba, remove SAVEX ; 138 -- from qkumba, remove SAVEX
; 133 -- run from zero page
; 132 -- make lookup 8*sin+7
; 131 -- re-arrange sine table
; 128 -- call into PLOT for MASK seting
; 127 -- base YY<<16 by adding smc, not by shifting
; 125 -- realize that the top byte wraps so no need to and
; 124 -- re-arrange code to make an CLC unnecessary
; goal=135 ; urgh lovebyte wants 124 byte (counts header)
.include "zp.inc" ; zero page
.include "hardware.inc" GBASL = $26
GBASH = $27
MASK = $2E
COLOR = $30
;CTEMP = $68
YY = $69
; soft-switches
FULLGR = $C052
PAGE1 = $C054
; ROM routines
PLOT1 = $F80E ;; PLOT at (GBASL),Y (need MASK to be $0f or $f0)
GBASCALC= $F847 ;; take Y-coord/2 in A, put address in GBASL/H ( a trashed, C clear)
SETCOL = $F864 ;; COLOR=A*17
SETGR = $FB40
.zeropage
.globalzp colorlookup,plot_lookup_smc,draw_page_smc,frame_smc,sinetable
CTEMP = $FC
;================================ ;================================
; Clear screen and setup graphics ; Clear screen and setup graphics
@ -42,25 +68,27 @@ plasma:
; we only create a 16x16 texture, which we pattern across 40x48 screen ; we only create a 16x16 texture, which we pattern across 40x48 screen
; I've tried re-optimizing this about 10 different ways
; and it never ends up shorter
create_lookup: create_lookup:
ldy #15
create_yloop:
ldx #15 ldx #15
create_yloop:
ldy #15
create_xloop: create_xloop:
clc sec
lda #15 ; 8+8 (but 15 works better) lda sinetable,X
adc sinetable,X adc sinetable,Y ; 15+sin(x)+sin(y)
adc sinetable,Y
lsr lsr
lookup_smc: lookup_smc:
sta lookup ; always starts at $d00 sta lookup ; always starts at $d00
inc lookup_smc+1 inc lookup_smc+1
dex dey
bpl create_xloop bpl create_xloop
dey dex
bpl create_yloop bpl create_yloop
; X and Y both $FF ; X and Y both $FF
@ -70,34 +98,30 @@ create_lookup_done:
forever_loop: forever_loop:
cycle_colors: cycle_colors:
; cycle colors ; cycle colors
; instead of advancing entire frame, do slightly slower route
; instead now and just incrememnting the frame and doing the
; adjustment at plot time.
; can't do palette rotate on Apple II so faking it here ; increment frame
; just incrementing every entry in texture by 1
; X if $FF when arriving here
; ldx #0
inx ; make X 0
cycle_loop:
inc lookup,X
inx
bne cycle_loop
inc frame_smc+1
; set/flip pages ; set/flip pages
; we want to flip pages and then draw to the offscreen one ; we want to flip pages and then draw to the offscreen one
flip_pages: flip_pages:
; ldx #0 ; x already 0 ; ldy #0
iny ; y is $FF, make it 0
lda draw_page_smc+1 ; DRAW_PAGE lda draw_page_smc+1 ; DRAW_PAGE
beq done_page beq done_page
inx iny
done_page: done_page:
ldy PAGE0,X ; set display page to PAGE1 or PAGE2 ldx PAGE1,Y ; set display page to PAGE1 or PAGE2
eor #$4 ; flip draw page between $400/$800 eor #$4 ; flip draw page between $400/$800
sta draw_page_smc+1 ; DRAW_PAGE sta draw_page_smc+1 ; DRAW_PAGE
@ -109,26 +133,13 @@ done_page:
plot_frame: plot_frame:
ldx #47 ; YY=47 (count backwards) ldx #47 ; YY=47 (count backwards)
plot_yloop: plot_yloop:
txa ; get (y&0xf)<<4 txa ; get YY into A
pha ; save YY pha ; save X for later
asl
asl
asl
asl
sta CTEMP ; save for later
txa ; get Y in accumulator
lsr ; call actually wants Ycoord/2 lsr ; call actually wants Ycoord/2
php ; save C flag for mask handling
ldy #$0f ; setup mask for odd/even line
bcc plot_mask
ldy #$f0 ; needlessly clever, from monitor rom src
plot_mask:
sty MASK
; ugh can't use PLOT trick as it always will draw something ; ugh can't use PLOT trick as it always will draw something
; to PAGE1 even if we don't want to ; to PAGE1 even if we don't want to
@ -141,34 +152,43 @@ draw_page_smc:
adc #0 adc #0
sta GBASH sta GBASH
; increment YY in top nibble of lookup for (yy<<16)+xx
; clc from above, C always 0
lda plot_lookup_smc+1
adc #$10 ; no need to mask as it will oflo and be ignored
sta plot_lookup_smc+1
;========== ;==========
ldy #39 ; XX = 39 (countdown) ldy #39 ; XX = 39 (countdown)
; sets MASK by calling into middle of PLOT routine
; by Y being 39 draw in a spot that gets over-written
plp
jsr $f806
plot_xloop: plot_xloop:
tya ; get x&0xf tya ; get XX & 0x0f
and #$f and #$f
ora CTEMP ; combine with val from earlier
; get ((y&0xf)*16)+x
tax tax
plot_lookup:
; sta plot_lookup_smc+1
plot_lookup_smc: plot_lookup_smc:
lda lookup,X ; load lookup, (y*16)+x lda lookup,X ; load lookup, (YY*16)+XX
; lda lookup ; load lookup, (y*16)+x
clc
frame_smc:
adc #$00 ; add in frame
and #$f and #$f
lsr ; we actually only have 8 colors lsr ; we actually only have 8 colors
tax tax
lda colorlookup,X ; lookup color lda colorlookup,X ; lookup color
sta COLOR ; each nibble should be same sta COLOR ; each nibble should be same
jsr PLOT1 ; plot at GBASL,Y (x co-ord goes in Y) jsr PLOT1 ; plot at GBASL,Y (x co-ord goes in Y)
@ -178,29 +198,28 @@ plot_lookup_smc:
pla ; restore YY pla ; restore YY
tax tax
dex dex
bpl plot_yloop bpl plot_yloop
bmi forever_loop bmi forever_loop
colorlookup: colorlookup:
bw_color_lookup:
; blue ; blue
.byte $55,$22,$66,$77,$ff,$77,$55 ; ,$00 shared w sin table .byte $55,$22,$66,$77,$ff,$77,$55 ; ,$00 shared w sin table
; pink
;.byte $55,$11,$33,$bb,$ff,$bb,$55 ; ,$00 shared w sin table
; this is actually 8*sin(x)
sinetable: sinetable:
.byte $00,$03,$05,$07,$08,$07,$05,$03 ; this is actually (8*sin(x))+7
.byte $00,$FD,$FB,$F9,$F8,$F9,$FB,$FD ; re-arranged so starts with $00 for colorlookup overlap
.byte $00,$FF
HACK: ; use the $0200 here for (HACK),Y addressing?
; in the end no way to get Y set properly
.byte $00,$02,$04
.byte $07,$0A,$0C,$0E,$0F,$0E,$0C,$0A
.byte $07,$04,$02
;colorlookup:
;.byte $00,$00,$05,$05,$07,$07,$0f,$0f
;.byte $07,$07,$06,$06,$02,$02,$05,$05
;.byte $00,$55,$77,$ff,$77,$66,$22,$55
; make lookup happen at page boundary ; make lookup happen at page boundary
.org $d00 .org $200
lookup: lookup:

View File

@ -0,0 +1,221 @@
; do a (hopefully fast) plasma type demo
; 151 -- original
; 137 -- optimize generation
; 136 -- align lookup table so we can index it easier
; 130 -- optimize indexing of lookup
; 126 -- run loops backaward
; 124 -- notice X already 0 before plot
; 131 -- use GBASCALC. much faster, but 7 bytes larger
; 129 -- run loop backwards
; 128 -- set color ourselves
; 127 -- overlap color lookup with sine table
; 119 -- forgot to comment out unused
; 121 -- make it use full screen (40x48)
; 149 -- add page flipping
; 144 -- optimize a bit
; 141 -- smc DRAW_PAGE
; 139 -- from qkumba, remove php/plp
; 138 -- from qkumba, remove SAVEX
; 133 -- run from zero page
; 132 -- make lookup 8*sin+7
; 131 -- re-arrange sine table
; 128 -- call into PLOT for MASK seting
; urgh lovebyte wants 124 byte (counts header)
; zero page
GBASL = $26
GBASH = $27
MASK = $2E
COLOR = $30
CTEMP = $68
; soft-switches
FULLGR = $C052
PAGE0 = $C054
; ROM routines
PLOT1 = $F80E ;; PLOT at (GBASL),Y (need MASK to be $0f or $f0)
GBASCALC= $F847 ;; take Y-coord/2 in A, put address in GBASL/H ( a trashed, C clear)
SETCOL = $F864 ;; COLOR=A*17
SETGR = $FB40
.zeropage
.globalzp sinetable,colorlookup,draw_page_smc
;================================
; Clear screen and setup graphics
;================================
plasma:
jsr SETGR ; set lo-res 40x40 mode
bit FULLGR ; make it 40x48
; color = ( 8.0 + 8*sin(x) + 8.0 + 8*sin(y) )/2
; becomes
; color = ( 16 + (sintable[xx&0xf]) + (sintable[yy&0xf])) / 2;
; we only create a 16x16 texture, which we pattern across 40x48 screen
create_lookup:
ldy #15
create_yloop:
ldx #15
create_xloop:
sec
lda sinetable,X
adc sinetable,Y ; 15+sin(x)+sin(y)
lsr
lookup_smc:
sta lookup ; always starts at $d00
inc lookup_smc+1
dex
bpl create_xloop
dey
bpl create_yloop
; X and Y both $FF
create_lookup_done:
forever_loop:
cycle_colors:
; cycle colors
; can't do palette rotate on Apple II so faking it here
; just incrementing every entry in texture by 1
; X if $FF when arriving here
; ldx #0
inx ; make X 0
cycle_loop:
inc lookup,X
inx
bne cycle_loop
; set/flip pages
; we want to flip pages and then draw to the offscreen one
flip_pages:
; ldx #0 ; x already 0
lda draw_page_smc+1 ; DRAW_PAGE
beq done_page
inx
done_page:
ldy PAGE0,X ; set display page to PAGE1 or PAGE2
eor #$4 ; flip draw page between $400/$800
sta draw_page_smc+1 ; DRAW_PAGE
; plot current frame
; scan whole 40x48 screen and plot each point based on
; lookup table colors
plot_frame:
ldx #47 ; YY=47 (count backwards)
plot_yloop:
txa ; get (y&0xf)<<4
pha ; save YY
asl
asl
asl
asl
sta CTEMP ; save for later
txa ; get Y in accumulator
lsr ; call actually wants Ycoord/2
php ; save C flag for mask handling
; ugh can't use PLOT trick as it always will draw something
; to PAGE1 even if we don't want to
jsr GBASCALC ; point GBASL/H to address in (A is ycoord/2)
; after, A is GBASL, C is clear
lda GBASH ; adjust to be PAGE1/PAGE2 ($400 or $800)
draw_page_smc:
adc #0
sta GBASH
;==========
ldy #39 ; XX = 39 (countdown)
; sets MASK by calling into middle of PLOT routine
; by Y being 39 draw in a spot that gets over-written
plp
jsr $f806
plot_xloop:
tya ; get x&0xf
and #$f
ora CTEMP ; combine with val from earlier
; get ((y&0xf)*16)+x
tax
plot_lookup:
plot_lookup_smc:
lda lookup,X ; load lookup, (y*16)+x
and #$f
lsr ; we actually only have 8 colors
tax
lda colorlookup,X ; lookup color
sta COLOR ; each nibble should be same
jsr PLOT1 ; plot at GBASL,Y (x co-ord goes in Y)
dey
bpl plot_xloop
pla ; restore YY
tax
dex
bpl plot_yloop
bmi forever_loop
colorlookup:
; blue
.byte $55,$22,$66,$77,$ff,$77,$55 ; ,$00 shared w sin table
sinetable:
; this is actually (8*sin(x))+7
; re-arranged so starts with $00 for colorlookup overlap
.byte $00,$FF,$00,$02,$04
.byte $07,$0A,$0C,$0E,$0F,$0E,$0C,$0A
.byte $07,$04,$02
; make lookup happen at page boundary
.org $d00
lookup:

View File

@ -6,11 +6,12 @@ LINKERSCRIPTS = ../../../linker_scripts
all: sier.dsk all: sier.dsk
sier.dsk: HELLO SIER SIER_TINY sier.dsk: HELLO SIER SIER_TINY SIER_64
cp empty.dsk sier.dsk cp empty.dsk sier.dsk
$(DOS33) -y sier.dsk SAVE A HELLO $(DOS33) -y sier.dsk SAVE A HELLO
$(DOS33) -y sier.dsk BSAVE -a 0x36C SIER $(DOS33) -y sier.dsk BSAVE -a 0x36C SIER
$(DOS33) -y sier.dsk BSAVE -a 0x300 SIER_TINY $(DOS33) -y sier.dsk BSAVE -a 0x300 SIER_TINY
$(DOS33) -y sier.dsk BSAVE -a 0x300 SIER_64
### ###
@ -33,8 +34,17 @@ SIER_TINY: sier_tiny.o
sier_tiny.o: sier_tiny.s sier_tiny.o: sier_tiny.s
ca65 -o sier_tiny.o sier_tiny.s -l sier_tiny.lst ca65 -o sier_tiny.o sier_tiny.s -l sier_tiny.lst
###
SIER_64: sier_64.o
ld65 -o SIER_64 sier_64.o -C $(LINKERSCRIPTS)/apple2_300.inc
sier_64.o: sier_64.s
ca65 -o sier_64.o sier_64.s -l sier_64.lst
### ###
clean: clean:
rm -f *~ *.o *.lst HELLO SIER SIER_TINY rm -f *~ *.o *.lst HELLO SIER SIER_TINY SIER_64

View File

@ -0,0 +1,94 @@
; fake sierpinski
; scrolling and colors
; by Vince `deater` Weaver, dSr, Lovebyte 2021
; just plot XX AND YY
; zero page
COLOR = $30
XX = $66
YY = $67
FRAME = $68
;X2 = $69
; soft-switches
FULLGR = $C052
; rom routines
PLOT = $F800 ;; PLOT AT Y,A
PLOT1 = $F80E ;; PLOT at (GBASL),Y (need MASK to be $0f or $f0)
SETCOL = $F864 ;; COLOR=A
SETGR = $FB40
;================================
; Clear screen and setup graphics
;================================
sier:
jsr SETGR ; set lo-res 40x40 mode
bit FULLGR ; make it 40x48
lda #0
sta FRAME
sier_loop:
inc FRAME
ldx #47 ; YY
sier_yloop:
lda #39
sta XX
tay
txa
jsr PLOT ; PLOT AT Y,A
; sets GBASL/GBASH and MASK
sier_xloop:
txa
clc
adc FRAME
; sta X2
; lda XX
; adc FRAME
; and X2
and XX
bne black
; lda #$11 ; red
lda FRAME
lsr
lsr
lsr
lsr
bne not_zero
lda #3
not_zero:
.byte $2C ; bit trick
black:
lda #$00
; sta COLOR
jsr SETCOL
ldy XX
txa
jsr PLOT1 ; PLOT AT (GBASL),Y
dec XX
bpl sier_xloop
dex
bpl sier_yloop
done:
bmi sier_loop

View File

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