start of sound code

This commit is contained in:
Dagen Brock 2012-12-11 13:49:34 -06:00
parent 147854095e
commit e09226657b
4 changed files with 518 additions and 128 deletions

15
applerom.s Normal file
View File

@ -0,0 +1,15 @@
**************************************************
* Apple Standard Memory Locations
* @todo: finalize as include?
**************************************************
CLRLORES equ $F832
LORES equ $C050
TXTSET equ $C051
MIXCLR equ $C052
MIXSET equ $C053
KEY equ $C000
STROBE equ $C010
SPEAKER equ $C030
VBL equ $C02E
RDVBLBAR equ $C019 ;not VBL (VBL signal low)

395
festro.s
View File

@ -26,6 +26,14 @@ srcPtrL equz $02
srcPtrR equz $04 srcPtrR equz $04
srcPtrD equz $06 srcPtrD equz $06
**************************************************
* Demo Machine initialization
**************************************************
jsr DetectIIgs
jsr InitState
************************************************** **************************************************
* Main Demo Controller * Main Demo Controller
@ -40,6 +48,7 @@ DemoMain
bra :mainLoop bra :mainLoop
DemoSubroutineTable DemoSubroutineTable
* dw HandleKfestLogo
dw HandleProdrop dw HandleProdrop
dw HandleScan01 dw HandleScan01
@ -52,9 +61,9 @@ DemoSubroutineTable
dw HandleScan03 dw HandleScan03
dw HandleLoResInit dw HandleLoResInit
dw HandleFireRatio20 dw SetFireRatio20
dw HandleFireState1 dw HandleFireState1
dw HandleFireRatio90 dw SetFireRatio90
dw HandleFireState1 dw HandleFireState1
dw HandleFireStateK dw HandleFireStateK
dw HandleFireState1 dw HandleFireState1
@ -69,10 +78,10 @@ DemoSubroutineTable
dw HandleFireState1 dw HandleFireState1
dw HandleFireStateYear dw HandleFireStateYear
dw HandleFireState1 dw HandleFireState1
dw HandleFireRatio20 dw SetFireRatio20
dw HandleFireState1 dw HandleFireState1
dw HandleFireState1 dw HandleFireState1
dw HandleFireRatio01 dw SetFireRatio01
dw HandleFireState1 dw HandleFireState1
dw HandleKfestLogo dw HandleKfestLogo
dw HandleMedWait dw HandleMedWait
@ -95,97 +104,6 @@ DemoSubroutineTable
dw HandleFinalScreen dw HandleFinalScreen
dw P8Quit dw P8Quit
HandleAppleDraw
:mainLoop
lda #1
sta _appleDone
lda #AppleLogo
sta srcPtr
lda #>AppleLogo
sta srcPtr+1
lda #_appleOffsetY
sta _currentY
:lineStart asl
tax
lda LoLineTable,x
sta dstPtr
lda LoLineTable+1,x
sta dstPtr+1
lda dstPtr ; add offset
clc
adc #_appleOffsetX
sta dstPtr
bcc :noCarry2
inc dstPtr+1
:noCarry2
; src = buffer
; dst = screen
ldy #$00
:drawLoop lda (srcPtr),y
* bra :noMagic
cmp (dstPtr),y
beq :nextChar
stz _appleDone
jsr GetRand
cmp #$00 ; occasional black pixel @todo
beq :noMagic
cmp #$F8 ; had to add in a way to keep it from
blt :noMagic ; getting stuck so now it occasionally puts
lda (srcPtr),y ; the right pixel even when it wasn't
:noMagic sta (dstPtr),y ; found by getrand. (because it's only pseudorandom)
:nextChar iny
cpy #AppleLogoWidth
bne :drawLoop
:nextLine lda srcPtr
clc
adc #AppleLogoWidth
sta srcPtr
bcc :noCarry1
inc srcPtr+1
:noCarry1
inc _currentY ; handle screen offset
lda _currentY
cmp #AppleLogoHeight+_appleOffsetY
bne :lineStart
:donePass lda #$5
jsr SimplerWait
lda _appleDone
beq :mainLoop
lda #$33
jsr SimplerWait
inc GDemoState
jmp DemoMain
_currentY db #$00
_appleDone db #$00
_appleOffsetX equ 10
_appleOffsetY equ 8
* done = true
* while !done
* for x = 0 to width
* for y = 0 to height
* load buffer x,y
* cmp screen x,y (plus offsets)
* if (screen = buffer) continue
* done = false
* get rand
* store at screen x,y
* waitvbl
HandleFinalScreen HandleFinalScreen
@ -570,8 +488,11 @@ _defaultStarSpeed equ #$10
inc inc
cmp #8*4+#_defaultStarSpeed cmp #8*4+#_defaultStarSpeed
bne :slowDown bne :slowDown
lda #$40 jsr SErandStatic
jsr SimplerWait jsr SErandStatic
jsr SErandStatic
jsr SErandStatic
* speed up again * speed up again
@ -766,35 +687,34 @@ ScrollLeft
HandleLoResInit HandleLoResInit
sta LORES sta LORES
jsr ClearLoRes jsr ClearLoRes
inc GDemoState jmp DemoNext
jmp DemoMain
HandleTextClear HandleTextClear
sta TXTSET sta TXTSET
jsr ClearText jsr ClearText
inc GDemoState jmp DemoNext
jmp DemoMain
HandleFireRatio01 SetFireRatio01
lda #$01 lda #$01
sta GFireRatio sta GFireRatio
inc GDemoState jmp DemoNext
jmp DemoMain
HandleFireRatio20 SetFireRatio20
lda #$20 lda #$20
sta GFireRatio sta GFireRatio
inc GDemoState jmp DemoNext
jmp DemoMain
HandleFireRatio90 SetFireRatio90
lda #$90 lda #$90
sta GFireRatio sta GFireRatio
inc GDemoState jmp DemoNext
jmp DemoMain
HandleFireRatioC0 SetFireRatioC0
lda #$C0 lda #$C0
sta GFireRatio sta GFireRatio
inc GDemoState jmp DemoNext
DemoNext inc GDemoState
jmp DemoMain jmp DemoMain
HandleFireState1 HandleFireState1
@ -861,7 +781,9 @@ FirePass pha
jsr MakeHeat jsr MakeHeat
jsr Scroll8 jsr Scroll8
jsr Average8 jsr Average8
jsr VBlank
jsr DrawBufFullScreen jsr DrawBufFullScreen
jsr RandPop
plx plx
pla pla
rts rts
@ -873,8 +795,15 @@ HandleFireStateYear
jsr FirePass3 ; preserves A,X,Y jsr FirePass3 ; preserves A,X,Y
dec dec
bne :loop bne :loop
inc GDemoState jmp DemoNext
jmp DemoMain
RandPop jsr GetRandHot
bne :noPop
sta SPEAKER
:noPop rts
* A = count X=lowbyte Y=hibyte * A = count X=lowbyte Y=hibyte
FirePass2 FirePass2
@ -883,6 +812,7 @@ FirePass2
phy phy
jsr MakeHeat jsr MakeHeat
jsr Scroll8 jsr Scroll8
jsr RandPop
ply ply
plx plx
jsr DrawSpriteMask jsr DrawSpriteMask
@ -898,6 +828,7 @@ FirePass3
phy phy
jsr MakeHeat jsr MakeHeat
jsr Scroll8 jsr Scroll8
jsr RandPop
ply ply
plx plx
jsr DrawSpriteMaskBig jsr DrawSpriteMaskBig
@ -1146,6 +1077,17 @@ DrawStringXYWait
beq :done beq :done
sta (dstPtr),y sta (dstPtr),y
iny iny
pha
phx
phy
lda #6
ldx #1
ldy #24
jsr tone
ply
plx
pla
lda _drawWait lda _drawWait
jsr SimplerWait jsr SimplerWait
bra :loop bra :loop
@ -1444,6 +1386,7 @@ HandleProdrop
jmp :prodropUpdate jmp :prodropUpdate
:prodropScan :prodropScan
jsr soundDownReset
lda #0 ; start scan at line 0 every time lda #0 ; start scan at line 0 every time
sta _prodropScanLine sta _prodropScanLine
@ -1517,18 +1460,25 @@ HandleProdrop
jmp DemoMain jmp DemoMain
rts ;; @todo: add rts support to jmp table stuff? rts ;; @todo: add rts support to jmp table stuff?
]prodropAnimDone ]prodropAnimDone ;; might rework this.. is there any point in returning to
;; the main demo loop between scans and such?
lda #0 lda #0
sta _prodropState ; uhg..reset state before exit so can be called again sta _prodropState ; uhg..reset state before exit so can be called again
inc GDemoState ; ugh again... not great.. using globals inc GDemoState ; ugh again... not great.. using globals
jmp DemoMain jmp DemoMain
* This is the animation loop
:prodropUpdate :prodropUpdate
lda #0 ; finished = false lda #0 ; finished = false
sta _prodropAnimDone stz _prodropAnimDone
:prodropUpdateLoop :prodropUpdateLoop
lda _prodropSound
bne :noSound
lda #4
jsr soundDown ;SErandBlip
:noSound stz _prodropSound ; if this flag gets set we call our sound routine
lda #16 lda #16
tax tax
tay tay
@ -1580,6 +1530,7 @@ HandleProdrop
]dropCharWrite equ *-1 ; we set this differently for GRaphics mode ]dropCharWrite equ *-1 ; we set this differently for GRaphics mode
sta (dstPtr),y sta (dstPtr),y
* breath... holy crap all that just to draw a space at X,Y * breath... holy crap all that just to draw a space at X,Y
* now we draw the character one line down
ldy #2 ldy #2
lda (srcPtr),y ; get Y value lda (srcPtr),y ; get Y value
inc ; move it down inc ; move it down
@ -1600,6 +1551,8 @@ HandleProdrop
bra ]nextAnimChar bra ]nextAnimChar
]charFinished ]charFinished
lda #1 ; SET SOUND ANY TIME NEW CHAR DROPS
sta _prodropSound
lda #0 lda #0
sta (srcPtr) sta (srcPtr)
bra ]nextAnimChar bra ]nextAnimChar
@ -1611,6 +1564,7 @@ HandleProdrop
sta (srcPtr),y sta (srcPtr),y
]nextAnimChar ]nextAnimChar
lda srcPtr lda srcPtr
clc clc
@ -1643,6 +1597,30 @@ HandleProdrop
_prodropAnimDone db 1 ; any time we find a character it flips this false _prodropAnimDone db 1 ; any time we find a character it flips this false
_prodropScanLine db 0 ; starts scanning at line 0 _prodropScanLine db 0 ; starts scanning at line 0
_prodropState db 0 ; starts with 0, which is scan mode _prodropState db 0 ; starts with 0, which is scan mode
_prodropSound db 0 ; determine if we should call sound engine
soundDownReset stz _sndFreq
stz _sndFreq+1
rts
_sndFreq dw 0
_sndInt db 0
soundDown pha ;interval
ldy _sndFreq
ldx _sndFreq+1
lda #$8
jsr tone
pla
cmp _sndInt
beq :intMatch
inc _sndInt
rts
:intMatch stz _sndInt
inc _sndFreq
bcs :inc
rts
:inc inc _sndFreq+1
rts
@ -1751,6 +1729,117 @@ _swipeMaxWidth db #0 ; set # characters per line in the source buffer
_swipeXOffset db #$0 ; screen offset for placement _swipeXOffset db #$0 ; screen offset for placement
_swipeYOffset db #$0 ; screen offset for placement _swipeYOffset db #$0 ; screen offset for placement
HandleAppleDraw
:mainLoop
lda #1
sta _appleDone
lda #AppleLogo
sta srcPtr
lda #>AppleLogo
sta srcPtr+1
lda #_appleOffsetY
sta _currentY
:lineStart asl
tax
lda LoLineTable,x
sta dstPtr
lda LoLineTable+1,x
sta dstPtr+1
lda dstPtr ; add offset
clc
adc #_appleOffsetX
sta dstPtr
bcc :noCarry2
inc dstPtr+1
:noCarry2
; src = buffer
; dst = screen
ldy #$00
:drawLoop lda (srcPtr),y
* bra :noMagic
cmp (dstPtr),y
beq :nextChar
stz _appleDone
jsr GetRand
cmp #$10 ; occasional black pixel @todo
bge :noBlack
lda #0
bra :noMagic
:noBlack cmp #$FA ; had to add in a way to keep it from
blt :noMagic ; getting stuck so now it occasionally puts
lda (srcPtr),y ; the right pixel even when it wasn't
:noMagic sta (dstPtr),y ; found by getrand. (because it's only pseudorandom)
:nextChar iny
cpy #AppleLogoWidth
bne :drawLoop
:nextLine lda srcPtr
clc
adc #AppleLogoWidth
sta srcPtr
bcc :noCarry1
inc srcPtr+1
:noCarry1
inc _currentY ; handle screen offset
lda _currentY
cmp #AppleLogoHeight+_appleOffsetY
bne :lineStart
:donePass lda #$5
jsr SimplerWait
lda _appleDone
beq :mainLoop
lda #$33
jsr SimplerWait
inc GDemoState
jmp DemoMain
_currentY db #$00
_appleDone db #$00
_appleOffsetX equ 10
_appleOffsetY equ 8
* done = true
* while !done
* for x = 0 to width
* for y = 0 to height
* load buffer x,y
* cmp screen x,y (plus offsets)
* if (screen = buffer) continue
* done = false
* get rand
* store at screen x,y
* waitvbl
********************* *********************
* DEMO ONLY! * DEMO ONLY!
* x=10,y=10 * x=10,y=10
@ -1857,6 +1946,10 @@ KeyHandler
sta GKeyEvent sta GKeyEvent
cmp #"q" cmp #"q"
beq P8Quit beq P8Quit
cmp #"Q"
beq P8Quit
cmp #K_ESC
beq P8Quit
]noKey rts ]noKey rts
@ -2392,18 +2485,61 @@ _multiplyResult dw 0000
************************************************** **************************************************
* Apple Standard Memory Locations * See if we're running on a IIgs
* @todo: finalize as include? * From Apple II Technote:
* Miscellaneous #7
* Apple II Family Identification
************************************************** **************************************************
CLRLORES EQU $F832 DetectIIgs
LORES EQU $C050 sec ;Set carry bit (flag)
TXTSET EQU $C051 jsr $FE1F ;Call to the monitor
MIXCLR EQU $C052 bcs :oldmachine ;If carry is still set, then old machine
MIXSET EQU $C053 * bcc :newmachine ;If carry is clear, then new machine
KEY EQU $C000 :newmachine lda #1
STROBE EQU $C010 sta GMachineIIgs
SPEAKER EQU $C030 rts
VBL EQU $C02E :oldmachine stz GMachineIIgs
rts
InitState
lda GMachineIIgs
beq :IIe
rts
:IIe rts
VBlank lda _vblType
bne :IIc
jsr VBlankNormal
rts
:IIc rts
_vblType db 0 ; 0 - normal, 1 - IIc
**************************************************
* Wait for vertical blanking interval - IIe/IIgs
**************************************************
VBlankNormal
:loop1 lda RDVBLBAR
bpl :loop1 ; not VBL
:loop lda $c019
bmi :loop ;wait for beginning of VBL interval
rts
**************************************************
* Keyboard equates
**************************************************
K_CTRL equ $60
K_ESC equ $9b
K_DELETE equ $7f
K_SHIFT equ $20
K_CTRL_S equ "s"-K_CTRL
K_CTRL_P equ "n"-K_CTRL
************************************************** **************************************************
* Lores/Text lines * Lores/Text lines
@ -2455,6 +2591,7 @@ DSEG2 ds 4096 ; Secondary (overflow region?)
GKeyEvent db 0 ; keypress - allow subroutines to access GKeyEvent db 0 ; keypress - allow subroutines to access
GDemoState db 0 ; current demo state GDemoState db 0 ; current demo state
GMachineIIgs db 0 ; machine identification flag
************************************************** **************************************************
@ -2465,5 +2602,7 @@ ProdropStateUpdate equ #1 ; Does one round of character updates, buffer&screen
ProdropStateDone equ #2 ; Really just to let the callee(s) know it's all done ProdropStateDone equ #2 ; Really just to let the callee(s) know it's all done
use festrodata ; all the sprites and such use festrodata ; all the sprites and such
use soundengine ; bleep, boops and clicks
use applerom ; softswitch locations, etc
lst on lst on
sav /code/festro.sys sav /code/festro.sys

109
sndplay.s Normal file
View File

@ -0,0 +1,109 @@
**************************************************
* SNDPLAY
* @author Dagen Brock <dagenbrock@gmail.com>
* @date 2012-12-10
**************************************************
org $2000
typ #$ff
xc off ; 65c02
xc
lst off
:noKey lda KEY
cmp #$80
blt :noKey
bit STROBE
cmp #K_ESC
beq P8Quit
cmp #"+"
beq :slideUp
cmp #"-"
beq :slideDown
cmp #"_"
beq :slideDown
cmp #"]"
beq :play
cmp #"/"
bne :noChangeDur
lda _noteDur
clc
adc #$20
sta _noteDur
jsr HexPrint
bra :noKey
:slideUp inc _slideNote
lda _slideNote
bra :printBeep
:slideDown dec _slideNote
lda _slideNote
bra :printBeep
:play ldx _noteDur
lda _slideNote
bra :printBeep
:noChangeDur
sec
sbc #"a"
tax
lda _SE_tones,x
:printBeep jsr HexPrint
ldx _noteDur
jsr SENoteAX
bra :noKey
_noteDur db #$20
_slideNote db 0
P8Quit jsr $bf00
dfb $65
da qparms
rts
qparms dfb 4
dfb 0
da $0000
dfb 0
da $0000
* print accumulator
HexPrint pha
pha
lsr
lsr
lsr
lsr
tax
lda _chars,x
sta $400
pla
and #%00001111
tax
lda _chars,x
sta $401
pla
rts
_chars asc "0123456789ABCDEF"
**************************************************
* Awesome PRNG thx to White Flame (aka David Holz)
**************************************************
GetRand
lda _randomByte
beq :doEor
asl
bcc :noEor
:doEor eor #$1d
:noEor sta _randomByte
rts
_randomByte db 0
K_ESC equ $9b
use soundengine ; bleep, boops and clicks
use applerom
lst on
sav /code/sndplay.sys

127
soundengine.s Normal file
View File

@ -0,0 +1,127 @@
* COSMOS THEME
Song01
_SE_tonesBAD db 255,241,227,214,202,191,180,170,161,152,143,135
db 128,121,114,108,102,096,091,085,081,076,072,068
db 064,060,057,054,051,048,045,043,040,038,036,034
_SE_tones db NoteG0,NoteGsharp0,NoteA0,NoteBflat0,NoteB0
db NoteC1,NoteCsharp1,NoteD1,NoteDsharp1,NoteE1
db NoteF1,NoteFsharp1,NoteG1,NoteGsharp1,NoteA1
db NoteBflat1,NoteB1,NoteC2,NoteCsharp2,NoteD2
db NoteDsharp2,NoteE2,NoteF2
NoteG0 equ $00 ; because it loops
NoteGsharp0 equ $f0
NoteA0 equ $e6
NoteBflat0 equ $d5
NoteB0 equ $cb ; speculating here on up
NoteC1 equ $c0
NoteCsharp1 equ $b5
NoteD1 equ $ac
NoteDsharp1 equ $a3
NoteE1 equ $99
NoteF1 equ $90
NoteFsharp1 equ $89
NoteG1 equ $80
NoteGsharp1 equ $79
NoteA1 equ $72
NoteBflat1 equ $6c
NoteB1 equ $66
NoteC2 equ $60
NoteCsharp2 equ $5b
NoteD2 equ $56
NoteDsharp2 equ $51
NoteE2 equ $4c
NoteF2 equ $48
; starts to suck here anyway
SErandStatic
ldy #$ff
:loop lda SPEAKER
jsr GetRand
* lsr
beq :next
:wait dec
bne :wait
:next dey
bne :loop
rts
SErandBlip
jsr GetRand
sta _SECURRNOTE
lda #5
sta _SECURRNOTE+1
jsr SEplayNote
rts
* a = freq ... x = dur
SENoteAX
sta _SECURRNOTE
stx _SECURRNOTE+1
jsr SEplayNote
;lda _SECURRNOTE+1
;ldy _SECURRNOTE
;ldx #$0
;jsr tone
rts
SEplayNote
:loop lda SPEAKER
:whyWut dey
bne :thar
dec _SECURRNOTE+1
beq :doneThat
:thar dex
bne :whyWut
ldx _SECURRNOTE
jmp :loop
:doneThat rts
_SECURRNOTE db 0,0 ; current note being played (frequency/duration)
*-------------------------------
*
* T O N E
*
* In: y-x = pitch lo-hi
* a = duration
*
*-------------------------------
tone
sty :pitch
stx :pitch+1
:outloop bit SPEAKER
ldx #0
:midloop ldy #0
:inloop iny
cpy :pitch
bcc :inloop
inx
cpx :pitch+1
bcc :midloop
sec
sbc #1
bne :outloop
rts
:pitch ds 2