User:Freem/Sound Drivers/STSOUND

From NeoGeo Development Wiki
Jump to navigation Jump to search

The STSOUND engine is found in the NeoGeo 3D! demo by Leonard of Oxygene. It is notable in that it uses the SSG portion of the YM2610 to playback an Atari ST song.

Description

Leonard describes the engine as follows:

"68k only send a "tick" command at 50hz (ATARI music are 50hz). Then Z80 wake up at 50hz, and depack YM registers (all data is packed in Z80 ROM, the packed music is about 43KB). And then the magic trick is that NeoGeo has a YM2160 chip, far better than ATARI YM2149. BUT, the YM2160 has a SSG part (simple sound generator), which is hardware compatible with YM2149 :) So no software emulation, I simply put the registers into the SSG par[t] of the YM2160" (quoted post)

RAM Usage

  • $F800-$F81F – command buffer (32 bytes)
  • $F820 – previous command (1 byte)
  • $F821 – current command (1 byte)
  • $F822 – music data pointer (2 bytes)

Command Codes

Code Description
0x01 Slot Switch
0x03 Reset
0x10 Sound driver tick

Code

The bulk of the work is done in Command 0x10, which is sent from the 68K at 50Hz.

 handleCommand:
 	cp #0x10 ; is this command $10?
 	jr Z, command10
 	ret
 
 command10:
 	ld hl, (0xF822) ; current music data pointer
 	ld d, #0
 
 loc_134:
 	ld a, d
 	or a
 	jr NZ, loc_13C
 
 loc_138:
 	ld b, (hl) ; load value from music data
 	inc hl ; increment music data pointer
 	jr loc_144
 ; ---------------------------------------------------------------------------
 
 loc_13C:
 	cp #8
 	jr Z, loc_138
 	cp #0xE
 	jr Z, loc_153
 
 loc_144:
 	bit 7, b ; check for MSB
 	jr Z, loc_14D ; branch if top bit not set
 	ld e, (hl) ; load value from music data
 	inc hl ; increment music data pointer
 	call write_45 ; write values to ports $04 and $05
 
 loc_14D:
 	ld a, b
 	add a, a
 	ld b, a
 	inc d
 	jr loc_134
 ; ---------------------------------------------------------------------------
 
 loc_153:
 	ld (0xF822), hl ; update music data pointer
 	ld a, (hl) ; get first value from music data
 	cp #0xFF
 	jr NZ, handleCommand_end ; end if first value is not $FF
 
 	inc hl ; increment music data pointer
 	ld a, (hl) ; get second value from music data
 	cp #0xFF
 	jr NZ, handleCommand_end ; end if second value is not $FF
 
 	ld hl, #musicData ; music data
 	ld (0xF822), hl ; update music data pointer
 
 handleCommand_end:
 	ret