Jump to content
IGNORED

Playing basic sound directly in ASM


LordKraken

Recommended Posts

Hello guys,

 

I'm trying to play a sound directly in "lyxass-style" asm, without the use of any library.

I looked at the code from pong1k from Sage, and actually managed to play a sound in my own program, but I basically just figured out what the sound code was and copy/pasted it .

 

I'm trying to understand what the code is ACTUALLY doing now, so any help would be greatly appreciated :)

(my guess is that we poke some value at special magic address...?)

Note that it is just code snippet from different part of the code.

; Sound definition..?
SetSound::						; stereo sound
	lda #$42					; Beep metal sound
	sta $fd50
	lda #$3B
	sta $fd25
	lda #$24
	sta $fd21

; Code to play the sound
.playsound
	lda #80
	sta $fd20 					; Volume
	jmp .main

; As the comment says... 
.loop
	lda $fd0a 					; No clue what this is doing but it makes the sound better
	bne .loop

; apparently decrease the volume and eventually stop the sound
	lda $fd20
	_IFNE
		dec $fd20
		jmp .loop
	_ENDIF

Edited by LordKraken
Link to comment
Share on other sites

There is 4 sets of registers for sound.

 

#define STEREO_REG (*(char *)0xfd50)
#define VOLUME_REG(chan) (*(char *)(0xfd20 + 0 + (chan & 3) * 8))
#define FEED_REG(chan) (*(char *)(0xfd20 + 1 + (chan & 3) * 8))
#define OUT_REG(chan) (*(char *)(0xfd20 + 2 + (chan & 3) * 8))
#define SHIFT_REG(chan) (*(char *)(0xfd20 + 3 + (chan & 3) * 8))
#define BKUP_REG(chan) (*(char *)(0xfd20 + 4 + (chan & 3) * 8))
#define CTLA_REG(chan) (*(char *)(0xfd20 + 5 + (chan & 3) * 8))
#define CNT_REG(chan) (*(char *)(0xfd20 + 6 + (chan & 3) * 8))
#define CTLB_REG(chan) (*(char *)(0xfd20 + 7 + (chan & 3) * 8))
The VOLUME is obvious.
The BKUP is the pitch.
The rest are related to waveform.
The OUT reg is where you can bang PCM waveform to produce digitized sound.
Link to comment
Share on other sites

When I wrote the sound routines for Lacim's Legacy I quickly realized that the common docs arent toooo helpful there :-) Emulator sources helped me best so far.

 

; No clue what this is doing

That made me cry a little, though :-)

 

fd0a is the timer for rasterlines/vblank.

Link to comment
Share on other sites

Thanks Karri, I'll look at the code again with this piece of information :) (I think the smileys are hiding some relevant information...)

 

@enthusi Well it might be obvious for you but without documentation I can just guess ^^ Plus I'm from this generation of programmers who still know what asm is and how it works but has never done anything more than practicing a bit at school (believe me, the "millenial" programmers are even worse they don't even know what ASM is :D).

 

Now does that snippet also mean that the sound is going to sound different every time, depending on how much time is left before a vblank?

Also what is in $fcb0?

 

thanks :)

 

 

Also what is in $fcb0?

 

Found the epyx document and apparently lda $fcb0 is used to check whether the josytick button is pressed... am I right? :)

Edited by LordKraken
Link to comment
Share on other sites

Thanks Karri, I'll look at the code again with this piece of information :) (I think the smileys are hiding some relevant information...)

 

@enthusi Well it might be obvious for you but without documentation I can just guess ^^ Plus I'm from this generation of programmers who still know what asm is and how it works but has never done anything more than practicing a bit at school (believe me, the "millenial" programmers are even worse they don't even know what ASM is :D).

 

Now does that snippet also mean that the sound is going to sound different every time, depending on how much time is left before a vblank?

Also what is in $fcb0?

 

thanks :)

 

 

Found the epyx document and apparently lda $fcb0 is used to check whether the josytick button is pressed... am I right? :)

 

What do you mean "without documentation". There are the original docs either as picture or html. So instead of "guessing" try "reading".

Link to comment
Share on other sites

I found it much easier to get started with assembler on the c64 (not that I've done much of it, it's so slow when you're a beginner at it), but at least it was faster understanding the general concepts, because the documentation and books are so much more beginner friendly on the c64.

 

I found these two sites for lynx hardware addresses. 42bs site for more thorough documentation:

and this one for a quick reference list:
Edited by Turbo Laser Lynx
Link to comment
Share on other sites

Assembler is great fun. You will see! And in my opinion the only real Option for 8bit systems. You will often check the Hardware Register appendix. In the end it contains basically all you need. Lynx isnt that hard to access. No complex gfx modes, etc. Fd0a counts down to 0 each frame. The loop is a so-called busy loop that Waits until the timer reaches zero. So it ends once per frame. Debugging via screen colors is quite helpful on lynx. Try lda $fd0a then sta $fda0 in the loop. After that add a few LSR between lda and sta and try to understand what it does.

Link to comment
Share on other sites

What do you mean "without documentation". There are the original docs either as picture or html. So instead of "guessing" try "reading".

 

This is an odd answer. I'm just asking for help, no need to patronize me;)

 

First of all I didn't know about the doc, because I didn't even know what to look for.

But more than that I also clearly stated I am not (definitely not!) an ASM programmer, so what is obvious for you guys might not be for me.

 

Anyway, thanks Karri and Sampo for the information and the link, I learnt new stuff :)

 

@enthusi thanks a lot! That sounds like a reasonable approach to understand all of that a bit better (last time I touched asm it was x86 in 1998... :D )

Edited by LordKraken
Link to comment
Share on other sites

 

This is an odd answer. I'm just asking for help, no need to patronize me;)

 

First of all I didn't know about the doc, because I didn't even know what to look for.

But more than that I also clearly stated I am not (definitely not!) an ASM programmer, so what is obvious for you guys might not be for me.

 

 

 

"patronize", well, I was even polite not the say RTFM. I just expect that someone does a bit of search him/herself before asking questions. And "finding" the Lynx documentation shouldn't be a big deal (try Google: atari lynx documentation). And this is by no way related to assembly. It is basic programming.

 

A lot of gus here (me included) are willing to answer questions, but I expect a sign that the questioner did try to solve the problem him/herself first.

Link to comment
Share on other sites

If you are not interested in libraries but you just want to make sound directly then I would suggest looking at the C-version of abcmusic. Everything is written in C with no hidden libraries.

 

Here is a bit from "Shaken, not stirred" for digital saying of "Big.. Bada big boom". I did not use a timer but put in a dummy for loop doing nothing to get the right sound out of the beast.

 

        tgi_sprite(&Smushroom);
        tgi_setcolor(COLOR_YELLOW);
        tgi_outtextxy(70, 40, "Big...");
        tgi_outtextxy(30, 50, "Bada Big Boom");
        tgi_updatedisplay();
        lynx_snd_pause();
        lynx_load((int)&BIGBADABOOM_FILENR);
        musa = bigbadaboom;
        CTLB_REG(0) = 0x0;
        CTLA_REG(0) = 0x10;
        STEREO_REG = 0;
        VOLUME_REG(0) = (char) 255;
        for (i = 0; i < 21000; i++) {
            for (j = 0; j < 15; j++) {
                isfrog = 0;
            }
            OUT_REG(0) = (char)*musa;
            musa++;
        }
        VOLUME_REG(0) = (char) 255;

The file BIGBADABOOM is just an 8kHz mono file with one byte per sample.

 

.export _bigbadaboom
.segment "BIGBADABOOM_RODATA"
_bigbadaboom:
.byte  253
.byte  250
.byte  251
.byte  251
.byte  251
.byte  251
.byte  250
.byte  248
.byte  249
.byte  251
.byte  253
.byte  253
.byte  0
.byte  2
.byte  1
.byte  254
.byte  252
.byte  251
.byte  248
.byte  248
...
Link to comment
Share on other sites

Dude seriously, I spent an evening and a half reading the code of your pong1k example. For someone with no prior experience of ASM, especially not 6502, it was a difficult and exhausting experience (although very interesting).

 

I'm not coming up with random question while taking my shower to just annoy people. I figured that those memory addresses were somehow specials and the only thing I was asking was indeed "What are they really, and where can I learn more".

An answer with a link to the actual low-level documentation would have been good enough. Worst case scenario, just don$t answer.

But NO NEED to be condescending. Really.

 

Now I realize you've done a lot for the developer community, and I'm grateful for that, but again it does NOT grant you the right to be mean to people.

Link to comment
Share on other sites

Now I realize you've done a lot for the developer community, and I'm grateful for that, but again it does NOT grant you the right to be mean to people.

 

Is it "mean" to ask for a little searching before asking? If so, I am mean.

If you'd asked "Why is this code reading the VBL counter register until it is zero?" might have brought you the answer w/o even asking.

Link to comment
Share on other sites

I guess we can not overestimate the efforts that went into all the documentation and libraries, tool-chains that are around and openly distributed.

That was already like 25 years ago? BS93 iirc ;-)

The Lynx homebrew community seems to be quite small and on top of that relying on high-level languages/interfaces for decades now.

So there remain only very few people with in-depth knowledge. I myself try to avoid asking for 'solutions' but I also really much enjoy discovering things on my own and re-inventing the wheel.

And I still ask alot :)

If you are fully new to assembler I think the direct read/write of registers is maybe a bit new concept.

To become familiar I mostly dont use labels for registers either but their hex-adresses directly instead. Helps you reading disassemblies alot!

Just by playing with the palette colors in 'real time' will give you a good feeling of how things work.

But be aware that the Lynx emulators only render on a line-by-line basis, whereas the real Lynx will start using the new color right when you change it.

The above mentioned colorbars will look clean and stable when used in horizontal interrupt but not so much in a busy loop. You will see when you test on real hardware (old and new LCD alike).

Assembler will allow for much more efficient code, including selfmodifying code which is a completely new concept for C-coders or people used to execute code from ROM only.

(Some assembler programmers dont like it either, though :)

Don't worry about being new to it. The good thing about old things: they dont really age. Never too late.

  • Like 1
Link to comment
Share on other sites

There is also a newcc65 version of abcmusic in the same repo I mentioned earlier. If you look at the file abcmusic.m65 you have the driver for playing music on the newcc65 platform. There is also a newcc65 version that plays 4-voice kantele music called abcmini.c

  • Like 1
Link to comment
Share on other sites

Well nice to hear that :)

 

I understand your point, make no mistake, sometimes helping with real basic stuff can get annoying.

When that happen, and you're not in a good day, just ignore the question, or put a link w/o comment, that's ok.

 

No one can thank you enough, you, Karri and a few others, for giving us all these tools to create games on our favourite handheld!

But with great power come great responsibilities, and empowering people is one of them imho (not bashing then though ^^).

 

That said, ich hoffe das wir friede machen kann ;)

Have a nice day!

  • 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.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   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.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...