|
Subject: Re: [stella] Scan lines, FotR.... From: Paul Slocum <paul-stella@xxxxxxxxxxxxxx> Date: Wed, 24 Apr 2002 00:46:16 -0500 |
Turns out Dark Mage *also* has 271 scan lines. So it's not anything my code, in particular, is doing, but rather something in Greg's engine.
Where would I look to figure out whether that's something I can reduce to a more NTSC-friendly value (I assume 262 or 263 would be ideal...) ?
;---------------------------------------------------------------------------
;
; Synthcart by Paul Slocum
;
; Text macros from Dark Mage (Greg Troutman)
; Text code from Stellar Track (Atari)
;
;---------------------------------------------------------------------------
processor 6502
include vcs.h
;---------------------------------------------------------------------------
; Constants
;---------------------------------------------------------------------------
SETUPDELAY equ #255
; Amount of balance attenuation
BALATT equ 5
;---------------------------------------------------------------------------
; RAM Variables
;---------------------------------------------------------------------------
frame equ $80
temp equ frame + 1
; 16 bit temp
temp16L equ temp + 1
temp16H equ temp16L + 1
; Initialize Flag
init equ temp16H + 1
visualBuffer equ init + 1; 46 bytes (overlaps with gfxBuffer and textPointer)
; Text engine variables
grfxBuffer equ init + 1 ; 24 bytes
; Array of text pointers to be displayed
textPointer equ grfxBuffer + 24 ; 22 bytes
visualPointer equ textPointer + 22 ; (overlap)
scanSec equ textPointer + 22
EOTflag equ scanSec + 1
backColor equ EOTflag + 1
; Variable for reading Keyboards
keyRead equ backColor + 1
note1 equ keyRead + 1
note2 equ note1 + 1
vol1 equ note2 + 1
vol2 equ vol1 + 1
soundTypeL equ vol2 + 1
soundTypeR equ soundTypeL + 1
sound1 equ soundTypeR + 1
sound2 equ sound1 + 1
soundEffect equ sound2 + 1
arpOn equ soundEffect + 1
arpPattern equ arpOn + 1
scale equ arpPattern + 1
beatBox1 equ scale + 1
beatBox2 equ beatBox1 + 1
beatLock equ beatBox2 + 1
beatBank equ beatLock + 1
beatResetCount equ beatBank + 1
adsrcount equ beatResetCount + 1
adsrSetting equ adsrcount + 1
; Attack/Decay/Sustain/Release variables
adsrLevel1 equ adsrSetting + 1
adsrLevel2 equ adsrLevel1 + 1
adsrEnable1 equ adsrLevel2 + 1
adsrEnable2 equ adsrEnable1 + 1
lastNote1 equ adsrEnable2 + 1
lastNote2 equ lastNote1 + 1
lastSound1 equ lastNote2 + 1
lastSound2 equ lastSound1 + 1
; Attenuation
atten1 equ lastSound2 + 1
atten2 equ atten1 + 1
balAttLeft equ atten2 + 1
balAttRight equ balAttLeft + 1
; Metrenome stuff
beat equ balAttRight + 1
tempoCount equ beat + 1
; Color cycle counter
colorCycle equ tempoCount + 1
arpShort equ colorCycle + 1 ;***
visualMode equ arpShort + 1
easterPointer equ visualMode + 1
visualModeCount equ easterPointer + 1
setupMode equ visualModeCount + 1
setupCount equ setupMode + 1
lastSetupKey equ setupCount + 1
tempo equ lastSetupKey + 1
; Keyboard key buffers
keys1 equ tempo + 1
keypad1 equ keys1 + 1 ; 4 bytes
keys2 equ keypad1 + 4
keypad2 equ keys2 + 1 ; 4 bytes
tempKeys1 equ keypad2 + 4
tempKeypad1 equ tempKeys1 + 1 ; 4 bytes
tempKeys2 equ tempKeypad1 + 4
tempKeypad2 equ tempKeys2 + 1 ; 4 bytes
; 111 bytes 1-25-02
;---------------------------------------------------------------------------
; Text Macros
;---------------------------------------------------------------------------
; a few macros for storing text in a reasonably easy to read format
;---------------------------------------------------------------------------
mac off
dc.b <#{0}
endm
mac wordOff
dc.b #<{1}
dc.b #>{1}
endm
mac mapRow
wordOff {1}
wordOff {2}
wordOff {3}
wordOff {4}
wordOff {5}
endm
mac EOL
dc.b #$FF
endm
mac EOT
dc.b #$FE
endm
mac line
;must supply 12 characters, though 0's will not be assembled
;------------------------------------------------------------
if {1} != 0
off {1}
endif
if {2} != 0
off {2}
endif
if {3} != 0
off {3}
endif
if {4} != 0
off {4}
endif
if {5} != 0
off {5}
endif
if {6} != 0
off {6}
endif
if {7} != 0
off {7}
endif
if {8} != 0
off {8}
endif
if {9} != 0
off {9}
endif
if {10} != 0
off {10}
endif
if {11} != 0
off {11}
endif
if {12} != 0
off {12}
endif
EOL
endm
mac blank
line #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
endm
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
org $1000
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
; Font Data
;---------------------------------------------------------------------------
; Include the font data here so it is aligned on a page
; boundary without wasting any space
;---------------------------------------------------------------------------
include snthfont.h ;just change the filename to use a different font...
;--------------------------------------------------------------------------
; Println
;--------------------------------------------------------------------------
; Most of this subroutine is ripped from Stellar Trak. Feel free to add
; your own comments--it's pretty straightforward ;) and very touchy. Won't
; work if a page boundary appears at certain places, due to excruciating
; cycle dependency, so if modifying the source, you might need an ALIGN
; pseudo-op to correct flubbery text displays. ALIGN 256 will always work,
; but maybe ALIGN 128, ALIGN 64, etc. will also work, and not waste as many
; bytes.
;--------------------------------------------------------------------------
align 256
println
ldx #4
sta WSYNC
pause
nop
dex
bne pause
lda temp
lda temp
sta HMCLR
ldx #$90
ldy #6 ;FONTHEIGHT
lda frame
and #$01
beq oddFrame
jmp evenFrame
print1
sta GRP1
lda (grfxBuffer + $8),y
sta GRP0
lda (grfxBuffer + $C),y
stx HMP0
stx HMP1
sta GRP1
lda (grfxBuffer + $10),y
sta GRP0
lda (grfxBuffer + $14),y
sta GRP1
sta GRP0
evenFrame
dey
bmi wrapEven
lda (grfxBuffer + $2),y
lsr
sta GRP0
lda (grfxBuffer +6),y
lsr
sta.w $001C
sta HMOVE
lda (grfxBuffer + $A),y
lsr
sta GRP0
lda (grfxBuffer + $12),y
lsr
sta temp
lda (grfxBuffer + $E),y
lsr
sta GRP1
lda temp
sta GRP0
lda (grfxBuffer + $16),y
lsr
sta GRP1
oddFrame
sta GRP0
lda #$70
sta HMP0
sta HMP1
dey
bmi wrapOdd
lda (grfxBuffer),y
sta GRP0
lda (grfxBuffer + $4),y
sta HMOVE
jmp print1
wrapEven
stx HMP0
stx HMP1
sta WSYNC
sta HMOVE
jmp print2
wrapOdd
sta WSYNC
sta temp
sta temp
print2
lda #$00
sta GRP0
sta GRP1
sta GRP0
rts ; println
;---------------------------------------------------------------------------
; Start of Program
;---------------------------------------------------------------------------
; Clear memory, locate character graphics positions and such,
; initialize key memory values, start GameLoop.
;-------------------------------------------------------------
Start
sei
cld
ldx #$FF
txs
lda #0
clear
sta 0,x
dex
bne clear
;---------------------------------------------------------------------------
; Initialize variables
;---------------------------------------------------------------------------
jsr fontSetup
; debug - start in setup mode
;lda #2
;sta setupMode
;lda #255
;sta setupCount
;lda #255
;sta visualMode
lda #11
sta beatBox1
sta beatBox2
lda #2
sta tempo
sta soundTypeL
sta soundTypeR
; clear keypad buffers
jsr clearKeys
; Set initialization flag.
; This stays set until the first frame is drawn.
lda #255
sta init
sta lastSetupKey
lda #startupSoundEffect
sta soundEffect
; Set up the text pointers for the status screen
jsr printStatus
sta lastNote1
sta lastNote2
lda #$0f ;set text color to white
sta COLUP0
sta COLUP1
jsr graphicsSetup
;--------------------------------------------------------------------------
; GameLoop
;--------------------------------------------------------------------------
GameLoop
jsr VSync ;start vertical retrace
inc frame ;we count frames for alternating graphics displays
jsr VBlank ; spare time during screen blank
jsr Picture ; draw one screen
jsr overscan ; do overscan
; Clear init flag
lda #0
sta init
jmp GameLoop ;back to top
;---------------------------------------------------------------------------
; Font Setup
;---------------------------------------------------------------------------
;the entire font is limited to one page, so we can hard code that page
;value into the MSB position of our graphics buffer
;-----------------------------------------------------
fontSetup
ldx #23 ;graphics buffer is 24 bytes
lda #>_space ;load up the page value for the font
grOff
sta grfxBuffer,x ;stuff it, won't ever change
dex ;back up two bytes
dex
bpl grOff ;and loop
rts
;---------------------------------------------------------------------------
; Text Engine Graphics Setup
;---------------------------------------------------------------------------
; use cycle counting to get the GRP registers configured and located
; in exactly the right spot
;---------------------------------------------------------------------------
graphicsSetup
sta WSYNC ;newline
lda #54 ;triple copy sprites, spaced wide
sta NUSIZ0 ;for both player graphic registers
sta NUSIZ1
lda #$31 ;draw leftmost and rightmost 2 playfield bits: reflect
sta PF0 ;this turns left/right edges black
sta CTRLPF ;this makes playfield reflective
nop ;wait 2 cycles, we need them get our RESP0/1 right
sta VDELP0 ;turn on vertical delay for both players
sta VDELP1
sta RESP0 ;mark our left margin here in P0
lda #$D0 ;setup to shift over 3 pixels to the right
sta RESP1 ;set P1
sta HMP0 ;prep P0 for his HMOVE
lda #$C0 ;setup to shift P1 4 pixels to the right
sta HMP1 ;prep P1 for his HMOVE
sta WSYNC ;newline
sta HMOVE ;anchor them down
rts
;--------------------------------------------------------------------------
; VSync
;--------------------------------------------------------------------------
VSync
lda #2 ;bit 1 needs to be 1 to start retrace
sta VSYNC ;start retrace
sta WSYNC ;wait a few lines
sta WSYNC
lda #44 ;prepare timer to exit blank period (44)
sta TIM64T ;turn it on
sta WSYNC ;wait one more
sta VSYNC ;done with retrace, write 0 to bit 1
rts ; VSync
;--------------------------------------------------------------------------
; Easter Check
;--------------------------------------------------------------------------
; Checks to see if the user has activated
; an easter egg (by playing a special melody)
;--------------------------------------------------------------------------
easterCheck
lda note1
cmp #255
beq stay
lda sound1
cmp #7
beq contEaster
cmp #1
beq contEaster
jmp resetPointer
contEaster
ldx easterPointer
lda note1
cmp easterArray,x
beq stay
inx
cmp easterArray,x
bne resetPointer
cpx #6
beq activateEaster
stx easterPointer
rts
activateEaster
lda visualMode
beq setupVisualMode
lda #0
sta visualMode
sta easterPointer
; Disable missles
sta ENAM0
sta ENAM1
; Have to re-setup text graphics since everything's
; messed up in visual mode.
jsr fontSetup
jsr graphicsSetup
; Set up the text pointers for the status screen
jsr printStatus
;set text color to white
lda #$0f
sta COLUP0
sta COLUP1
rts
setupVisualMode
lda #100
sta visualModeCount
resetPointer
lda #0
sta easterPointer
rts
stay
rts ; easterCheck
;--------------------------------------------------------------------------
; Clear temp Keypad Buffers
;--------------------------------------------------------------------------
; This function is copied in the upper 4k as clearKeys8k
;--------------------------------------------------------------------------
clearKeys
lda #255
sta tempKeypad1;
sta tempKeypad1+1;
sta tempKeypad1+2;
sta tempKeypad1+3;
sta tempKeypad2;
sta tempKeypad2+1;
sta tempKeypad2+2;
sta tempKeypad2+3;
lda #0
sta tempKeys1
sta tempKeys2
rts ; clearKeys
;--------------------------------------------------------------------------
; Background Color Cycling
;--------------------------------------------------------------------------
colorCycling
; Decrement the beat reset counter here.
; This makes it so the measure/beat will
; reset when a beat and arp are off for a while.
lda beatResetCount
beq noDecResetCount
dec beatResetCount
noDecResetCount
lda visualMode
bne colorModeA
; Use special bkgd colors for setup mode
lda setupCount
beq goAhead
lda setupMode
cmp #1
beq colorModeA
lda #62
sta colorCycle
rts
colorModeA
lda #51
sta colorCycle
rts
goAhead
; Every other frame
lda frame
and #%00000001
beq skipCycle
lda colorCycle
cmp #39
bmi skipColorReset
lda #0
skipColorReset
tax
inx
stx colorCycle
skipCycle
rts ; colorCycling
;--------------------------------------------------------------------------
; Set Sound Text
;--------------------------------------------------------------------------
; Stores a pointer to sound type text
; in the text pointer array using a lookup
; table.
; - ACC must contain the sound type (255 = beat)
; - X must contain the offset in the text pointer array
; where the text is to be stored.
;--------------------------------------------------------------------------
setSoundText
cmp #255
bne notBeat
lda #2
notBeat
asl ; x2
tay
dey ; back off one word. The array's just
dey ; set up like this.
; ERRCHECK
; (the Atari will crash if an odd value
; occurs here)
; cpy #22
; bpl err
; jmp noErr
;err
; ldy #22
;noErr
; Set sound text
lda soundTextArray,y
sta textPointer,x
inx
iny
lda soundTextArray,y
sta textPointer,x
rts ; setSoundText
;--------------------------------------------------------------------------
; Set Arp Text
;--------------------------------------------------------------------------
; Stores a pointer to arpeggiator text
; in the text pointer array based on arp settings.
;
; - X must contain the offset in the text pointer array
; where the text is to be stored.
;--------------------------------------------------------------------------
setArpText
; set up arp text from arp settings
lda arpShort
and #8
sta temp
lda arpOn
asl
adc temp
tay
lda arpTextArray,y
sta textPointer,x
iny
inx
lda arpTextArray,y
sta textPointer,x
rts ; setArpText
;--------------------------------------------------------------------------
; Set Tempo Text
;--------------------------------------------------------------------------
; Stores a pointer to tempo text
; in the text pointer array based on tempo settings.
;
; - X must contain the offset in the text pointer array
; where the text is to be stored.
;--------------------------------------------------------------------------
setTempoText
; set up tempo text from tempo delay
lda tempo
asl
tay
lda tempoTextArray,y
sta textPointer,x
inx
iny
lda tempoTextArray,y
sta textPointer,x
rts ; setTempoText
;--------------------------------------------------------------------------
; Set ADSR Text
;--------------------------------------------------------------------------
; Stores a pointer to ADSR text
; in the text pointer array based on tempo settings.
;
; - X must contain the offset in the text pointer array
; where the text is to be stored.
;--------------------------------------------------------------------------
setADSRText
lda adsrSetting
cmp #8 ; tremelo
bne notTremText
lda #5
notTremText
asl
tay
;DEBUG
;ldy #2
lda adsrTextArray,y
sta textPointer,x
inx
iny
lda adsrTextArray,y
sta textPointer,x
rts ; setADSRText
;--------------------------------------------------------------------------
; Set Title Text
;--------------------------------------------------------------------------
; Stores a pointer to title text.
; Fuji logo flashes with tempo.
;
; - X must contain the offset in the text pointer array
; where the text is to be stored.
;--------------------------------------------------------------------------
setTitleText
; If the beatResetCount is zero, then
; the beat will reset next time it's started,
; so don't flash the tempo
ldy #0
lda beatResetCount
beq alwaysOn
lda beat
and #%00001100
lsr
tay
alwaysOn
lda titleTextArray,y
sta textPointer,x
inx
iny
lda titleTextArray,y
sta textPointer,x
rts ; setTitleText
;--------------------------------------------------------------------------
; Set Arp Pattren
;--------------------------------------------------------------------------
; Stores a pointer to arp pattern text.
;
; - X must contain the offset in the text pointer array
; where the text is to be stored.
;--------------------------------------------------------------------------
setArpPatternText
lda arpPattern
asl
tay
lda arpPatternTextArray,y
sta textPointer,x
inx
iny
lda arpPatternTextArray,y
sta textPointer,x
rts ; setArpPatternText
;--------------------------------------------------------------------------
; Set Balance and Bank Text
;--------------------------------------------------------------------------
; Stores a pointer to balance and bank text.
; (Balance and Beat Bank are on the same line)
;
; - X must contain the offset in the text pointer array
; where the text is to be stored.
;--------------------------------------------------------------------------
setBalBankText
lda beatBank
asl
ldy balAttLeft
beq checkRightBal
ora #8
checkRightBal
ldy balAttRight
beq copyBalPointer
ora #16
copyBalPointer
tay
lda balBeatTextArray,y
sta textPointer,x
inx
iny
lda balBeatTextArray,y
sta textPointer,x
rts ; setBalText
;--------------------------------------------------------------------------
; Set Scale Text
;--------------------------------------------------------------------------
; Stores a pointer to scale text.
;
; - X must contain the offset in the text pointer array
; where the text is to be stored.
;--------------------------------------------------------------------------
setScaleText
lda scale
asl
tay
lda scaleTextArray,y
sta textPointer,x
inx
iny
lda scaleTextArray,y
sta textPointer,x
rts ; setScaleText
;--------------------------------------------------------------------------
; Set Text
;--------------------------------------------------------------------------
; Stores text pointer in text pointer array.
;
; - ACC must be low byte
; - X must be high byte
; - Y must by text pointer array offset
;--------------------------------------------------------------------------
setText
sta textPointer,y
txa
iny
sta textPointer,y
rts ; setText
;--------------------------------------------------------------------------
; Print Status Screen
;--------------------------------------------------------------------------
; This sets the text pointers to display the
; status screen (the information shown while
; playing the synthcart
;--------------------------------------------------------------------------
printStatus
ldx #0
jsr setTitleText
ldx #2
jsr setADSRText
ldx #4
jsr setTempoText
ldx #6
jsr setArpText
ldx #8
jsr setArpPatternText
ldx #10
jsr setScaleText
ldx #12
jsr setBalBankText
lda #<tx_leftsound
ldx #>tx_leftsound
ldy #14
jsr setText
ldx #16
lda soundTypeL
jsr setSoundText
lda #<tx_rightsound
ldx #>tx_rightsound
ldy #18
jsr setText
ldx #20
lda soundTypeR
jsr setSoundText
rts ; setupStatus
;--------------------------------------------------------------------------
; Print Setup Screen B
;--------------------------------------------------------------------------
; This sets the text pointers to display the
; setup screen B, where the user changes
; synthesizer settings
;--------------------------------------------------------------------------
printSetupB
lda #<tx_setupB1
sta textPointer + 0
lda #>tx_setupB1
sta textPointer + 1
lda #<tx_setupB2
sta textPointer + 2
lda #>tx_setupB2
sta textPointer + 3
lda #<tx_setupB3
sta textPointer + 4
lda #>tx_setupB3
sta textPointer + 5
lda #<tx_setupB4
sta textPointer + 6
lda #>tx_setupB4
sta textPointer + 7
lda #<tx_setupB5
sta textPointer + 8
lda #>tx_setupB5
sta textPointer + 9
lda #<tx_setupB6
sta textPointer + 10
lda #>tx_setupB6
sta textPointer + 11
lda #<tx_setupB7
sta textPointer + 12
lda #>tx_setupB7
sta textPointer + 13
lda #<tx_setupB8
sta textPointer + 14
lda #>tx_setupB8
sta textPointer + 15
ldx #16
jsr setADSRText
ldx #18
jsr setTempoText
ldx #20
jsr setArpText
rts ; printSetupB
;--------------------------------------------------------------------------
; Print Setup Screen A
;--------------------------------------------------------------------------
; This sets the text pointers to display the
; setup screen A, where the user changes
; synthesizer settings
;--------------------------------------------------------------------------
printSetupA
lda #<tx_setupA1
sta textPointer + 0
lda #>tx_setupA1
sta textPointer + 1
lda #<tx_setupA2
sta textPointer + 2
lda #>tx_setupA2
sta textPointer + 3
lda #<tx_setupA3
sta textPointer + 4
lda #>tx_setupA3
sta textPointer + 5
lda #<tx_setupA4
sta textPointer + 6
lda #>tx_setupA4
sta textPointer + 7
lda #<tx_setupA5
sta textPointer + 8
lda #>tx_setupA5
sta textPointer + 9
lda #<tx_setupA6
sta textPointer + 10
lda #>tx_setupA6
sta textPointer + 11
lda #<tx_setupA7
sta textPointer + 12
lda #>tx_setupA7
sta textPointer + 13
lda #<tx_setupA8
sta textPointer + 14
lda #>tx_setupA8
sta textPointer + 15
ldx #16
jsr setArpPatternText
ldx #18
jsr setScaleText
ldx #20
jsr setBalBankText
rts ; printSetupA
;--------------------------------------------------------------------------
; Print Visual Mode
;--------------------------------------------------------------------------
; Displays a message that visual mode is being activated
;--------------------------------------------------------------------------
printVisualMode
lda #<tx_blank
sta textPointer + 0
sta textPointer + 2
sta textPointer + 4
sta textPointer + 6
sta textPointer + 8
sta textPointer + 10
sta textPointer + 12
sta textPointer + 14
sta textPointer + 16
lda #>tx_blank
sta textPointer + 1
sta textPointer + 3
sta textPointer + 5
sta textPointer + 7
sta textPointer + 9
sta textPointer + 11
sta textPointer + 13
sta textPointer + 15
sta textPointer + 17
lda #<tx_visual1
ldx #>tx_visual1
ldy #18
jsr setText
lda #<tx_visual2
ldx #>tx_visual2
ldy #20
jsr setText
rts ; printVisualMode
;--------------------------------------------------------------------------
; Handle Setup Mode Keys
;--------------------------------------------------------------------------
; If in setup mode, deal with setup keys
; pressed. Must be called after readKeyboards.
;--------------------------------------------------------------------------
handleSetupKeys
lda setupCount
beq noSetup
ldx setupMode
dex
beq setup1
dex
bne noSetup
jsr handleSetup2
rts
setup1
jsr handleSetup1
rts
noSetup
rts ; handleSetupKeys
;--------------------------------------------------------------------------
; Handle Switches
;--------------------------------------------------------------------------
; Read and respond to console switches.
; Set up sound types.
; Display sound information on screen.
;--------------------------------------------------------------------------
handleSwitches
; *** Choose Sound from B&W, DF1, and DF2 switches ***
lda SWCHB
and #%00001000
lsr
sta temp
lda SWCHB
and #%11000000
clc
rol
rol
rol
ora temp
; Now ACC =
;
; BRL
; W
; 00000111
; Get the two sounds from the sound pair arrays
tax
lda soundPairArrayL,x
sta soundTypeL
lda soundPairArrayR,x
sta soundTypeR
; Clear the selected beats if
; beatbox is de-selected
cmp #255
beq noBeatReset
lda #11
sta beatBox1
sta beatBox2
noBeatReset
; Game Select Switch (activates Advanced Setup Mode for a few seconds)
;--------------------------------------------------------------------------
lda SWCHB
and #%000000010
bne noSel
lda setupCount
bne noSoundB
lda #setupActEffect
sta soundEffect
noSoundB
lda #255
sta setupCount
lda #2
sta setupMode
noSel
; Game Reset Switch (activates Setup Mode for a few seconds)
;--------------------------------------------------------------------------
lda SWCHB
and #%000000001
bne noRes
lda setupCount
bne noSoundA
lda #setupActEffect
sta soundEffect
noSoundA
lda #255
sta setupCount
lda #1
sta setupMode
noRes
; Update display
;--------------------------------------------------------------------------
updateDisplay
; check setup mode timer to see if setup mode is active
lda setupCount
beq statusScreen
; Count down
dec setupCount
bne noSetupDeactivateSound
lda #setupDeaEffect
sta soundEffect
noSetupDeactivateSound
; Figure out which setup mode is enabled
lda setupMode
cmp #1
beq goPrintSetupB
; Don't print test if visual mode is active
lda visualMode
bne handleVisualMode
jsr printSetupA
jmp handleVisualMode
goPrintSetupB
; Don't print test if visual mode is active
lda visualMode
bne handleVisualMode
jsr printSetupB
jmp handleVisualMode
; Setup mode is not active, so print the status screen
statusScreen
; Don't print test if visual mode is active
lda visualMode
bne handleVisualMode
jsr printStatus
; Handle Visual Mode
;--------------------------------------------------------------------------
handleVisualMode
; If visualModeCount is >0 then
; display "light show mode" message.
ldx visualModeCount
bne goVisualMode
jmp endHandleSwitches
goVisualMode
dex
stx visualModeCount
beq activateVisualMode
jsr printVisualMode
jmp endHandleSwitches
; Time has expired so switch to visual mode
activateVisualMode
lda #255
sta visualMode
; The visual color buffer shares space with the
; text buffers, so clear them out before
; visual mode starts.
lda #0
ldx #45
clearVisual
sta visualBuffer,x
dex
bne clearVisual
sta visualBuffer,x
endHandleSwitches
rts ; handleSwitches
;--------------------------------------------------------------------------
; Handle Setup 1
;--------------------------------------------------------------------------
; Deal with keys pressed in setup mode.
; Changes synth settings.
; Don't call this unless the synth is in setup mode
; since it will clear the keyboard buffers.
;--------------------------------------------------------------------------
handleSetup1
lda keypad1
cmp #255
bne handleKeys
lda keypad2
cmp #255
bne handleKeys
; Only unmark on odd frames (long story...)
lda keyRead
and #%00000001
beq noLastKeyReset
; Unmark the "last key" indicating that the key was released
lda lastSetupKey
and #%01111111
sta lastSetupKey
noLastKeyReset
; No keys pressed -- quit
jmp quitHandleSetup
endSetup
; If a key is pressed twice in a row, quit setup mode
lda #0
sta setupCount
lda #255
sta lastSetupKey
; Setup mode de-activate sound effect
lda #setupDeaEffect
sta soundEffect
jmp quitHandleSetup
handleKeys
; reset setup mode delay
ldx #255
stx setupCount
; Handle the tempo keys first since they're the
; only ones that won't close setup if pressed twice
cmp #0
bne notTempUp
ora #%10000000
cmp lastSetupKey
beq noDecTempo
sta lastSetupKey
lda tempo
beq noDecTempo
; Key press sound effect
ldx #setupSelectEffect
stx soundEffect
dec tempo
lda #0
sta tempoCount
noDecTempo
jmp quitHandleSetup
notTempUp
cmp #3
bne notTempDown
ora #%10000000
cmp lastSetupKey
beq noIncTempo
sta lastSetupKey
lda tempo
cmp #9
beq noIncTempo
; Key press sound effect
ldx #setupSelectEffect
stx soundEffect
inc tempo
noIncTempo
jmp quitHandleSetup
notTempDown
bit lastSetupKey
bmi noKeyHitSound
; Key press sound effect
ldx #setupSelectEffect
stx soundEffect
noKeyHitSound
; Check to see if the same key was pressed twice in a row
cmp lastSetupKey
beq endSetup
; Mark the new "last key"
ora #%10000000
sta lastSetupKey
and #%01111111
cmp #4
bne notArp32
lda #3
sta arpOn
jmp quitHandleSetup
notArp32
cmp #1
bne notArp16
lda #2
sta arpOn
jmp quitHandleSetup
notArp16
cmp #2
bne notArp8
lda #1
sta arpOn
jmp quitHandleSetup
notArp8
cmp #5
bne notArpOff
lda #0
sta arpOn
jmp quitHandleSetup
notArpOff
cmp #9
bne notTremA
lda #4
sta adsrSetting
jmp quitHandleSetup
notTremA
cmp #7
bne notLongRelease
lda #2
sta adsrSetting
lda #0
sta adsrLevel1
sta adsrLevel2
jmp quitHandleSetup
notLongRelease
cmp #6
bne notTremS
lda #8
sta adsrSetting
jmp quitHandleSetup
notTremS
cmp #8
bne notSlowAtk
lda #1
sta adsrSetting
jmp quitHandleSetup
notSlowAtk
cmp #10
bne notSlowAtkRel
lda #3
sta adsrSetting
lda #0
sta adsrLevel1
sta adsrLevel2
jmp quitHandleSetup
notSlowAtkRel
cmp #11
bne notNormAtk
lda #0
sta adsrSetting
jmp quitHandleSetup
notNormAtk
quitHandleSetup
; Clear keypad buffers
ldx #255
stx keypad1
stx keypad1+1
stx keypad1+2
stx keypad1+3
stx keypad2
stx keypad2+1
stx keypad2+2
stx keypad2+3
rts ; handleSetup
;--------------------------------------------------------------------------
; Handle Setup 2
;--------------------------------------------------------------------------
; Deal with keys pressed in setup mode.
; Changes synth settings.
; Don't call this unless the synth is in setup mode
; since it will clear the keyboard buffers.
;--------------------------------------------------------------------------
handleSetup2
lda keypad1
cmp #255
bne handleKeys2
lda keypad2
cmp #255
bne handleKeys2
; Only unmark on odd frames (long story...)
lda keyRead
and #%00000001
beq noLastKeyReset2
; Unmark the "last key" indicating that the key was released
lda lastSetupKey
and #%01111111
sta lastSetupKey
noLastKeyReset2
; No keys pressed -- quit
jmp quitHandleSetup2
endSetup2
; If a key is pressed twice in a row, quit setup mode
lda #0
sta setupCount
lda #255
sta lastSetupKey
; Setup mode de-activate sound effect
lda #setupDeaEffect
sta soundEffect
jmp quitHandleSetup2
handleKeys2
; reset setup mode delay
ldx #255
stx setupCount
bit lastSetupKey
bmi noKeyHitSound2
; Key press sound effect
ldx #setupSelectEffect
stx soundEffect
noKeyHitSound2
; Check to see if the same key was pressed twice in a row
cmp lastSetupKey
beq endSetup2
; Mark the new "last key"
ora #%10000000
sta lastSetupKey
and #%01111111
; Check keys/set settings...
cmp #0
bne notArpUp
lda #0
sta arpPattern
jmp quitHandleSetup2
notArpUp
cmp #1
bne notArpDown
lda #1
sta arpPattern
jmp quitHandleSetup2
notArpDown
cmp #2
bne notArpMix
lda #2
sta arpPattern
jmp quitHandleSetup2
notArpMix
cmp #6
bne notBeatBank1
lda #0
sta beatBank
jmp quitHandleSetup2
notBeatBank1
cmp #7
bne notBeatBank2
lda #1
sta beatBank
jmp quitHandleSetup2
notBeatBank2
cmp #8
bne notBeatBank3
lda #2
sta beatBank
jmp quitHandleSetup2
notBeatBank3
cmp #3
bne notMajorScale
lda #0
sta scale
jmp quitHandleSetup2
notMajorScale
cmp #4
bne notMinorScale
lda #1
sta scale
jmp quitHandleSetup2
notMinorScale
cmp #5
bne notAtonalScale
lda #2
sta scale
jmp quitHandleSetup2
notAtonalScale
cmp #9
bne notLeftBal
lda #0
sta balAttLeft
lda #BALATT
sta balAttRight
jmp quitHandleSetup2
notLeftBal
cmp #10
bne notCentBal
lda #0
sta balAttLeft
sta balAttRight
jmp quitHandleSetup2
notCentBal
cmp #11
bne notRightBal
lda #BALATT
sta balAttLeft
lda #0
sta balAttRight
jmp quitHandleSetup2
notRightBal
quitHandleSetup2
; Clear keypad buffers
ldx #255
stx keypad1
stx keypad1+1
stx keypad1+2
stx keypad1+3
stx keypad2
stx keypad2+1
stx keypad2+2
stx keypad2+3
rts ; handleSetup2
;--------------------------------------------------------------------------
; Sound Effect Player
;--------------------------------------------------------------------------
; This function plays sound effects to indicate the status
; of the machine. Sound effects are selected by setting
; soundEffect to the start of a sound in the
; sound effect array.
;--------------------------------------------------------------------------
soundEffectPlayer
ldx soundEffect
lda soundEffectArray,x
cmp #255
beq noSoundEffects
sta note1
inx
stx soundEffect
lda #5
sta sound1
lda #7
sta vol1
noSoundEffects
rts ; soundEffectPlayer
;--------------------------------------------------------------------------
; Voice Manager
;--------------------------------------------------------------------------
; This funtion calls the standard player, argpeggiator, and beat box
; based on which setup is selected. It also designates voices
; to the players based on some rules:
;
; 1) If keys are pressed on both keyboards, then each sound
; generator gets one voice.
; 2) If multiple keys are pressed on a keyboard and none on the other,
; the sound generator can have both voices.
; 3) The arpeggiator gets at most one voice.
;
; Note that the BeatBox is only allowed on soundR
;--------------------------------------------------------------------------
voiceManager
lda soundTypeR
cmp #255
beq beatBoxPlay
lda arpOn
bne arpPlay
; Standard Play on both keypads
;--------------------------------------------------------------------------
standard
lda keypad1
cmp #255
beq twoOnTwo
lda keypad2
cmp #255
beq twoOnOne
oneOnEach
lda #<keypad1 ; Use keypad 1
sta temp16L
lda #0
sta temp16H
ldy #1 ; One voice available
ldx #0 ; Osc 1
jsr standardPlayer
lda #<keypad2 ; Use keypad 2
sta temp16L
lda #0
sta temp16H
ldy #1 ; One voice available
ldx #1 ; Osc 2
jsr standardPlayer
rts
twoOnOne
lda #<keypad1 ; Use keypad 1
sta temp16L
lda #0
sta temp16H
ldy #2 ; Two voices available
ldx #0 ; Osc1 primary
jsr standardPlayer
rts
twoOnTwo
lda #<keypad2 ; Use keypad 2
sta temp16L
lda #0
sta temp16H
ldy #2 ; Two voices available
ldx #1 ; Osc2 primary
jsr standardPlayer
rts
; Arp on both keypads
;--------------------------------------------------------------------------
arpPlay
lda #<keypad2 ; Use keypad 1
sta temp16L
lda #0
sta temp16H
lda #1 ; Osc1
jsr arp
lda #<keypad1 ; Use keypad 2
sta temp16L
lda #0
sta temp16H
lda #0 ; Osc2
jsr arp
rts
; Standard play on left, Beatbox on right
;--------------------------------------------------------------------------
beatBoxPlay
lda arpOn
bne beatAndArpPlay
lda keypad1
cmp #255
beq checkRelease
lda beatBox1
cmp #11
beq twoOnPlayer
jmp beatAndPlayer
; Before going to twoOnBeat, need to make
; sure that long release isn't on and fading
; out a release.
checkRelease
; Check to see if a long
; release is being held
lda adsrSetting
and #2
beq twoOnBeat
ldx adsrLevel1
beq twoOnBeat
beatAndPlayer
lda #<keypad1 ; Use keypad 1
sta temp16L
lda #0
sta temp16H
ldy #1 ; One voice available
ldx #0 ; Osc 1
jsr standardPlayer
lda #1 ; One voice
jsr callBeatBox
rts
twoOnPlayer
lda #<keypad1 ; Use keypad 1
sta temp16L
lda #0
sta temp16H
ldy #2 ; Two voices available
ldx #0 ; Osc 1
jsr standardPlayer
rts
twoOnBeat
lda #2 ; Two voices available
jsr callBeatBox
rts
; Arp on left, Beatbox on right
;--------------------------------------------------------------------------
beatAndArpPlay
lda keypad1
cmp #255
bne beatOneArpOne
; Check to see if a long
; release is being held
lda adsrSetting
and #2
beq twoOnBeat
ldx adsrLevel1
beq twoOnBeat
beatOneArpOne
lda #<keypad1 ; Use keypad 1
sta temp16L
lda #0 ; page 1/osc1
sta temp16H
jsr arp
lda #1 ; One voice
jsr callBeatBox
rts ; voiceManager
;--------------------------------------------------------------------------
; Tempo
;--------------------------------------------------------------------------
; Generates tempo based on set tempo
;--------------------------------------------------------------------------
handleTempo
; Now deal with the tempo
; increment the tempo counter
inc tempoCount
; Check to see if the tempo counter
; has reached the point where the beat counter
; will be incremented
lda tempo
clc
adc #4
cmp tempoCount
bne quitTempo
; reset the tempo counter
lda #0
sta tempoCount
; increment the beat
ldx beat
inx
stx beat
cpx #128
bne quitTempo
lda #0
sta beat
quitTempo
rts ; tempo
;--------------------------------------------------------------------------
; Arpeggiator
;--------------------------------------------------------------------------
; Effectively two arpeggiators -- can arpeggiate both keypads
; simultaneously. Each supports up to 4 points.
; - temp16 should contain the address of the keypad array
; - ACC should contain the primary oscillator number (0 or 1)
;--------------------------------------------------------------------------
arp
tax
lda soundTypeL,x
sta sound1,x
ldy #0
lda (temp16L),y
cmp #255
bne keyCount
sta note1,x
; enable adsr control for arp
lda #255
sta adsrEnable1,x
rts
; Get number of keys pressed
keyCount
lda #255
sta beatResetCount
txa
pha
; Get the location of the number of keys
; variable (right before key array)
ldx temp16L
dex
; Get number of keys pressed
ldy 0,x
playArp
; # of keys pressed
dey
tya
asl
asl
asl
sta temp
clc
lda beat
and #%00011111
; Check arp rate (8/16/32) and shift accordingly
ldx arpOn
cpx #3
beq doneShifting
lsr
cpx #2
beq doneShifting
lsr
doneShifting
and #%00000111
clc
; keyspressed*8 + beat = arpArray index
adc temp
asl
asl
adc arpPattern
tax
lda arpUpArray,x
tay
lda (temp16L),y
asl
asl
clc
adc scale
tax
pla
tay
lda soundData1,x
sta note1,y
; Handle balance setting
lda balAttLeft,y
adc atten1,y
sta atten1,y
; enable adsr control for arp
lda #255
sta adsrEnable1,y
endArp
rts ; arp
;--------------------------------------------------------------------------
; Standard Player
;--------------------------------------------------------------------------
; For normal playing of notes from keyboard
; data (no arpeggiator or beat box)
; - temp16 should contain the address of the keypad array
; - Y should contain the number of voices available (1 or 2)
; - x should contain the primary oscillator number (0 or 1)
; - ACC should contain the attenuation setting
; If two oscillators are available, the other oscillator
; will be used if a second key is pressed on the keypad.
;--------------------------------------------------------------------------
standardPlayer
lda balAttLeft,x
sta temp
cpy #2
bne primaryOsc
secondOsc
lda soundTypeL,x
pha
txa
eor #%00000001
tax
pla
sta sound1,x
ldy #1
lda (temp16L),y
cmp #255
beq noSound2
asl
asl
clc
adc scale
tay
lda soundData1,y
noSound2
sta note1,x
; Handle balance setting
lda temp
adc atten1,x
sta atten1,x
; enable adsr control for standard play
lda #255
sta adsrEnable1,x
txa
eor #%00000001
tax
primaryOsc
ldy #0
lda (temp16L),y
cmp #255
beq noSound1
asl
asl
clc
adc scale
tay
lda soundData1,y
noSound1
sta note1,x
; Handle balance setting
lda temp
adc atten1,x
sta atten1,x
; enable adsr control for standard play
lda #255
sta adsrEnable1,x
lda soundTypeL,x
sta sound1,x
rts ; standardPlayer
;--------------------------------------------------------------------------
; VBlank
;--------------------------------------------------------------------------
; Handle user input and display setup during the VBLANK period
;--------------------------------------------------------------------------
VBlank
; Read keyboards here.
jsr readKeyboards
jsr handleSetupKeys
; If the tempo is calculated once per frame, the tempo change
; increments are too large. So I chose to count the tempo
; twice per frame. The tempo is checked and the voices setup here,
; but the notePlayer is called about halfway through the screen draw
; to keep the tempo steady.
jsr handleTempo
jsr calcVolume
jsr easterCheck
jsr soundEffectPlayer
jsr colorCycling
rts ; VBlank
;--------------------------------------------------------------------------
; Overscan
;--------------------------------------------------------------------------
; I ran out of time in VBlank, so I'm doing some things during overscan
;--------------------------------------------------------------------------
overscan
sta WSYNC
lda #33 ; Use the timer to make sure overscan takes (34)
sta TIM64T ; 30 scan lines. 29 scan lines * 76 = 2204 / 64 = 34.4
jsr handleSwitches
ldx #255
stx adsrEnable1
stx adsrEnable2
jsr voiceManager
jsr calcVolume
jsr soundEffectPlayer
jsr notePlayer
jsr handleTempo
ldx #255
stx adsrEnable1
stx adsrEnable2
jsr voiceManager
endOS
lda INTIM ; We finished, but wait for timer
bne endOS ; by looping till zero
sta WSYNC ; End last scanline
lda #$82
sta VBLANK
lda #$02
sta VBLANK
rts ; overscan
;--------------------------------------------------------------------------
; Note Player
;--------------------------------------------------------------------------
; Actually plays assigned notes using assigned voices
;--------------------------------------------------------------------------
notePlayer
; Sound type
ldx sound1
ldy sound2
stx AUDC0
sty AUDC1
; Frequency
ldx note1
ldy note2
stx AUDF0
sty AUDF1
; Volume
ldx vol1
ldy vol2
stx AUDV0
sty AUDV1
rts ; notePlayer
;--------------------------------------------------------------------------
; Show Visuals
;--------------------------------------------------------------------------
; Alternative draw screen function for visual mode
;--------------------------------------------------------------------------
showVisuals
pictureLoop2
lda INTIM ;check timer for end of VBLANK period
bne pictureLoop2 ;loop until it reaches 0
lda #0
sta COLUBK
lda #$80
sta VBLANK ;end screen blank
; Setup Color buffer pointer
;--------------------------------------------------------------------------
ldx visualPointer
inx
cpx #46
bmi notResetVis
ldx #0
notResetVis
stx visualPointer
sta WSYNC
; Put current note color into buffer
;--------------------------------------------------------------------------
; Put the next color in the scrolling buffer
; based on the current note1.
lda note1
cmp #255
bne calcColor
lda #0
jmp setColor
calcColor
asl
asl
asl
asl
asl
ora #%00000100
setColor
sta visualBuffer,x
sta WSYNC
; Set the missile colors based on the current note2.
lda note2
cmp #255
bne getColor2
lda #0
jmp setColor2
getColor2
asl
asl
asl
asl
asl
ora #%00001000
setColor2
sta WSYNC
sta COLUP0
sta COLUP1
; Enable missiles
lda #255
sta ENAM0
sta ENAM1
sta WSYNC
; Draw screen loop
;--------------------------------------------------------------------------
ldy #46
visualLoop
sta WSYNC
; Move the missles around every few scanlines
; based on notes pressed. This creates some
; neat patterns.
lda note1
asl
asl
sta HMM0
lda note2
asl
asl
sta HMM1
sta WSYNC
sta HMOVE
; Have to play last calculated note around middle of screen
; for steadiest beat.
cpy #22
bne noNotePlay
; Have to save X and Y on stack
tya
pha
txa
pha
jsr notePlayer
pla
tax
pla
tay
noNotePlay
sta WSYNC
; Display the scrolling note-color buffer
inx
cpx #46
bmi notResetVis2
ldx #0
notResetVis2
sta WSYNC
lda visualBuffer,x
sta COLUBK
dey
bne visualLoop
; Done drawing screen. Finish up.
;--------------------------------------------------------------------------
sta WSYNC
sta WSYNC
sta WSYNC
sta WSYNC
sta WSYNC
sta WSYNC
lda #$82
sta VBLANK ; Finished a screen, blank the beam.
rts ; showVisuals
;--------------------------------------------------------------------------
; Draw TV Pictures
;--------------------------------------------------------------------------
; Here is where we step down the screen drawing everything.
;
; Note that temp16 is used in here as a text pointer, so don't use
; it for anything else during the loop.
;--------------------------------------------------------------------------
Picture
ldx visualMode
beq regularPicture
jmp showVisuals
regularPicture
lda #0
sta COLUBK
lda #11 ;setup counter for rows of text
sta scanSec ;store in zero page memory variable
ldy #0 ;Y is used to track progress through this screen's text
sty EOTflag
pictureLoop
lda INTIM ;check timer for end of VBLANK period
bne pictureLoop ;loop until it reaches 0
;sta WSYNC ;newline (1)
lda #$80
sta VBLANK ;end screen blank
ScanLoop
;---------------------------------------------------------------------------
; This allows a different pointer to each line of text
lda #12
clc
sbc scanSec ; Get the current row of chars
pha
asl ; multiply x2
tax
; Get the pointer to the next text.
lda textPointer,x
sta temp16L
inx
lda textPointer,x
sta temp16H
; *** Set the BG Colors ***
pla
tay
adc colorCycle
tax
lda bgColorCycles,x
sta backColor
lda setupCount
beq loadSetupArray
lda dividerArray1,y
jmp drawDividers
loadSetupArray
lda dividerArray2,y
drawDividers
beq skipWhiteLine
sta WSYNC
; Draw a white line
lda #$0D
sta COLUBK
lda setupCount
beq skipWhiteLine
cpy #8
beq skipWhiteLine
; This makes some of the divider lines
; in setup mode shorter to make the keyboard
; grid look better
; Waste some cycles:
lda (temp16L,y)
lda (temp16L,y)
lda (temp16L,y)
lda (temp16L,y)
lda (temp16L,y)
lda (temp16L,y)
lda (temp16L,y)
lda (temp16L,y)
nop
nop
lda temp16L
lda backColor
sta COLUBK
skipWhiteLine
; Around the middle of the screen, the notePlayer is called.
; This must occur on a line where the white divider line
; is not drawn (on the Status or Setup screen)
cpy #5
bne skipNotePlayer
jsr notePlayer
skipNotePlayer
lda #64 ; A variable amount of text will be processed, so stay....
ldx backColor
sta WSYNC
jmp timer
; Timer
;--------------------------------------------------------------------------
; align 256
timer
sta TIM8T ;....in sync by timing out after finished (7 scanlines)
stx COLUBK
ldx #22 ;write 12 spaces to text buffer to wipe out what's there
lda #<_space ; from previous row/frame/etc.
blankLine
sta grfxBuffer,x ;grfxBuffer is our 24 byte, 16 bit list of chars
dex
dex
bpl blankLine ;fill it
lda EOTflag
bne eol
ldx #0 ; Will load from left to right.
ldy #0 ; Each line is referenced individually.
nextCol
lda (temp16L),y ; Indirect/indexed - pointer to a section of text
iny ; next char
cmp #$FF ; FF is EOL
beq eol ; done with a line?
cmp #$FE
bne noEOT
lda #1
sta EOTflag
jmp eol
noEOT
sta grfxBuffer,x ; No, stuff this char into the buffer
inx
inx
jmp nextCol ; Just keep going--a screen w/o 10 $FF's will screw this up
eol
lda INTIM ; We finished, but wait for timer
bne eol ; by looping till zero
sta WSYNC ; end current line
tya ; Need to save Y by putting into accumulator
pha ; then onto stack.
jsr println ; Print this row via subroutine. (6 scanlines)
pla ; Pull Y off stack
tay ; and put back.
dec scanSec ; next row to print
beq quitScanLoop; loop until all 11 rows of text have been displayed
jmp ScanLoop
quitScanLoop
sta WSYNC
; Skip one line if in setup mode to make it exactly 262 lines
lda setupCount
bne skipLastLine
sta WSYNC
skipLastLine
; Draw the white line at the bottom.
lda #$0D
sta COLUBK
sta WSYNC
lda #$82
sta VBLANK ; Finished a screen, blank the beam.
endScreen
rts ; Picture
;---------------------------------------------------------------------------
; Text and Note Data
;---------------------------------------------------------------------------
include snthdata.h
;--------------------------------------------------------------------------
; Call Keyboard Reader
;--------------------------------------------------------------------------
; Bankswitching code to call keyboard reader subroutine
; and then switch back to bank 1.
;--------------------------------------------------------------------------
org $1FC0
readKeyboards
ldx $1FF9 ; (switch to bank 2)
nop ; 1FE3 jsr readKeyboards8k
nop ; .
nop ; .
nop ; 1FE6 lda $1FF8 (Switch back to bank 1)
nop ; .
nop ; .
rts
;--------------------------------------------------------------------------
; Call Calculate Volume
;--------------------------------------------------------------------------
; Bankswitching code to call beat player subroutine
; and then switch back to bank 1.
;--------------------------------------------------------------------------
org $1FD0
calcVolume
ldx $1FF9 ; (switch to bank 2)
nop ; 1FE3 jsr calcVolume8k
nop ; .
nop ; .
nop ; 1FE6 lda $1FF8 (Switch back to bank 1)
nop ; .
nop ; .
rts
;--------------------------------------------------------------------------
; Call Beat Box
;--------------------------------------------------------------------------
; Bankswitching code to call beat player subroutine
; and then switch back to bank 1.
;
; Can't use ACC here since it is set to the number
; of oscillators for the beat box player.
;--------------------------------------------------------------------------
org $1FE0
callBeatBox
ldx $1FF9 ; (switch to bank 2)
nop ; 1FE3 jsr beat box
nop ; .
nop ; .
nop ; 1FE6 lda $1FF8 (Switch back to bank 1)
nop ; .
nop ; .
rts
;---------------------------------------------------------------------------
; Program Startup Vector
;---------------------------------------------------------------------------
org $1FF3 ; The cart will start in bank 2, then a bankswitch
; will occur and land here...
jmp Start ; Start program
org $1FFC ; Program startup vector (not used)
.word Start
.word Start
include snthup4k.h ; Upper 4k
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| [stella] Scan lines, FotR...., Adam Thornton | Thread | Re: [stella] Scan lines, FotR...., Glenn Saunders |
| Re: [stella] Cosmic Ark disassemble, Glenn Saunders | Date | Re: [stella] Cosmic Ark disassemble, Thomas Jentzsch |
| Month |