LIB: pmmusic

Background Music (BGM) and sound effects (SFX) playback

Note: IRQ_TMR2_HI must be included in HEADER IRQ flags list for the mixer to work

pmmusic_ram.s

Type: Header File

Dependency: pminit.s

Including Rules: Must be after RAM (RAM_BEGIN) declaration

ROM/RAM Usage: 67 Bytes of RAM

pmmusic_rom.s

Type: Source File

Dependency: pminit.s and pmmusic_ram.s

Including Rules: Must be after ROM (HEADER) declaration and inside Bank 0

ROM/RAM Usage: 1.2KB of ROM

pmmusic_macro.s (Optional)

Type: Header File

Dependency: pminit.s, pmmusic_ram.s and pmmusic_rom.s

Including Rules: Can be declared anywhere (once)

ROM/RAM Usage: None

Functions

Functions found in pmmusic_rom.s

Functions Parameters Description
Initialize    
call pmmusic_init BA = RAM Pointer
HL = Master time
No return
Initialize tracker
Manage master time    
call pmmusic_setmastertime HL = Master time
No return
Modify master time (affects both BGM and SFX)
call pmmusic_getmastertime No parameters
Return HL = Master Timer
Get master time
Manage volume    
call pmmusic_setvolbgm A = Volume
No return

Set BGM master volume
0 (Silence) to 3 (Max), default is 3
If out of range, the call will be ignored

call pmmusic_getvolbgm No parameters
Return A = Volume
Get BGM master volume
call pmmusic_setvolsfx A = Volume
No return

Set SFX master volume
0 (Silence) to 3 (Max), default is 3
If out of range, the call will be ignored

call pmmusic_getvolsfx No parameters
Return A = Volume
Get SFX master volume
Play music (BGM)    
call pmmusic_playbgm B = BGM Address (Hi)
HL = BGM Address (Med & Lo)
No return
Play BGM, address must be a list of patterns
call pmmusic_stopbgm No parameters
No return
Stop BGM
call pmmusic_isplayingbgm No parameters
Return Non-Zero if playing
Return A != 0 if playing
Is playing BGM?
Play sound effect (SFX)    
call pmmusic_playsfx B = SFX Address (Hi)
HL = SFX Address (Med & Lo)
No return
Play SFX, address must be a patterns
call pmmusic_stopsfx No parameters
No return
Stop SFX
call pmmusic_isplayingsfx No parameters
Return Non-Zero if playing
Return A != 0 if playing
Is playing SFX?

Macros

Macros found in pmmusic_macro.s

Macro Description
PATTERN pataddr Must be inside BGM
Define pattern, BGM must have at least 1 pattern
pataddr = Label of pattern
ROW note_id, pwm_amt, volume, wait_amt Must be inside SFX or Pattern
Define row inside pattern
note_id = N_* definition
pwm_amt = Pulse-Width, 0 to 255, 128 = 50% (Square)
volume = Volume, 0 to 3
wait_amt = Wait ticks, 1 to 255
Set note_id to N____ and pwm_amt to -1 to not update note (saves 4 bytes)
Pulse-width changing require note definition!
WRITE_RAM address, value Must be inside SFX or Pattern
Write to RAM
address = Relative adress
pwm_amt = Pulse-Width, 0 to 255, 128 = 50% (Square)
MARK loop_id Must be inside SFX or Pattern
Mark position for loop
loop_id = Loop identification, 0 to 3
LOOP loop_id, loop_num Must be inside SFX or Pattern
Loop back
loop_id = Loop identification, 0 to 3
loop_num = Number of loops, 0 to 255
NEXT_PAT Must be inside Pattern
Go to next pattern
GOBACK_PAT pattnum Must be inside Pattern
Mark position for loop
pattnum = Number of patterns to go back
0 will repeat same pattern over and over
1 will jump to the previous pattern
END_SOUND Must be inside SFX or Pattern
End BGM/SFX playback

Defines

Definitions found in pmmusic_macro.s

Notes

Definition Description
N____ Don't change note
N_C_n Play C, n is octave number between 1 and 7
N_CSn Play C#, n is octave number between 1 and 7
N_D_n Play D, n is octave number between 1 and 7
N_DSn Play D#, n is octave number between 1 and 7
N_E_n Play E, n is octave number between 1 and 7
N_F_n Play F, n is octave number between 1 and 7
N_FSn Play F#, n is octave number between 1 and 7
N_G_n Play G, n is octave number between 1 and 7
N_GSn Play G#, n is octave number between 1 and 7
N_A_n Play A, n is octave number between 1 and 7
N_ASn Play A#, n is octave number between 1 and 7
N_B_n Play B, n is octave number between 1 and 7

Example

  .include "pm_libs/pminit.s"
  .include "pm_libs/pmmusic_macro.s"

  RAMBEGIN	; same as ".org RAM"
	.include "pm_libs/pmmusic_ram.s"
variable:	.ds 1
  RAMEND	; Optional, report RAM size

  ; 1st: Game Code string, must be 4 characters
  ; 2nd: Game Title string, must be 12 characters
  ; 3rd: Interrupts to map, OR flags for multiple interrupts
  ; 4th: Extra flags
  ; Note! For pmmusic to work you MUST define IRQ_TMR2_HI
  HEADER "PoKe", "PMMusic TsT ", IRQ_KEY_POWER | IRQ_TMR2_HI, 0

  .include "pm_libs/pmmusic_rom.s"

  ; Power button, shutdown PM
irq_key_power:	; Interrupt function (same name as definition but in lowercase)
  cint CINT_SHUTDOWN	; Call shutdown in BIOS

  ; Code starts here
main:
  pm_init

  ; Enable power key interrupt
  mov [n+IRQ_ENA3], IRQ_ENA3_KEY_POWER
  mov [n+IRQ_PRI2], IRQ_PRI2_KEY_PAD

  ; Initialize PM Music
  mov ba, 0	; RAM pointer isn't needed
  mov hl, $00FF	; Master time of 255 (approx. 61 Hz)
  call pmmusic_init

  ; Enable interrupts
  mov f, ENABLE_IRQ

  ; Play PM Intro sound
  mov b, pm_intro >> 16
  mov hl, pm_intro
  call pmmusic_playbgm

loop:
  halt
  jmp loop

  ; 2 bytes alignment is recommended for pmmusic data
  ; data can be located anywhere in 2MB range and support bank crossing
  .align 2

  ; PM Intro list of patterns
pm_intro:
  PATTERN pm_intro_pat

  ; PM Intro pattern
pm_intro_pat:
  ROW N_E_5, $80, 3, 4
  ROW N____,  -1, 2, 4
  ROW N_A_5, $80, 3, 4
  ROW N____,  -1, 2, 4
  ROW N____,  -1, 0, 9
  ROW N_D_6, $80, 3, 4
  ROW N____,  -1, 2, 4
  ROW N_CS6, $80, 3, 4
  ROW N____,  -1, 2, 4
  ROW N_A_5, $80, 3, 4
  ROW N____,  -1, 2, 4
  ROW N_E_6, $80, 3, 4
  ROW N____,  -1, 2, 4
  ROW N____,  -1, 0, 24
  ROW N_D_6, $80, 3, 3
  ROW N_A_6, $80, 3, 3
  ROW N_E_7, $80, 3, 3
  ROW N_B_7, $80, 3, 3
  ROW N_E_7, $80, 3, 3
  ROW N_B_7, $80, 3, 3
  ROW N____,  -1, 0, 6
  END_SOUND

  ROMEND	; Optional, report ROM size