Jump to content

New audio upload: Tiny PCM Synth


Recommended Posts

Tiny PCM Synth

View File

I wanted to explore the possibilities with the PCM output. This tiny synth generates a sweet tone from three sine waves, coated in a thin shiny silver layer of aliasing. To spice it up, I also added a delay effect. You can play it with your keyboard. Use Z and X to switch octaves.

I do not plan to follow this route any further, because the possibilities are quite limited with the X16. I am sure one could do better than I did, but the X16 doesn't have enough power to provide a whole lot of flexibility in the sound generation (at least with PCM).

Find the source here: https://github.com/biermanncarl/cx16-tiny-pcmsynth

Feel free to reuse the code for your own projects!



  • Like 4
Link to comment
Share on other sites

AMAZING JOB!!!!!! This likely wouldn't be reliable for use in an actual game though, considering how CPU-intensive synthesizing PCM audio on the fly is.

If you want to reduce the CPU usage though, have you thought about using some of the additional 65C02 instructions? All of them are said to be compatible with R38.

  • Thanks 1
Link to comment
Share on other sites

Thanks! I didn't know about the extra 65C02 instructions. Looking at them, I think they would rather benefit the keyboard polling code than the actual sound generation, unfortunately.

The question is rather, if the game would run reliably alongside this 😄

I think atm the CPU usage is 70-80% -- so you would still have a C64 equivalent of computing power left for the game 😉

Edited by kliepatsch
Link to comment
Share on other sites

  • 2 months later...
  • 2 weeks later...
  • 3 months later...
On 10/19/2020 at 1:18 AM, kliepatsch said:

Looking at them, I think they would rather benefit the keyboard polling code than the actual sound generation, unfortunately.

You can optimize an LDr #0 / STr pair into an STZ instruction, as long as the addressing mode for the store instruction is ZP, ZP,X, ABS, or ABS,X. If you're using the zero loaded in the register r as a value to pass to a subroutine (e.g. LDA #0; STA address; JSR subroutineThatTakesOnA), you could omit the STZ optimization for easier porting to an NMOS 6502 system.

X and Y can now be pushed or pulled. On an NMOS, this requires the X or Y register to be transferred to the accumulator before pushing, and transferred back after pulling.

You can branch relative unconditionally with the BRA instruction in the same way as any conditional branch, like what you used accidentally.

You can increment or decrement the accumulator, while an NMOS can only increment/decrement X, Y, or memory contents. Slithy pointed out that CA65 just takes plain INC/DEC without an operand specified, but some other assemblers accept A as the operand, and others use the mnemonics INA and DEA.

The 65C02 also adds #IMM, ZP,X and ABS,X modes to BIT. On an NMOS, testing with a immediate requires the byte to be stored in a literal pool in memory, or the AND instruction to be used at the cost of destroying the value in the accumulator.

AND'ing or OR'ing directly on memory can be done with the TRB and TSB instructions. Just discard the Z flag (the result of BIT) and back up the accumulator whenever needed. Remember that TRB takes the inverse of the value in the accumulator, but TSB doesn't.

There's also a (ZP) mode added to all instructions that have (ZP,X) and (ZP),Y. This prevents the need of setting X or Y to zero. For example, I can write a MEMCPY implementation (basically emulates LDIR in Z80) with the source and destination pointers in zero-page, and a 16-bit loop counter in X and Y. If this were an NMOS, I need to put one (or even both) halves of the loop counter in the zero-page.

There's also a JMP (ABS,X) instruction added, which is very handy for jump tables.

There's also zero-page-only bit test+branch (BBR, BBS) and manipulation (RMB, SMB) instructions. These were initially only on Rockwell models before they were merged into the WDC design. You won't find these on a 65816, even though it has all other 65C02 instructions. These can't be found on 65C02's from any other manufacturers.

WDC models also have the WAI and STP instructions that set the processor to a low-power state. The former stops execution until any interrupt occurs, and the latter stops the processor only until a reset occurs. No other 65C02's have these.

The 65C02 also fixes well-known NMOS bugs such as the infamous JMP ($xxFF) bug and the decimal mode flags bug. Some cycle counts were also changed.

Is this information helpful for you? Because I still see you LDA #0 before STA and such.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

On 4/18/2021 at 8:57 PM, StinkerB06 said:

Is this information helpful for you? Because I still see you LDA #0 before STA and such.

Ah don't worry about Tiny PCM Synth. I haven't updated the code since its release. I'll update it once someone is actually interested in using it somewhere 🙂

For my other project, Concerto, I have been using many of the WDC 65C02 instructions (my go-to reference is http://www.obelisk.me.uk/65C02/reference.html). Although I have to admit that I am probably underusing some of the bit manipulation/testing instructions. But yea, STZ, INC, DEC, and the JMP (ABS,X) are really useful and I use them often, and BBR/BBS in my multiplication routines.

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.

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.


  • Create New...

Important Information

Please review our Terms of Use