prog8/examples/c64/plasma.p8

131 lines
3.5 KiB
Plaintext
Raw Normal View History

%import syslib
%import textio
%import math
2020-08-21 14:53:56 +00:00
; converted from plasma test program for cc65.
; which is (w)2001 by groepaz/hitmen
;
; Cleanup and porting to C by Ullrich von Bassewitz.
2023-09-04 18:19:04 +00:00
; See https://github.com/cc65/cc65/tree/master/samples/cbm/plasma.c
;
; Converted to prog8 by Irmen de Jong.
2020-08-21 14:53:56 +00:00
2020-11-03 20:31:08 +00:00
2020-08-21 14:53:56 +00:00
main {
const uword SCREEN1 = $E000
const uword SCREEN2 = $E400
const uword CHARSET = $E800
const ubyte PAGE1 = ((SCREEN1 >> 6) & $F0) | ((CHARSET >> 10) & $0E)
const ubyte PAGE2 = ((SCREEN2 >> 6) & $F0) | ((CHARSET >> 10) & $0E)
sub start() {
txt.color(1)
2022-04-02 15:53:24 +00:00
txt.clear_screen()
2023-09-04 18:19:04 +00:00
txt.print("creating charset...\n\nwhile running, press key to stop.\n\n")
2020-08-21 14:53:56 +00:00
makechar()
ubyte block = c64.CIA2PRA
2023-09-04 18:19:04 +00:00
ubyte v = c64.VMCSB
2020-08-21 14:53:56 +00:00
c64.CIA2PRA = (block & $FC) | (lsb(SCREEN1 >> 14) ^ $03)
2023-09-04 18:19:04 +00:00
uword frames = 0
cbm.SETTIM(0,0,0)
while cbm.GETIN()==0 {
2020-08-21 14:53:56 +00:00
doplasma(SCREEN1)
c64.VMCSB = PAGE1
doplasma(SCREEN2)
c64.VMCSB = PAGE2
2023-09-04 18:19:04 +00:00
frames += 2
2020-08-21 14:53:56 +00:00
}
2020-08-21 15:44:44 +00:00
2023-09-04 18:19:04 +00:00
uword jiffies = cbm.RDTIM16()
; restore screen and displays stats
c64.VMCSB = v
c64.CIA2PRA = block
txt.print("time in jiffies: ")
txt.print_uw(jiffies)
txt.print("\nframes: ")
txt.print_uw(frames)
uword fps = (frames*60)/jiffies
txt.print("\nfps: ")
txt.print_uw(fps)
txt.print("\ndone!\n")
repeat {
}
2020-08-21 14:53:56 +00:00
}
; several variables outside of doplasma to make them retain their value
ubyte c1A
ubyte c1B
ubyte c2A
ubyte c2B
2023-09-04 18:19:04 +00:00
sub doplasma(uword @zp screen) {
2020-08-21 14:53:56 +00:00
ubyte[40] xbuf
ubyte[25] ybuf
ubyte c1a = c1A
ubyte c1b = c1B
ubyte c2a = c2A
ubyte c2b = c2B
2020-08-21 15:44:44 +00:00
ubyte @zp x
ubyte @zp y
2020-08-21 14:53:56 +00:00
2020-08-24 22:35:51 +00:00
for y in 24 downto 0 {
ybuf[y] = math.sin8u(c1a) + math.sin8u(c1b)
2020-08-21 14:53:56 +00:00
c1a += 4
c1b += 9
}
c1A += 3
c1B -= 5
2020-08-24 22:35:51 +00:00
for x in 39 downto 0 {
xbuf[x] = math.sin8u(c2a) + math.sin8u(c2b)
2020-08-21 14:53:56 +00:00
c2a += 3
c2b += 7
}
c2A += 2
c2B -= 3
2020-08-24 22:35:51 +00:00
for y in 24 downto 0 {
for x in 39 downto 0 {
2023-09-04 18:19:04 +00:00
; split the array expression to avoid a prog8 temporary var inefficiency
; this pure prog8 version achieves ~17 fps
ubyte @zp tmp = ybuf[y]
@(screen+x) = xbuf[x] + tmp
; prog8 at this time needs a temp variable to calculate the above expression.
; in optimized asm, this is the fastest way to do this line (achieving ~21 fps on the C64):
2020-08-24 22:59:02 +00:00
; %asm {{
2023-09-04 18:19:04 +00:00
; ldy p8_y
; lda p8_ybuf,y
; ldy p8_x
2020-08-24 22:59:02 +00:00
; clc
2023-09-04 18:19:04 +00:00
; adc p8_xbuf,y
; sta (p8_screen),y
2020-08-24 22:59:02 +00:00
; }}
}
screen += 40
2020-08-21 14:53:56 +00:00
}
}
sub makechar() {
ubyte[8] bittab = [ $01, $02, $04, $08, $10, $20, $40, $80 ]
ubyte c
for c in 0 to 255 {
2023-09-04 18:19:04 +00:00
ubyte @zp s = math.sin8u(c) ; chance
2020-08-21 14:53:56 +00:00
ubyte i
2023-09-04 18:19:04 +00:00
; for all the pixels in the 8x8 character grid, determine (with a rnd chance) if they should be on or off
2020-08-21 14:53:56 +00:00
for i in 0 to 7 {
ubyte b=0
ubyte @zp ii
for ii in 0 to 7 {
2023-09-04 18:19:04 +00:00
if math.rnd() > s
2020-08-21 14:53:56 +00:00
b |= bittab[ii]
}
@(CHARSET + i + c*$0008) = b
2020-08-21 14:53:56 +00:00
}
}
}
}