MSU1 Code Library

Go down

MSU1 Code Library Empty MSU1 Code Library

Post by Cubear Thu 21 Sep 2023 - 6:39

Hi all. I figured it might be nice to have a spot to post some cleaned up code to insert into various games. a lot of times the MSU1 code can be shared easily between similar functions, so there's no need to write new code all the time...

I'll start with the very basics: Playing the track number in A on the MSU1
Play_Track
Code:

pha
sta $2004 ;store track to MSU1
stz $2005 ;zero to msu1 high byte.
stz $2006 ; zero to 2006. no volume. prevents crackle.
loop:
bit $2000 ;checking MSU1 busy
bvs loop
lda $2000;
and #$08 ; is the track found?
beq $03 ;if yes, don't play spc.
jmp notrack
pla
pha
cmp #$XX ;insert whatever number of tracks here that need to not loop.
beq noloop
cmp #$XX
beq noloop
cmp #$XX
beq noloop
lda #$03
bra $02
noloop:
lda #$01
sta $2007 ; sets MSU play
lda #$ff ;\raises volume
sta $2006;/
notrack:
pla
rts;rtl if you jumped long to get in here

Can't take credit for this one: I stole it from conn Smile


Last edited by Cubear on Thu 21 Sep 2023 - 7:33; edited 1 time in total
Cubear
Cubear

MSU1 Code Library Image211

Since : 2021-11-17

https://www.patreon.com/Cubear

Back to top Go down

MSU1 Code Library Empty Re: MSU1 Code Library

Post by pev Thu 21 Sep 2023 - 6:53

I think a lot of my patches are from Conn stolen bits, lol. He is legend.

pev

MSU1 Code Library Image211

Since : 2017-10-17

Back to top Go down

MSU1 Code Library Empty Re: MSU1 Code Library

Post by Cubear Thu 21 Sep 2023 - 7:24

here's an absolute beast of a fade routine that i had to make for live-a-live
this part is for setting up the speed of the fade and which direction it goes (fade up vs fade down)
Set_Fade
Code:

isfade:
lda #$00
phb
pha
plb ;lets do this in databank 00

lda #$03
sta !FADECLOCKLIMIT ;the fade clock will count to this number before resetting to 0 and doing a fade step. larger values = slower fade.
stz !FADECLOCK ;zero out whatever value might still be in there. sanity check.

;$30 was a native code value for fade time in live-a-live. put whatever value you like here for number of frames of fade.
lda $30   ;total time for fade in frames
sta !FADESTEP

;$31 was what volume the game wanted to fade to. you probably want #$00 or #$FF but this game would fade to specific volumes.
lda $31 ;get target volume.
sta !MSUVOLUMETARGET

cmp !MSUVOLUMECURRENT ;check if target is above or below current volume.
beq fadeSame          
bcc fadeDown
bcs fadeUp

fadeDown:
lda !MSUVOLUMECURRENT
sec ;gets the difference between current and target values.
sbc $31
stz $4205 ;high byte (Zero)
sta $4204 ;low byte to be divided.
STA !FADEDIFFERENCE ;total amount to fade.
lda !FADESTEP ;number of frames to fade for.
sta $4206 ;divide volume difference by volume step (number of frames)
NOP                
NOP
NOP
NOP
NOP ;wait 16 machine cycles
NOP
NOP
NOP
LDA $4216 ;check for remainder
CMP !FADEDIFFERENCE ;make sure it is NOT the entire thing.
beq slowFade ;if it is, do a slower fade
lda !MSUVOLUMECURRENT
sec ;subtract the division remainder from our current volume
sbc $4216 ;so that the math always comes to an exact multiple.
sta !MSUVOLUMECURRENT
lda $4214 ;get our result.
sta !FADESTEP ;save it to be subtracted once per frame.
noFadeEnd:
plb
plp
pla
rtl

fadeUp:
lda $31
sec ;gets the difference between current and target values.
sbc !MSUVOLUMECURRENT
stz $4205 ;high byte.
sta $4204 ;low byte to be divided.
STA !FADEDIFFERENCE
lda !FADESTEP
sta $4206 ;divide volume difference by volume step (number of frames)
NOP
NOP
NOP
NOP
NOP ;wait 16 machine cycles
NOP
NOP
NOP
lda !MSUVOLUMECURRENT
clc
adc $4216 ;check for remainder
CMP !FADEDIFFERENCE ;make sure it is NOT the entire thing.
beq slowFade ;if it is, do a slower fade
sta !MSUVOLUMECURRENT ;and remove it from the current volume so the math works out
lda $4214 ;get our result.
sta !FADESTEP ;save it to be subtracted once per frame.
slowFadedone:
plb
plp
pla
rtl

slowFade: ;3x slower than normal fade.
lda #$06
sta !FADECLOCKLIMIT
lda #$01
sta !FADESTEP
bra slowFadedone

once you had all these values set, you can hook in NMI and run this:

Do_Fade
Code:
doFade: ;try to be really light in here, not sure how many cycles extra are here.

pha
 php
 sep #$20
 lda !FADECLOCK
 inc
 CMP !FADECLOCKLIMIT
 beq clockTime
 sta !FADECLOCK
 bra notTime ;exit if clock doesnt match
 
clockTime:
 lda #$00
 sta !FADECLOCK
 lda !MSUVOLUMECURRENT
 cmp !MSUVOLUMETARGET
 beq doneFade ;if they're the same, get out of here NOW
 bcs doDown ;otherwise doUp

;doUp:
 clc
 adc !FADESTEP ;add this once per frame until they match.
 bcs overflowUp ;check for overflow? it shouldnt happen but maybe....
 bra doneFade

doDown:
 sec
 sbc !FADESTEP ;subtract by step amount per frame
 ;maybe check for overflow here, even though it should not happen.
 bcc overflowDown
 
doneFade:
 sta !MSUVOLUMECURRENT
 sta $2006
 lda #$02
 sta !FADECLOCKLIMIT
notTime:
 plp
 pla
rtl

overflowUp:
 lda #$FF
 bra doneFade
overflowDown:
 lda #$00
 bra doneFade


this is some code that i'm pretty proud of, but i'm not sure it'll ever be useful again.  just in case though, i'll put it here.


Last edited by Cubear on Thu 21 Sep 2023 - 8:59; edited 2 times in total
Cubear
Cubear

MSU1 Code Library Image211

Since : 2021-11-17

https://www.patreon.com/Cubear

Back to top Go down

MSU1 Code Library Empty Re: MSU1 Code Library

Post by Cubear Thu 21 Sep 2023 - 7:32

A much simpler fade code is here.  set #$01 to a ram address to fade up, #$02 to fade down. It'll fade to the limits #$FF or #$00 and if your fade changes while it is running, it'll change directions too.

this is just the NMI routine since setting up the fade is so much simpler.
Do_Fade
Code:
dofade:
php
 sep #$20
 pha
 lda !msufadeflag ;check for fade flag (01)
 beq nofade
 cmp #$01
 bne nofadeup
 lda !msuvol ;check to see if our volume is capped out
 beq startfadeup
 cmp #$FF
 beq donefadeup
donestartfadeup:
 inc
 beq donefadeup
 inc
 beq donefadeup
 inc
 beq donefadeup
 sta !msuvol
 STA $2006
fadedownout:
 pla
plp
rtl
startfadeup:
lda #$03
sta $2007
lda #$00
bra donestartfadeup

nofadeup:
 cmp #$02
 bne nofade
 lda !msuvol ;check to see if our volume is capped out
 beq donefadedown
 dec
    beq donefadedown
 dec
    beq donefadedown
 dec
 sta !msuvol
 sta $2006
 bra fadedownout
 
donefadeup:
 lda #$FF
donefadedownout:
 sta !msuvol
 sta $2006

nofade:
 stz !msufadeflag
pla
plp
rtl
pausetrack:

donefadedown:
lda #$04
sta $2007
lda #$00
bra donefadedownout
Cubear
Cubear

MSU1 Code Library Image211

Since : 2021-11-17

https://www.patreon.com/Cubear

Back to top Go down

MSU1 Code Library Empty Re: MSU1 Code Library

Post by Cubear Thu 21 Sep 2023 - 7:37

yet another fade, this one just fades down, smaller and simpler for when that matters. set 01 to a ram address to fade down. I've set it up that you should set your volume to FE instead of FF because I like the speed of 2 units at a time instead of 1 or 3.

Do_Fade_Down
Code:
dofade:
php
sep #$20 ;8 bit mode
pha
lda !MSUFadeFlag ;check for fade flag (01) if not, exit and max volume
beq nofade ;if 0, this branches.
lda !MSUVolume
cmp #$00
beq donefade ;if already at 0, done fading.

dec
dec ;2 decrease here with volume #$FE, if #FF do 1 or 3.

sta !MSUVolume        
STA $002006 ;long addressed in case DB is set weird
pla
plp
rts

donefade:
lda #$00 ;sets our fades to 0
sta !MSUFadeFlag ;remove this one for Life Force since the internal system should remove the fade flag for us
sta !MSUVolume        
STA $002006
nofade:
pla
plp
rts
Cubear
Cubear

MSU1 Code Library Image211

Since : 2021-11-17

https://www.patreon.com/Cubear

Back to top Go down

MSU1 Code Library Empty Re: MSU1 Code Library

Post by Conn Thu 21 Sep 2023 - 11:00

Too many cooks spoil the food. But what I noticed is for example:
Code:
lda !MSUVolume
cmp #$00
beq donefade ;if already at 0, done fading.

dec
dec ;2 decrease here with volume #$FE, if #FF do 1 or 3.
so if you never reach 00 because e.g. 3 dec:s will lead to FF, there will be bug.

The easiest code to fade imo is that I used for ALTTP lite patch:

All in one check msu ready/ fade down (full/half) and fade up in NMI cycle
Code:

; $0127 fade flag (in this example only), set at introducing new track/fade
; -- #$f1: fadeZero: in this example fade to Zero command
; -- #$f2: fadeHalf
; -- #$f3: fadeFull
; $0129 msu busy flag (this example only), set at introducing new track/fade
; -- #$00: no busy
; -- #$01: either fade or msu ready check given
; $012b current volume level to be stored to $2006, set at introducing new track/fade
; -- #$00: start value should be 00 if fade up requested
; -- #$ff: start value should be FF if fade down requested

; when introducing a new track
; do all the msu stuff:
;....

STA $2004
STA $0127  ;store track number or fading instruction (fading can also be stored atdifferent hook)
STZ $2005
STZ $2006
STZ $012b ; erase target volume
LDA #$01
STA $0129  ; set msu busy
;....

; check fade/msu busy (sd2snes) flag $0129 in !!! NMI cycle!!! - set it somewhere else
LDA $0129; in msu busy mode, e.g., fade flag or ready flag set
BNE $01
end:
RTL

LDA $0127 ; fade flag set?
cmp #$f1; fade down Zero set
beq fadeZero
cmp #$f2 ;fade down Half set?
beq fadeHalf
cmp #$f3 ; fade up Full set?
beq fadeFull
; if no fade, there's now sd2snes check whether track is ready
; here you can now check if track ready for sd2snes
bit $2000
bvs end    ; track not ready
STZ $0129  ; clear msu busy flag
; store now $2007, 2006, check spc, whatever
;LDA $2000
;AND #$08
;BNE playSPC
;lda $loopValue ;load loop value (01 or 03)
;sta $2007  
;lda #$FF   ;volume
;sta $2006
;sta $012b ; set full volume to fade later
;RTL
;
;playSPC:
;LDA track
;STA $2140
;RTL

fadeZero:
lda $012b ; current volume
dec
dec
dec
cmp #$10 ; if below $10, zero
bcs $05 ; if not branch 5 bytes
lda #$00
sta $0129 ;reset msu busy flag
sta $2006
sta $012b ;set new current volume
jmp end

fadeHalf:
lda $012b
dec
dec
dec
cmp #$40 ; half volume reached?
bcs $03 ; if not branch 3 bytes
stz $0129 ; if half volume reset fade flag
sta $012b ; new current volume
sta $2006
jmp end

fadeFull:
lda $012b
inc
inc
inc
cmp #$fb ; is (more or less) max volume reached?
bcc $05 ; if not, branch 5 bytes
stz $0129 ; if yes reset fade Flag
lda #$FF; give full volume
sta $2006 ; set current volume
sta $012b
jmp end


Attachment is the working code in zelda as example
Attachments
MSU1 Code Library Attachment
alttp_shotrt.zip You don't have permission to download attachments.(1 Kb) Downloaded 3 times


Last edited by Conn on Tue 26 Sep 2023 - 8:30; edited 2 times in total
Conn
Conn

MSU1 Code Library Image212

Since : 2013-07-01

Back to top Go down

MSU1 Code Library Empty Re: MSU1 Code Library

Post by Cubear Thu 21 Sep 2023 - 21:53

lol, that's accounted for, sort of.
in the patches where i use that code i set the volume to FE instead of FF so it's divisible by 2 evenly.

That aside, I'm happy to have everybody contribute to this thread! it might make developing patches easier and more time efficient in the future when most things you could want from MSU1 is easily copy + pasted.
Cubear
Cubear

MSU1 Code Library Image211

Since : 2021-11-17

https://www.patreon.com/Cubear

Back to top Go down

MSU1 Code Library Empty Re: MSU1 Code Library

Post by Conn Thu 21 Sep 2023 - 23:11

Indeed an awesome idea!
Yes, it's better to work with BCS/BCC when greater/smaller, equal than... but I mix this up all time as well. Bcs is less but not equal than 0 in substraction, BCc is more or equal 0 on addition or way round. I forgot, lol
Conn
Conn

MSU1 Code Library Image212

Since : 2013-07-01

Back to top Go down

MSU1 Code Library Empty Re: MSU1 Code Library

Post by Cubear Thu 21 Sep 2023 - 23:56

lol, i have to google it a lot. every time i need to know i look at this:
https://ersanio.gitbook.io/assembly-for-the-snes/the-basics/branches
Cubear
Cubear

MSU1 Code Library Image211

Since : 2021-11-17

https://www.patreon.com/Cubear

Back to top Go down

Back to top

- Similar topics

 
Permissions in this forum:
You cannot reply to topics in this forum