TRS80 model 3 sound

Discussion about other targets
Post Reply
voidstar
New member
Posts: 6
Joined: Sun May 30, 2021 6:38 am

TRS80 model 3 sound

Post by voidstar »

Greetings,

I'm trying to do sound on a TRS-80, like in the game Eliminator for that platform.

I figured out sound for the Commodore and Apple, but I'm not seeing any notes for the TRS-80.

There are some manuals about TRS-80 BASIC that referenced a BEEP and SOUND command. But in the trs80gp.exe emulator, these commands didn't work (syntax error on both). Not that I want to use BASIC, but if the programming manuals suggest the system can perform sound (and even has a note/frequency chart), I'm not quite sure why those commands aren't working. And as mentioned, the game Eliminator has a few sound effects.

z88dk has worked great for me in compiling for the TRS-80 target, with very little change in my C code. I looked in libsrc/target/trs80 for any sound related examples, but didn't not see any.

Thanks for any help to point me in the right direction on this :)
voidstar
New member
Posts: 6
Joined: Sun May 30, 2021 6:38 am

Re: TRS80 model 3 sound

Post by voidstar »

I was able to make it work in cc65 with the sample below. I looked into USR(ARGS), disassembled that, which seems to be: load what is in 4121h into HL...
// e7 rst 0x20
// 2a2141 ld hl,(0x4121) == 16673 dec (load content at 0x4121 into HL)
// f8 ret m

But I made the adjustment to by-pass all that, and just directly load values into HL (which you can POKEW directory into that address).

....
// Based on BASIC sample referenced here:
// http://www.trs-80.com/wordpress/zaps-pa ... elanguage/

#define AUDIO_BASE 0xFACE
POKE(AUDIO_BASE , 33); // 0x21 LD HL
POKE(AUDIO_BASE+1, 0); // H placeholder (POKE here)
POKE(AUDIO_BASE+2, 0); // L placeholder (POKE here)
POKE(AUDIO_BASE+3, 77); // 4D ld c,l
POKE(AUDIO_BASE+4, 68);
POKE(AUDIO_BASE+5, 62);
POKE(AUDIO_BASE+6, 1);
POKE(AUDIO_BASE+7, 105);
POKE(AUDIO_BASE+8, 211);
POKE(AUDIO_BASE+9, 255);
POKE(AUDIO_BASE+10, 45);
POKE(AUDIO_BASE+11, 32);
POKE(AUDIO_BASE+12, 253);
// -----------------------
POKE(AUDIO_BASE+13, 60);
POKE(AUDIO_BASE+14, 105);
POKE(AUDIO_BASE+15, 211);
POKE(AUDIO_BASE+16, 255);
POKE(AUDIO_BASE+17, 45);
POKE(AUDIO_BASE+18, 32);
POKE(AUDIO_BASE+19, 253);
POKE(AUDIO_BASE+20, 13);
POKE(AUDIO_BASE+21, 16);
POKE(AUDIO_BASE+22, 238);
POKE(AUDIO_BASE+23, 175);
POKE(AUDIO_BASE+24, 211); // D3
POKE(AUDIO_BASE+25, 255); // FF
POKE(AUDIO_BASE+26, 201); // C9 RET

#asm
call AUDIO_BASE
#endasm

for (v = 1027; v >= 755; --v)
{
POKEW(AUDIO_BASE+1, v);

#asm
call AUDIO_BASE
#endasm
}
...
stefano
Well known member
Posts: 1681
Joined: Mon Jul 16, 2007 7:39 pm

Re: TRS80 model 3 sound

Post by stefano »

that poke sequence is creating a z80 machine code routine looping around the out (ff) instruction. I think that the existing z88dk functions are already built to work on that port.
Could you try the examples provided in the "sound" folder? are they all failing?
voidstar
New member
Posts: 6
Joined: Sun May 30, 2021 6:38 am

Re: TRS80 model 3 sound

Post by voidstar »

Oh - I'm not using any of the standard library and didn't notice the sound.h in the include folder :) I do recall a note that z88dk does include quite a bit of extra stuff in its library, although I wasn't sure how much of it applied to the TRS80.

So now I tried those sound folder samples - I'm not sure if bit_click() is working, but yes synth_play(xxx) and bit_synth(xxx) are working (with trs80gp emulator, ran as: trs80gp -m3 test.cmd -dx ). Nice examples, very cool.

However,

I think synth_phase/synth_play(xxx) is taking about 2387 bytes,

and bit_synth(xxx) is taking about 1041 bytes.


The POKE example earlier takes under 100 bytes and does provide a bit of audio range. But you just have to find a "safe" place to POKE it into - I wasn't sure of the 26 bytes after 0xFACE was "safe" (it's working for using trs80gp.exe -m3 -dx, but not sure if it's just coincidence).


Thanks for pointing out the samples! Now have a variety of sound options.
stefano
Well known member
Posts: 1681
Joined: Mon Jul 16, 2007 7:39 pm

Re: TRS80 model 3 sound

Post by stefano »

The bit_fx functions are smaller, the example program looks big because it uses them all together and includes the console output code.
stefano
Well known member
Posts: 1681
Joined: Mon Jul 16, 2007 7:39 pm

Re: TRS80 model 3 sound

Post by stefano »

Your function can be simply put in a code frame in C,

e.g. something like:

void mysound() {
#asm
defb 33,0,0, ...
#endasm
}
voidstar
New member
Posts: 6
Joined: Sun May 30, 2021 6:38 am

Re: TRS80 model 3 sound

Post by voidstar »

Yes, I considered that - except then it's harder to know the offset of where to POKE to adjust the H/L register values (and obviously you don't want the overhead of passing an argument). Some C compilers have the &&label option ("address of a label") but I don't think that worked for me in z88dk (it's not exactly a standard feature in some compilers). Or you can take the address of the function itself (except for me, I think z88dk also had some issue on the syntax for that -- I can't remember the specific issue I had; probably I was just tired and gave up too easily since the POKE option was working).

So poking an word at AUDIO_BASE+1 works out. You're right, the function-style would be better to make it just a natural part of whatever code-space your program uses. Then you POKE, something like:

void mysound() {..}

POKEW(&mysound+2, val); // Think that's what I tried initially, but just seems z88dk required me to cast &mysound somehow, or maybe define a function pointer typedef?
stefano
Well known member
Posts: 1681
Joined: Mon Jul 16, 2007 7:39 pm

Re: TRS80 model 3 sound

Post by stefano »

you may have noticed the #asm directive, labels and mnemonics are allowed ;)
User avatar
dom
Well known member
Posts: 1416
Joined: Sun Jul 15, 2007 10:01 pm

Re: TRS80 model 3 sound

Post by dom »

To take the address of a function it's pretty standard:

```
extern int test();

int main() {
void *ptr = test;
....
}
```

For what features are available for which target, <features.h> is useful and is driven by this spreadsheet: https://github.com/z88dk/z88dk/blob/mas ... atures.csv
Post Reply