8bit Digital Sound / not quite Soundblaster for RCbus

244 views
Skip to first unread message

Alan Cox

unread,
Apr 11, 2023, 8:37:03 AM4/11/23
to rc201...@googlegroups.com
I'd forgotten to post this one a long time back.This board on its own
gives you a simple CPU controlled 8bit DAC and amplifier for digital
sound. It's something akin to the old TRS80 Orch cards and the good
old PC Covox. If you have a CTC and DMA however you can also wire it
up to run as an 8bit DMA driven sound adapter.

https://hackaday.io/project/190520-8bit-sound-for-rcbus

Alan

Phil G

unread,
Apr 12, 2023, 6:24:45 AM4/12/23
to RC2014-Z80
Hi Alan, there are a few DAC sound demos on my yooch that might interest you, Richard Russell's music compiler, audio samples etc using a ZN328E:   https://www.youtube.com/@PHILG2864/videos
Cheers - Phil

Sergey Kiselev

unread,
Apr 12, 2023, 11:23:31 AM4/12/23
to RC2014-Z80
Hi Alan,

I assume the idea is to use the flip-flop for timing, connecting READY/NOTREADY signals to a DMA request or a CPU interrupt signal?

A few ideas for improvements:
1. Add a "slow" clock source on the board. 8 kHz was a common sample rate for old-school PCM... The RTC frequency (32768 Hz) divided by 4 is close enough (just 2.4% faster)
2. Add a functionality to poll the READY signal . That would require a three state buffer, e.g. 74*125, with its output connected to one of the data lines. That would also require a bit of change to the current address decode... Perhaps adding a 74*32 to generate separate I/O read and I/O write signals for the board. Or it might be possible to use unused 74*125 gates for that
3. Use a FIFO as an alternative to the DMA. Maybe a couple of CD74HC40105E (https://www.ti.com/product/CD74HC40105) - 4-bit x 16 FIFOs? Unfortunately its "DATA IN READY" signal goes active as soon as the first word is shifted out. Ideally it should be a way to setup the threshold. I know it is getting complicated, but one way would be using a counter instead the flip-flop. It would be reset every time the input register is written, incremented (or decremented) when the data is shifted out of the FIFO (and "played"), and could be queried using the method described in (1) above

Thanks,
Sergey

Alan Cox

unread,
Apr 12, 2023, 12:50:39 PM4/12/23
to rc201...@googlegroups.com
> I assume the idea is to use the flip-flop for timing, connecting READY/NOTREADY signals to a DMA request or a CPU interrupt signal?

I'd not considered CPU interrupt but it does work for DMA this way. If
you are mixing 4 channel sound to an unbuffered DAC it's pretty much
got to be DMA or tight loops. For game sound effects you can get away
with all sorts as the old games on 1bit audio and the like did. Might
work for something like the 68xx systems with a fast interrupt.
Probably then need a jumper for the IRQ and make a read of the port
toggle the flip flop the other way. Something to ponder when I get
time. Not sure it would work well with the Z80 case.

The DMA/CTC bit was very much an afterthought. The Orch cards for the
Tandy machines of old are straight DAC bashing as were the COCO and
the Dragon. People used to get really quite good stuff out of them.

In terms of status and clocks I didn't want to complicate the board
and if you are using DMA and a CTC then you actually know the DMA
status from the DMA controller and you can monitor the CTC status on
the CTC side.

> 3. Use a FIFO as an alternative to the DMA. Maybe a couple of CD74HC40105E (https://www.ti.com/product/CD74HC40105) - 4-bit x 16 FIFOs? Unfortunately its "DATA IN READY" signal goes active as soon as the first word is shifted out. Ideally it should be a way to setup the threshold. I know it is getting complicated, but one way would be using a counter instead the flip-flop. It would be reset every time the input register is written, incremented (or decremented) when the data is shifted out of the FIFO (and "played"), and could be queried using the method described in (1) above

That's the Disney Sound Source pretty much. You can in fact plug one
of those into the MG014 printer port and it'll work with the right
code. I did consider a FIFO but the DMA side doesn't appear to need it
and the extra latency is bad for effects and breaks some of the
existing apps that want to vary the rate of DAC updating.

I was looking at some of the 1Kx9 FIFOs and wondering about a sound
driver that way, clocking in something like A8 as the extra bit and
using it as an IRQ when the FIFO output that byte, with A9 wired to
the FIFO reset I think you'd be able to do quite interesting tricks
with it assuming that there are enough ways to avoid clicks on the
FIFO reset as the IRQ will get to the CPU some bits after it hit the
DAC.

I'm still trying to work out if can use the shared memory bus
interface, another RC2014 Z80 and 512K RAM/ROM card and some extras as
a GeneralSound/NeoGS equivalent.

Alan

Sergey Kiselev

unread,
Apr 12, 2023, 5:36:54 PM4/12/23
to RC2014-Z80
Below is my quick attempt at the schematic of a PCM module with a small FIFO and a built-in 8 kHz clock.

Brief description of operation:
- The analog part - resistor ladder DAC and audio amplified is pretty much the same as in Alan's design
- U1 and U2 (74HCT40105) implement a 16 bytes deep FIFO. Writing to the PCM port (default - 0x70) writes to the FIFO
- U3 (74HCT4060) is a clock generator. It generates an 8 kHz clock for shifting the FIFO. It also generates a 1 kHz clock that can be used to generate interrupts, so that the application can refill the FIFO (the idea here is that the FIFO will be refilled when it drops below 8 bytes)
- U7A (74HCT47) latches the 1 kHz output. It can be used for generating level triggered interrupts, or it can be polled by reading bit 1 of port 0x71. The flip-flop is reset by writing the FIFO
- U7B (74HCT47) enables the interrupt generation
- U5C (74HCT125) allows reading the FIFO's Data In Ready (DIR) signal. It indicates that FIFO is ready to accept the next byte
- U5B (74HCT125) allows polling the U7A output (1 kHz / 1 ms delays)
- U4 (74HCT138), U5A and U5D (74HCT125) and U6 (74HCT32) are used for address and bus control signals decode

Note that since the clock is always running, simply writing to FIFO will work in the way mostly compatible with Alan's design, as a simple Covox-like DAC, as long as the average data rate does not exceed 8 kHz

I'd appreciate the circuit review, comments, and suggestions for improvements

-Sergey

RC-PCM.png

Bill Shen

unread,
Apr 13, 2023, 10:30:36 AM4/13/23
to RC2014-Z80
Kilohertz interrupt seems rather burdensome.  I wonder whether using FIFO like 7201 is better in reducing the interrupt rate?  CPLD plus 32K or 128K RAM can also serve as deep FIFO.
  Bill

Sergey Kiselev

unread,
Apr 13, 2023, 11:22:28 AM4/13/23
to RC2014-Z80
Yes, 1 kHz might be a bit on the higher side for a ~8 Mhz Z80 CPU system. At the same time, the interrupt handler would be pretty simple - just load the next ~8 bytes from a memory buffer to the FIFO. One can switch the alternate register set to even more speed up the process. Also that interrupt will be enabled only when playing sound (or at any time a 1 kHz interrupt is desired)
I looked at the 7201 FIFO, the problem with it is that it floats the outputs when the read signal goes inactive. 74HCT40105 has a separate shift FIFO and output enable controls. This can be solved by adding a latch on the FIFO output, which increases the circuit complexity a bit.
Another option would be to use a simple MCU to buffer the data and feed the DAC, just like Sound Blaster did. It would be a flexible approach, as the MCU can be programmed to do various stuff (e.g. work as a simple 1-byte DAC, work as a FIFO, interface with a DMA, enable/disable interrupts on various FIFO states, and so on.

-Sergey

Alan Cox

unread,
Apr 13, 2023, 12:53:08 PM4/13/23
to rc201...@googlegroups.com
The tradeoffs are difficult without DMA. Doing effects really demands you can drive the DAC fast and responsively but doing music you want to queue long bursts. In the DMA case you read the DMA pointer off the DMAC and rewrite over stuff that was queued (eg to put a kaboom over the backing track).

The MCU approach is how the GeneralSound and NeoGS work. The GeneralSound is a 12MHz (often more) Z80 and 128K-2MB of memory that is a complete offload sound system (it's basically a mod/tracker player) so you can just tell it "play the tune" at the start of a game level but you then have to combine it with the AY audio on the main system board for game action etc. It was pretty much Amiga grade audio.


gives a flavour of what it could achieve




Reply all
Reply to author
Forward
0 new messages