mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
irq driven music player example
This commit is contained in:
parent
248e7b808c
commit
3ae2597261
@ -250,6 +250,7 @@ $continueLabel inc $loopLabel+1
|
||||
$endLabel""")
|
||||
}
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||
// TODO: optimize loop code when the length of the array is < 256, don't need a separate counter in such cases
|
||||
val length = decl.arraysize!!.size()!!
|
||||
if(stmt.loopRegister!=null && stmt.loopRegister!= Register.A)
|
||||
throw AssemblyError("can only use A")
|
||||
@ -276,6 +277,7 @@ $counterLabel .byte 0
|
||||
$endLabel""")
|
||||
}
|
||||
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
||||
// TODO: optimize loop code when the length of the array is < 256, don't need a separate counter in such cases
|
||||
val length = decl.arraysize!!.size()!! * 2
|
||||
if(stmt.loopRegister!=null)
|
||||
throw AssemblyError("can't use register to loop over words")
|
||||
|
@ -48,6 +48,9 @@ without having to to index into the stack?
|
||||
Misc
|
||||
^^^^
|
||||
|
||||
Add sort() function that can sort an array (ascending and descending)
|
||||
|
||||
|
||||
Several ideas were discussed on my reddit post
|
||||
https://www.reddit.com/r/programming/comments/alhj59/creating_a_programming_language_and_cross/
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
%import c64utils
|
||||
%zeropage basicsafe
|
||||
|
||||
; TODO implement asm generation for all operation in here
|
||||
|
||||
main {
|
||||
|
||||
byte bb
|
||||
|
74
examples/bdmusic_irq.p8
Normal file
74
examples/bdmusic_irq.p8
Normal file
@ -0,0 +1,74 @@
|
||||
%zeropage basicsafe
|
||||
%import c64lib
|
||||
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
c64scr.print("playing the music from boulderdash,\nmade in 1984 by peter liepa.\n\n")
|
||||
c64utils.set_rasterirq(60) ; enable raster irq
|
||||
}
|
||||
}
|
||||
|
||||
irq {
|
||||
const ubyte waveform = %0001 ; triangle
|
||||
ubyte note_index = 0
|
||||
ubyte delay = 0
|
||||
|
||||
sub irq() {
|
||||
c64.EXTCOL++
|
||||
delay++
|
||||
if delay >= 8 {
|
||||
delay = 0
|
||||
c64.AD1 = %00011010
|
||||
c64.SR1 = %00000000
|
||||
c64.AD2 = %00011010
|
||||
c64.SR2 = %00000000
|
||||
c64.MVOL = 15
|
||||
|
||||
uword note = notes[note_index]
|
||||
note_index++
|
||||
ubyte note1 = lsb(note)
|
||||
ubyte note2 = msb(note)
|
||||
c64.FREQ1 = music_freq_table[note1] ; set lo+hi freq of voice 1
|
||||
c64.FREQ2 = music_freq_table[note2] ; set lo+hi freq of voice 2
|
||||
|
||||
; retrigger voice 1 and 2 ADSR
|
||||
c64.CR1 = waveform <<4 | 0
|
||||
c64.CR2 = waveform <<4 | 0
|
||||
c64.CR1 = waveform <<4 | 1
|
||||
c64.CR2 = waveform <<4 | 1
|
||||
}
|
||||
|
||||
c64.EXTCOL--
|
||||
}
|
||||
|
||||
; details about the boulderdash music can be found here:
|
||||
; https://www.elmerproductions.com/sp/peterb/sounds.html#Theme%20tune
|
||||
|
||||
uword[] notes = [
|
||||
$1622, $1d26, $2229, $252e, $1424, $1f27, $2029, $2730,
|
||||
$122a, $122c, $1e2e, $1231, $202c, $3337, $212d, $3135,
|
||||
$1622, $162e, $161d, $1624, $1420, $1430, $1424, $1420,
|
||||
$1622, $162e, $161d, $1624, $1e2a, $1e3a, $1e2e, $1e2a,
|
||||
$142c, $142c, $141b, $1422, $1c28, $1c38, $1c2c, $1c28,
|
||||
$111d, $292d, $111f, $292e, $0f27, $0f27, $1633, $1627,
|
||||
$162e, $162e, $162e, $162e, $222e, $222e, $162e, $162e,
|
||||
$142e, $142e, $142e, $142e, $202e, $202e, $142e, $142e,
|
||||
$162e, $322e, $162e, $332e, $222e, $322e, $162e, $332e,
|
||||
$142e, $322e, $142e, $332e, $202c, $302c, $142c, $312c,
|
||||
$162e, $163a, $162e, $3538, $222e, $2237, $162e, $3135,
|
||||
$142c, $1438, $142c, $1438, $202c, $2033, $142c, $1438,
|
||||
$162e, $322e, $162e, $332e, $222e, $322e, $162e, $332e,
|
||||
$142e, $322e, $142e, $332e, $202c, $302c, $142c, $312c,
|
||||
$2e32, $292e, $2629, $2226, $2c30, $272c, $2427, $1420,
|
||||
$3532, $322e, $2e29, $2926, $2730, $242c, $2027, $1420
|
||||
]
|
||||
|
||||
uword[] music_freq_table = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
732, 778, 826, 876, 928, 978, 1042, 1100, 1170, 1238, 1312, 1390, 1464, 1556,
|
||||
1652, 1752, 1856, 1956, 2084, 2200, 2340, 2476, 2624, 2780, 2928, 3112, 3304,
|
||||
3504, 3712, 3912, 4168, 4400, 4680, 4952, 5248, 5560, 5856, 6224, 6608, 7008,
|
||||
7424, 7824, 8336, 8800, 9360, 9904, 10496, 11120, 11712
|
||||
]
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
%import c64lib
|
||||
%import c64utils
|
||||
|
||||
; TODO: some optimizer breaks this.. the 3d sorting seems broken? or maybe more? runs fine without optimization
|
||||
; TODO: some optimizer breaks this.. runs fine without optimization
|
||||
|
||||
spritedata $2000 {
|
||||
; this memory block contains the sprite data
|
||||
@ -102,12 +102,12 @@ main {
|
||||
; rotate around origin (0,0,0)
|
||||
|
||||
; set up the 3d rotation matrix values
|
||||
word wcosa = cos8(ax) as word
|
||||
word wsina = sin8(ax) as word
|
||||
word wcosb = cos8(ay) as word
|
||||
word wsinb = sin8(ay) as word
|
||||
word wcosc = cos8(az) as word
|
||||
word wsinc = sin8(az) as word
|
||||
word wcosa = cos8(ax)
|
||||
word wsina = sin8(ax)
|
||||
word wcosb = cos8(ay)
|
||||
word wsinb = sin8(ay)
|
||||
word wcosc = cos8(az)
|
||||
word wsinc = sin8(az)
|
||||
|
||||
word wcosa_sinb = wcosa*wsinb / 128
|
||||
word wsina_sinb = wsina*wsinb / 128
|
||||
@ -136,7 +136,8 @@ main {
|
||||
; set each of the 8 sprites to the correct vertex of the cube
|
||||
|
||||
; first sort vertices to sprite order so the back/front order is correct as well
|
||||
; (chose to do a simple bubble sort it's only 8 items to sort)
|
||||
; (simple bubble sort as it's only 8 items to sort)
|
||||
; TODO make a builtin function sort()
|
||||
for ubyte sorti in 6 to 0 step -1 {
|
||||
for ubyte i1 in 0 to sorti {
|
||||
ubyte i2 = i1+1
|
||||
@ -163,7 +164,7 @@ main {
|
||||
else
|
||||
c64.SPRPTR[i] = $2000/64 ; small ball
|
||||
|
||||
c64.SPCOL[i] = spritecolors[zc>>13 as byte + 4] ; further away=darker color
|
||||
c64.SPCOL[i] = spritecolors[(zc>>13) as byte + 4] ; further away=darker color
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,12 +41,12 @@ main {
|
||||
; rotate around origin (0,0,0)
|
||||
|
||||
; set up the 3d rotation matrix values
|
||||
word wcosa = cos8(ax) as word
|
||||
word wsina = sin8(ax) as word
|
||||
word wcosb = cos8(ay) as word
|
||||
word wsinb = sin8(ay) as word
|
||||
word wcosc = cos8(az) as word
|
||||
word wsinc = sin8(az) as word
|
||||
word wcosa = cos8(ax)
|
||||
word wsina = sin8(ax)
|
||||
word wcosb = cos8(ay)
|
||||
word wsinb = sin8(ay)
|
||||
word wcosc = cos8(az)
|
||||
word wsinc = sin8(az)
|
||||
|
||||
word wcosa_sinb = wcosa*wsinb / 128
|
||||
word wsina_sinb = wsina*wsinb / 128
|
||||
@ -62,14 +62,13 @@ main {
|
||||
word Azz = wcosb*wcosc / 128
|
||||
|
||||
for ubyte i in 0 to len(xcoor)-1 {
|
||||
rotatedx[i] = (Axx*xcoor[i] + Axy*ycoor[i] + Axz*zcoor[i]) / 128
|
||||
rotatedy[i] = (Ayx*xcoor[i] + Ayy*ycoor[i] + Ayz*zcoor[i]) / 128
|
||||
rotatedz[i] = (Azx*xcoor[i] + Azy*ycoor[i] + Azz*zcoor[i]) / 128
|
||||
; don't normalize by dividing by 128, instead keep some precision for perspective calc later
|
||||
rotatedx[i] = (Axx*xcoor[i] + Axy*ycoor[i] + Axz*zcoor[i])
|
||||
rotatedy[i] = (Ayx*xcoor[i] + Ayy*ycoor[i] + Ayz*zcoor[i])
|
||||
rotatedz[i] = (Azx*xcoor[i] + Azy*ycoor[i] + Azz*zcoor[i])
|
||||
}
|
||||
}
|
||||
|
||||
ubyte[] vertexcolors = [1,7,7,12,11,6]
|
||||
|
||||
sub draw_edges() {
|
||||
|
||||
; plot the points of the 3d cube
|
||||
@ -80,24 +79,25 @@ main {
|
||||
word persp
|
||||
byte sx
|
||||
byte sy
|
||||
ubyte color
|
||||
|
||||
for i in 0 to len(xcoor)-1 {
|
||||
rz = rotatedz[i]
|
||||
if rz >= 10 {
|
||||
persp = (rz+200) / height
|
||||
persp = 900 + rz/32
|
||||
sx = rotatedx[i] / persp as byte + width/2
|
||||
sy = rotatedy[i] / persp as byte + height/2
|
||||
c64scr.setcc(sx as ubyte, sy as ubyte, 46, vertexcolors[(rz as byte >>5) + 3])
|
||||
c64scr.setcc(sx as ubyte, sy as ubyte, 46, 7)
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0 to len(xcoor)-1 {
|
||||
rz = rotatedz[i]
|
||||
if rz < 10 {
|
||||
persp = (rz+200) / height
|
||||
persp = 900 + rz/32
|
||||
sx = rotatedx[i] / persp as byte + width/2
|
||||
sy = rotatedy[i] / persp as byte + height/2
|
||||
c64scr.setcc(sx as ubyte, sy as ubyte, 81, vertexcolors[(rz as byte >>5) + 3])
|
||||
c64scr.setcc(sx as ubyte, sy as ubyte, 81, 7)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
%zeropage basicsafe
|
||||
|
||||
; TODO implement asm generation for all loops here
|
||||
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
|
Loading…
Reference in New Issue
Block a user