Jump to content
  • 1

Need help with BASIC/ASM access to VERA sound


K4TFJ
 Share

Question

I have succeeded in setting up sound from BASIC using the following:

300 REM =========================================== SOUND SETUP
310 VPOKE 1,$F9C0,255
320 VPOKE 1,$F9C1,5
330 VPOKE 1,$F9C3,%10000000

Then later in the program, I turn it on and off:

4300 SP=TI+DU
4310 VPOKE 1,$F9C2,255
4320 IF TI<SP THEN GOTO 4320
4330 VPOKE 1,$F9C2,0

This all works fine. I will be honest I do not know exactly what each VPOKE is doing other than the $F9C2. Any help in understanding what is doing would be grateful.

Secondly, I do not know how to increase the volume. I can hear the tone, but it is not as loud as I think it could be. Help!

And last but certainly not least... how do I do the same thing in ASM? I know there is banking involved and could use some help.

I have created a BASIC program to iron out the details of my program prior to attempting the ASM version. I have attached a copy for those interested. It is by no means finished, nor pretty.

 

 

MORSE6.PRG

Link to comment
Share on other sites

9 answers to this question

Recommended Posts

  • 0

If you look in x16.inc I define the following constant:

VRAM_psg       = $1F9C0

I use that as the basis of all PSG operations, using a fixed offset for the parameter being changed (e.g. volume is in the third byte of each channel, so I use an offset of 2) and then taking the channel number and shifting it left twice (to do a quick x4) to index into the channel's 4-byte section of VRAM (e.g. channel 2 starts at 8 bytes into the PSG registers, so 2 << 2 also gets added to the address).

So, say you want to max the volume of channel X of the PSG, the VRAM address you need to modify is $1F9C0 + 4X + 2. You need to read that in, then OR it with the maximum value (63 or $3F) and store it back to VRAM. The OR will prevent you from modifying the L/R channel bits in the same byte.

Link to comment
Share on other sites

  • 0

 

Quote

My program MakeWave is an example of using assembly, and acts as a tool to discover how the different parameters in the PSG work:

I cant seem to locate any address references in your ASM file that correspond to the ones i am using. Am I doing something totally different with a different "sound generator"?

 

Link to comment
Share on other sites

  • 0
4 minutes ago, K4TFJ said:

 

I cant seem to locate any address references in your ASM file that correspond to the ones i am using. Am I doing something totally different with a different "sound generator"?

 

The PSG registers aren't exposed to the CPU. They must be accessed through the VERA's ports.

Link to comment
Share on other sites

  • 0

Are the channel names zero indexed? (start with 0)

VPOKE 1,$F9C0,255    // low frequency byte?
VPOKE 1,$F9C1,5        // high frequency byte?
VPOKE 1,$F9C2,255   // L-R-Volume

VPOKE 1,$F9C3,%10000000   // Waveform and pulse width?

So with my example above: this must be channel 0, with frequency set to $05ff (will have to look at the calcs and see what that is)

The 1,$F9C2,255 being this:
255 = 1111 1111, so 11xx xxxx means Left and Right are turned on?
and xx11 1111 means the Volume is maxed?

Am I getting there?

 

Edited by K4TFJ
Link to comment
Share on other sites

  • 0

I cannot load and list the program MORSE6.PRG. I've tried

../x16-emulator/x16emu -prg MORSE6.PRG
x16emu -prg MORSE6.PRG
../x16-emulator/x16emu or x16emu
and then type in: LOAD "MORSE6.PRG"

I have a latest locally compiled x16emu from GitHub and the latest x16emu from snap https://snapcraft.io/x16emu.

I wrote a test program for a subroutine for BASICODE-3 and -3C that uses PSG:

Quote

10 PRINT "PITCH (0-127, 60=C4) AND VOLUME (0-15): SP,SV";
20 INPUT SP,SV
30 GOSUB 400
40 END
400 REM SOUND/BEEP/PLAY TONE FOR BASICODE-3 AND -3C FOR COMMANDER X16
402 REM SP=60:C4, 69:A4, 72:C5.
404 REM SV=15:MAX VOLUME, 7:NORMAL VOL, 0:SILENCE.
406 REM TODO: SD IS THE DURATION IN TENTH OF A SECOND.
408 OF=440*2^((SP-69)/12):REM SP RANGE 0-127
410 PRINT OF
412 OW=OF/(48828.125/2^17)
414 PRINT OW
416 OS=$F9C0:REM PSG FIRST CHANNEL/VOICE
418 OH=INT(OW/256)
420 OL=INT(OW-256*OH)
422 VPOKE 1,OS,OL
424 VPOKE 1,OS+1,OH
426 VPOKE 1,OS+3,63
428 IF SV=0 THEN OV=0:GOTO 432
430 OV=$C0+4*SV+3
432 PRINT OV
434 VPOKE 1,OS+2,OV
444 FOR OI=1 TO 10000:NEXT:REM TODO
446 VPOKE 1,OS+2,0
448 RETURN

Start with e.g.:
x16emu -bas psgtest.bas -echo

psgtest.bas

Link to comment
Share on other sites

  • 0
Posted (edited)
On 5/26/2022 at 1:38 PM, mobluse said:

I cannot load and list the program MORSE6.PRG. I've tried

../x16-emulator/x16emu -prg MORSE6.PRG
x16emu -prg MORSE6.PRG
../x16-emulator/x16emu or x16emu
and then type in: LOAD "MORSE6.PRG"

 

MORSE6.PRG should be named MORSE6.BAS - it's a .bas file (plaintext BASIC)

x16emu -bas MORSE6.PRG
It doesn't have a trailing carriage-return either, so you'll need to hit ENTER on the last line before typing RUN

Edited by ZeroByte
  • Thanks 1
Link to comment
Share on other sites

  • 0
  • Super Administrators
On 9/1/2020 at 1:18 PM, K4TFJ said:

This all works fine. I will be honest I do not know exactly what each VPOKE is doing other than the $F9C2. Any help in understanding what is doing would be grateful.

Secondly, I do not know how to increase the volume. I can hear the tone, but it is not as loud as I think it could be. Help!

And last but certainly not least... how do I do the same thing in ASM? I know there is banking involved and could use some help.

I have created a BASIC program to iron out the details of my program prior to attempting the ASM version. I have attached a copy for those interested. It is by no means finished, nor pretty.

MORSE6.PRG 3.27 kB · 127 downloads

 

So the reason for VPOKE is that VERA uses vectored communication. What that means is that to communicate with VERA, you have to set one set of registers with the address and another register with the data. VPOKE hides these details by setting the address registers for you.

So what you're doing with that first VPOKE is three things:

  1. This sets the VERA bank register to 1
  2. Sets the VERA address L and H registers to $F9C0
  3. Sets the VERA data register to 255

The VERA address registers live at $9F20-9F21, and the bank/increment register lives at $9F22. 

So to set an address of $1:F9C0 (bank 1, addr $F9C0) in VERA, you would need to do this in BASIC:

POKE $9F25,0   : REM always set the ADDRSEL register to make sure you are using the correct port
POKE $9F22,1   : REM Sets the bank register to 1
POKE $9F21,$F9  :REM high byte of address
POKE $9F20,$C0  :REM low byte of address
and then set the data value with
POKE $9F23, 255

So now that we see how you can directly address the registers, you can easily translate this to assembly code:
STZ $9F25  
LDA #1
STA $9F22
LDA #$F9
STA $9F21
LDA #$C0
STA $9F20
LDA #$FF
STA $9F23

(Note the STZ is a 65C02 instruction. If STZ doesn't assemble, you may need to enable the extended 65C02 opcodes in your assembler or fall back to LDA #0 / STA $9F25).

That's just to write one byte. You actually need to write at least 3 bytes to set the frequency and volume, so you'll want to set the Address Increment. This is the upper 4 bits of $9F22, and you can set the increment to 1 by writing $1x to that register. Since you're already writing a 1 there, you can instead write $11 to automatically increment the address register every time:

STZ $9F25  
LDA #11
STA $9F22
LDA #$F9
STA $9F21
LDA #$C0
STA $9F20
LDA #$FF
STA $9F23
LDA #$05
STA $9F23
LDA #$FF
STA $9F23
LDA #$80
STA $9F23

The sound will now be playing. To turn it off, 

STZ $9F25  
LDA #1
STA $9F22
LDA #$F9
STA $9F21
LDA #$C2
STA $9F20
STZ $9F23

I should mention that these are "off the top of my head" instructions. I don't have access to the emulator to try this, so it may need tweaking. If you get this to work, maybe you can post the code (and let us know which assembler) you used. 

I have actually been considering writing a Morse trainer. Maybe it's time to write one. 😃

--... ...-- / --- -- / -.. . / - --- -- -..- .--. ....- .---- .----

 

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

Please review our Terms of Use