User:Freem/Sound Drivers/STSOUND

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

 * – command buffer (32 bytes)
 * – previous command (1 byte)
 * – current command (1 byte)
 * – music data pointer (2 bytes)

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