I'm thinking of a design for a synthesizer to fit in a CPLD that would work even on an NES.
Each channel would resemble an APU channel, but without hardware envelope, length counter, or sweep. Each channel has an 11-bit divider, an 8-step PWM sequencer, and a volume control.
As on the 2A03 APU, the CPU frequency is pre-divided by 2 before being sent to the synthesizer as an 895 kHz clock.
Every time a channel's waveform rises or falls, the sequencer pulls /IRQ low.
When $4011 is read, the channels are summed and put on the data bus, and /IRQ goes high impedance.
So if you have two channels playing notes at about 300 Hz, you get about 1200 IRQs per second: 300 rises and 300 falls for each channel. Each IRQ takes 19 cycles to service:
Thus the CPU would spend about 1.3 percent of the time servicing IRQs. This would increase with higher frequencies, and it might be best to design the music engine to play lower frequencies on the CPLD and higher on the APU.
A CPLD needs a macrocell for each flip-flop, but it also needs a few spare macrocells for complex combinational logic. I count 64 flip-flops, meaning it might fit in a 72 macrocell CPLD, but it might not.
It'd need 26 pins, some of which might be shared with the mapper on a larger CPLD:
Inputs: R/W, /ROMSEL, A14-A0, M2, D7
Input/output: D6-D0
So would this be feasible?
Each channel would resemble an APU channel, but without hardware envelope, length counter, or sweep. Each channel has an 11-bit divider, an 8-step PWM sequencer, and a volume control.
Code:
7654 3210 $4020/$4024
TT VVVV
|| ++++- Volume
++-------- Timbre (12.5%, 25%, 37.5%, or 50% duty)
7654 3210 $4022/$4026
PPPPPPPPP
+++++++++- Period (bits 7-0)
7654 3210 $4023/$4024
PPP
+++- Period (bits 10-8)
TT VVVV
|| ++++- Volume
++-------- Timbre (12.5%, 25%, 37.5%, or 50% duty)
7654 3210 $4022/$4026
PPPPPPPPP
+++++++++- Period (bits 7-0)
7654 3210 $4023/$4024
PPP
+++- Period (bits 10-8)
As on the 2A03 APU, the CPU frequency is pre-divided by 2 before being sent to the synthesizer as an 895 kHz clock.
Every time a channel's waveform rises or falls, the sequencer pulls /IRQ low.
When $4011 is read, the channels are summed and put on the data bus, and /IRQ goes high impedance.
So if you have two channels playing notes at about 300 Hz, you get about 1200 IRQs per second: 300 rises and 300 falls for each channel. Each IRQ takes 19 cycles to service:
Code:
brk $00 ; 7
irq:
dec $4011 ; 6
rti ; 6
irq:
dec $4011 ; 6
rti ; 6
Thus the CPU would spend about 1.3 percent of the time servicing IRQs. This would increase with higher frequencies, and it might be best to design the music engine to play lower frequencies on the CPLD and higher on the APU.
A CPLD needs a macrocell for each flip-flop, but it also needs a few spare macrocells for complex combinational logic. I count 64 flip-flops, meaning it might fit in a 72 macrocell CPLD, but it might not.
- Divider reset values: 11 bits per channel
- Volume: 4 bits per channel
- Timbre:2 bits per channel:
- Divider position: 11 bits per channel
- Sequencer position: 3 bits per channel
- Pre-scaler: 1 bit
- IRQ flag: 1 bit
It'd need 26 pins, some of which might be shared with the mapper on a larger CPLD:
Inputs: R/W, /ROMSEL, A14-A0, M2, D7
Input/output: D6-D0
So would this be feasible?