Simple way to play sound effects on MSX PSG

By albs_br

Expert (67)

albs_br's picture

27-07-2020, 18:38

I haven't any experience with sound, in any language or platform, all my game prototypes were without (or almost) sound.

I managed to convert this BASIC routine to assembly, a simple "get item" sound for games (MSXPen here):

10 SOUND 8,15:SOUND 0,93:SOUND 1,0:FOR F=0 TO 20:NEXT F
20 SOUND 0,45:SOUND 1,0:FOR F=0 TO 29:NEXT F: SOUND 8,0

Assembly code (MSXPen here):

    ld b, 255
.loop1:
    ld a, 0					; Channel A Period (low 8 bits)
    ld e, 93
    call BIOS_WRTPSG

    ld a, 1					; Channel A Period (high 4 bits)
    ld e, 0
    call BIOS_WRTPSG
    
    djnz .loop1


    ld b, 255
.loop2:
    ld a, 0					; Channel A Period (low 8 bits)
    ld e, 45
    call BIOS_WRTPSG

    ld a, 1					; Channel A Period (high 4 bits)
    ld e, 0
    call BIOS_WRTPSG

	djnz .loop2

    ld a, 8					; Channel A Volume
    ld e, 0
    call BIOS_WRTPSG

    ret

Two questions:
Is this the right or adequate way to play a small sound effect?
How can I do a shot or explosion sound? A small and simple music for level complete or title screen?

I've seen some open source code for games, but is not very easy to understand other people's code in Assembly. It looks like the PSG values are stored as data, am I right?

Login or register to post comments

By albs_br

Expert (67)

albs_br's picture

27-07-2020, 19:54

Found this article from 1985: http://www.muzines.co.uk/articles/msx-and-music/3782
It has an interesting listing for an explosion sound:

10 SOUND 0,0: SOUND 6,250: SOUND 7.82
20 SOUND 2,130: SOUND 8,16: SOUND 13.0

Besides the typo (mistakenly using dot instead of comma), it has a dangerous and potentially destructive using of the two most significant bits of the register number 7.
I know BASIC's SOUND command treat this, but Assembly don't.

By albs_br

Expert (67)

albs_br's picture

27-07-2020, 19:58

Off topic: The thing I most hate about WebMSX is when you want to run a Basic program, hit F5 key, but the focus is outside of the emulator, and the page reloads wiping out all your code... Evil Crazy

By Grauw

Ascended (9176)

Grauw's picture

27-07-2020, 20:09

albs_br wrote:

Is this the right or adequate way to play a small sound effect?
How can I do a shot or explosion sound? A small and simple music for level complete or title screen?

I've seen some open source code for games, but is not very easy to understand other people's code in Assembly. It looks like the PSG values are stored as data, am I right?

Often effects are indeed programmed using a matrix of register values, or some variation thereof. Each interrupt the register values of the next column of the matrix are set, and you will get a sound effect which evolves over time.

Designing these effects can be done with a tool like AYFX. Here’s a nice demonstration video.

By santiontanon

Paladin (1024)

santiontanon's picture

27-07-2020, 21:14

Exactly, the basic form is to store SFX like this:

db registernumber1, registervalue1
db registernumber2, registervalue2
...
db registernumbern, registervaluen

At each interrupt, you read one row and sent the value to the appropriate register.

Now, you can expand on that. For example, you might want to send more than one command per interrupt. So, you could use special values in the matrix, to indicate this. For example, you could use the value "255" to separate the commands that you want to send to the PSG in consecutive interrupt frames, like this:

db regn1, regv1, regn2, regv2, 255
db regn3, regv3, 255
...

So, at each interrupt, you read pairs until you reach a 255, and then stop.

You can, of course expand this with any additional commands other than 255 as you see fit.

You can see all the SFX used in The Menace from Triton game, defined in mainly this way (with a few more bells and whistles, but nothing much), here: https://github.com/santiontanon/triton/blob/master/src/sfx.asm

By albs_br

Expert (67)

albs_br's picture

27-07-2020, 22:45

Very interesting.

Is there any way to read the PSG registers in Basic? Are the values mapped somewhere in RAM?

By Grauw

Ascended (9176)

Grauw's picture

27-07-2020, 22:58

All PSG registers are readable, but not from BASIC afaik.

See the PSG manuals here (I think the YM2413 manual is a little easier to read than the AY3 one).

By ARTRAG

Enlighted (6405)

ARTRAG's picture

29-07-2020, 07:56

Have a look at this online editor
https://zx.remysharp.com/audio/#src=MjM3LDIzNiwwLDIsMjM2LDcw...
It produces sfx files for the player above

By theNestruo

Master (158)

theNestruo's picture

29-07-2020, 09:05

albs_br wrote:

Off topic: The thing I most hate about WebMSX is when you want to run a Basic program, hit F5 key, but the focus is outside of the emulator, and the page reloads wiping out all your code... Evil Crazy

For that particular use case (running BASIC programs) maybe https://msxpen.com/ suits better.

ARTRAG wrote:

Have a look at this online editor (...)
It produces sfx files for the player above

I didn't knew there was an ayfxedit online! :D
"AY Sound FX Editor (Improved)" recently published a dependency-free executable (https://github.com/Threetwosevensixseven/ayfxedit-improved/r...) so, if any of you were affected by the "Missing library (rtl250.bpl)" problem... it is gone now.

By santiontanon

Paladin (1024)

santiontanon's picture

29-07-2020, 18:14

I didn't know AYFXEdit was online either, very nice!!! I always had to use wine to run it, which is never nice, as I think it was Windows only!