Jump to content
IGNORED

POKEY 16-bit mode and other AUDCTL settings - A7800 emulation


Recommended Posts

Thought I'd go ahead and start this thread ...

 

As some of you may know, the POKEY chip has a lot of neat features, most of them controlled from the AUDCTL register.  This register covers everything from changing the base clock (to pitch some or all channels up or down an octave), a hi-pass filter, and a 16-bit filter which lets you expand your note range into 16-bit, and lets you reach into the low bass range, or play higher accuracy high notes which are impossible in normal 8-bit mode.

 

Fans of the Bentley Bear game have already heard this feature in action ... the bass notes used in the title theme are done on channel 0, using 16-bit mode.  The trick is setting AUDCTL=$50.  This joins channels 0 and 1, whilst also simultaneously clocking channel 0 at 1.79 mhz so that the channel is in the right octave to play the notes.  You also have to silence all output from channel 1.

 

I have noticed that the A7800 emulator has troubles with emulation in this mode.  Everything is okay if you are using the pure tone setting (AUDC0=$Ax or $Ex) like I did in the Bentley Bear music. The problem arises, however, when using other distortion settings on AUDC0 ... for instance, the attached music which plays the theme song for the video game Mappy that I worked up once.

 

The bass is in 8-bit mode using $Cx distortion.  However, one of the lead channels is in 16-bit with AUDC0=$CX.  It works perfectly fine in Prosystem, but A7800 puts the track into the wrong tuning.  I think it may be because the 1.79 Mhz tuning is not behaving properly in the emulator.

 

This also happens with the Atariage jingle theme which I posted in the Arkanoid thread.  So I thought I would start up this thread to collect up test cases of this, for purposes of improving the emulator.  Hopefully this and other examples will prove helpful.  POKEY is @$4000 in this binary, so it will have to be moved to $450 and recompiled to test on some developer carts.

 

 

test16k.asm test16k.A78

  • Like 2
Link to comment
Share on other sites

Some facts about the $CX distortion setting in AUDC0 ... it's a sawtooth waveform, but it's complicated.  The actual technical explanation is above my pay grade, but it reads and outputs audio information using groups of bits, in such a way that frequencies which are divisible by 3 or 5 actually output a seperate waveform (I have termed this Distortion 12b) from the other frequencies which generate the normal buzzier saw wave (I named this distortion 12a).  When the frequency is divisible by both 3 and 5, silence is generated.  This is useful, in that you can input note rests into the music usng this, when needed.

 

The other interesting effect, is that the waveform in Distortion 12b will also vary slightly, depending on hardware timing.  The timbre changes slightly.  There is a means of resetting the system clock when a note is played, to negate or control this effect, again something a bit out of my knowledge ... :)

 

In 8-bit mode, the bass notes are somewhat usable, but the high notes cannot be used with any accuracy unless you engage either the 1.79 Mhz clock, or 16-bit mode.  With these, you get a waveform which sounds alot like the pulse wave setting used on a lot of NES music.  There is a note table I have posted elsewhere, which details all the frequency settings, in both $CX distortions, and in 8-bit and 16-bit mode, necessary to play music.

  • Like 1
Link to comment
Share on other sites

There is also this case ... the atariage jingle, in this case using AUDC0=$2x for the lead sound while $Ax in 8-bit mode does the remaining two voices.  This setting outputs a Triangle wave, a very sonorous bell tone.  It is completely unusable in 8-bit mode, but with the 16-bit settings, it is very useful.  However, in this case, both Prosystem and A7800 seem not to do this tune correctly.

atariage-jingle2.A78 atariage-jingle2.asm atariage-jingle2.bin

Link to comment
Share on other sites

And then there's this ... a test rendering of the Arkanoid 2 Revenge of Doh level start theme.  This one is a double-whammy.

 

Channels 2 and 3 are Distortion AUDC2=$CX in 16-bit mode, while a very different trick is used on channels 0 and 1.  We have an obscure register called SKCTLS, which when set to $8B engages a setting called 2-tone mode.  This allows channel 1's frequency to modulate the output of channel 0.  On the XL computer, this is used for purposes of floppy disk or casette I/O tones, or for generating modem carriers or DTMF touch tones for dialing.

 

However, this has a musical use too ... modulating the frequency creates distorted SID-type sounds.  You silence channel 1, and channel 0 handles the audio output.  AUDF1 is the frequency carrier, and AUDF0 modulates the frequency.  This can make some interesting effects.

 

Unsurprisingly, both emulators do not yet handle this feature. 

 

 

arkanoid2-levelstart-450.A78 arkanoid2-levelstart-450.asm arkanoid2-levelstart-450.bin arkanoid2-levelstart.A78 arkanoid2-levelstart.asm arkanoid2-levelstart.bin

Edited by Synthpopalooza
Link to comment
Share on other sites

Another obscure function of POKEY ... is that there is a means of playing sampled audio.  What you have to do is set AUDC0 to $1x or some other odd value.  Normally this plays no sound, but it pops the speaker.  By varying the volume, you can play a 4-bit quality audio sample, with the disadvantage that it will of course take up the entire CPU time for the duration of the sound being played.  I will attempt to work up a test example to see if it will work in the emulator or not.

Link to comment
Share on other sites

On 7/17/2019 at 12:05 AM, Synthpopalooza said:

And then there's this ... a test rendering of the Arkanoid 2 Revenge of Doh level start theme.  This one is a double-whammy.

 

Channels 2 and 3 are Distortion AUDC2=$CX in 16-bit mode, while a very different trick is used on channels 0 and 1.  We have an obscure register called SKCTLS, which when set to $8B engages a setting called 2-tone mode.  This allows channel 1's frequency to modulate the output of channel 0.  On the XL computer, this is used for purposes of floppy disk or casette I/O tones, or for generating modem carriers or DTMF touch tones for dialing.

 

However, this has a musical use too ... modulating the frequency creates distorted SID-type sounds.  You silence channel 1, and channel 0 handles the audio output.  AUDF1 is the frequency carrier, and AUDF0 modulates the frequency.  This can make some interesting effects.

 

Unsurprisingly, both emulators do not yet handle this feature. 

 

Regarding the above, real hardware produces the same results as what is heard under the A7800 emulator.  Essentially, it is just a series of pops and static/muffled noise. 

 

I made a ~1 min audio clip from real hardware and then from the A7800 emulator, repeating the audio clip by pressing the 'Reset' button.  Results match, accounting for speaker and volume differences:

 

SKCTLS_arkanoid2-levelstart_RealHW.wavSKCTLS_arkanoid2-levelstart_A7800.wav

 

Side note:  The *.a78 file posted for the POKEY@450 has the header set for POKEY@4000.  I corrected it for testing under A7800.  The POKEY@450 *.bin posted was utilized with the MCP DevCart for the hardware test.

  • Thanks 1
Link to comment
Share on other sites

An update ...

 

I reworked the tune into normal 8-bit mode:

 

Channels 0 and 1 are the lead sound, with SKCTLS put into two tone mode

Channel 2 is $CX base in 8-bit mode

Channel 3 is $AX lead detuned ...

 

Attached is a test I ran on Altirra XL emulator, as a wav file, which is close to how the actual tune should sound (for some reason the Altirra output omits channel 3).  Hopefully this is pretty close on real 7800 hardware.

arkanoid2-levelstart.asm arkanoid 2-tone.mp3 arkanoid2-levelstart-450.asm arkanoid2-levelstart.A78 arkanoid2-levelstart.bin arkanoid2-levelstart-450.128 arkanoid2-levelstart-450.bin

Link to comment
Share on other sites

And this is a recording of how the tune should sound with all three channels.  The lead channels in 3 and 0 flange together and create a Commodore 64-style SID flange.  This is the desired output on actual 7800 hardware.  All of this assumes that SKCTLS works the same on 7800 in regards to POKEY audio.

 

 

arkanoid 2-tone lead.wav

Link to comment
Share on other sites

So I have tried another tune ... this time, the theme from Bubble Bobble.

 

I used the following setup:

 

AUDCTL=$70 (join channels 0 and 1 in 16-bit mode, clock channels 0 and 3 at 1.79 Mhz)

Channels 0 and 1 are distortion 12, in 16 bit mode

Channel 2 is distortion 2, clocked at 1.79 Mhz mode

Channel 3 is distortion 10, no special settings.

 

The idea is ... by clocking channel 2 at 1.79 mhz, the frequencies are transposed up to a playable range using the $2x distortion setting (triangle wave).  Combined with a similar melody on channel 3 using the standard $Ax square wave, this makes interesting harmonics.

 

Channel 0 and 1 are 16-bit, with channel 1 set to $Cx saw wave, and using the 12b method of playing bass notes with frequencies divisible by 3.

 

When using Prosystem, the bass channel plays as expected, channel 2 plays as it should, but won't play notes above the highest C

 

When using A7800, the bass channel plays completely wrong, and channel 2 plays an octave too high.

 

Attaching the following source code ... it will need to be modified to place pokey @$450 ... a real hardware test would be appreciated.

 

Also attached:  A WAV recording of the tune in Altirra, which is how the tune should sound on real hardware.

 

 

bubbob7800.bin bubbob7800.log bubbob7800.128 bubbob7800.A78 bubbob7800.asm bubble bobble.mp3

  • Like 1
Link to comment
Share on other sites

On 7/22/2019 at 1:04 AM, Synthpopalooza said:

An update ...

 

I reworked the tune into normal 8-bit mode:

 

Channels 0 and 1 are the lead sound, with SKCTLS put into two tone mode

Channel 2 is $CX base in 8-bit mode

Channel 3 is $AX lead detuned ...

 

Attached is a test I ran on Altirra XL emulator, as a wav file, which is close to how the actual tune should sound (for some reason the Altirra output omits channel 3).  Hopefully this is pretty close on real 7800 hardware.

 

Attached is a sample from real hardware and from the A7800 emulator. 

Same issue as the 'AtariAge Jingle' sample, sounding slightly off with bass not quite right:

 

Arkanoid2LevelStartDemo_RealHW.wavArkanoid2LevelStartDemo_A7800.wav

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

1 hour ago, Trebor said:

 

Attached is a sample from real hardware and from the A7800 emulator. 

Same issue as the 'AtariAge Jingle' sample, sounding slightly off with bass sound not quite right:

 

Arkanoid2LevelStartDemo_RealHW.wav 687.3 kB · 1 download Arkanoid2LevelStartDemo_A7800.wav 668.92 kB · 1 download

Thanks ... the real hardware is again 100% correct in this case.  :) That's how it should sound.

 

An explanation ... 

 

To do 2-tone mode, store $8B into SKCTLS register.  You then have to silence channel 1, while playing your melody on channel 0.  The frequency modulation is played simultaneously on channel 2, but transposed up about 3 semitones.  This produces a SID type pitch modulation.  I then played the same melody on a normal square wave on channel 3, but detuned slightly, to make it sound fuller.

 

SKCTLS can also be used in other distortion settings.  $2x and both iterations of $Cx look promising.  There is also the possibility of combining it with $4x, or $8x with a 9-bit poly counter, to get a sound similar to a distorted guitar.  More experimentation is needed.

 

I am also going to experiment with the hi pass filter.  There is an AUDCTL setting which lets you use channel 2 as a hi pass filter for channel 0, or 3 for channel 1.  By inserting a frequency on 2 higher than what's played on 0, a pulse wave similar to the NES duty cycle wave is generated, and the pulse width can be controlled.  This will make a good approximation of most NES lead sounds.  I seem to remember both prosystem and A7800 having troubles here too.

 

The other setting of interest is the 9-bit poly counter, AUDCTL=%1xxxxxxx.  It gets used with the $8x white noise and $0x pink noise distortion.  When set, buzzing noises in the high frequencies are produced, and it's possible these can be modulated into music, either by 2-tone, hi pass, 1.79 mhz, or 16-bit frequencies.

  • Like 2
Link to comment
Share on other sites

So on my radar now ... two emulator test programs.  

 

The first will allow you to step through the scale in 16 bit mode for all four waveforms.

 

The second will be 8-bit and use the normal square wave as a reference point between these three settings:

 

Triangle wave at 1.79 mhz

Square wave with hi-pass filter

Square wave with 2-tone filter

 

I will also have a bass frequency setting at 15hz in this program as well, as a reference.

  • Like 3
Link to comment
Share on other sites

Another test ... this time, the Hi-pass filter.  The music is the iconic level start music from Mega Man 2. :)

 

When you set AUDCTL=$02, a Hi pass filter is set on channel #1, and is modulated by the frequency of channel #3.  With $04, the same effect is set on channel #0, and modulated from #2.

 

So, if you play a melody on channel #1, and then play the same melody an octave higher on channel #3, and silence the volume of channel 3, this emulates the duty cycle pulse wave of NES music.  It is also possible to vary the pulse width, just like on the NES.

 

A recording on Altirra emulator, followed by 7800 executables and source code.  These fail on both Prosystem and A7800.  On Prosystem, no modulation is done, and the harmony channel #2 is not played.  On A7800, the modulation is played in the wrong octave, and the harmony channel #2 is not played.

 

Here is the channel layout:

 

AUDCTL=$02 (Hi pass on #1, modulated from #3)

Channel #0:  $Ax square wave, no modulations - bass

Channel #1:  $Ax square wave, hi pass - lead

Channel #2:  $Ax square wave, no modulations - harmony

Channel #3:  Silenced (volume=0)

 

My next experiments will be with the 9-bit polycounter $8x settings, and some more with the SKCTLS 2-tone filter.

 

 

megaman-start.mp3 megaman2-start.128 megaman2-start.A78 megaman2-start.asm megaman2-start.bin

Edited by Synthpopalooza
  • Like 3
Link to comment
Share on other sites

I am preparing another test.  This time it will be the $8x distortion with the 9-bit polycounter.  $8x normally uses a 17-bit polycounter, and any 8 bits sampled from this produce white noise.  When this is changed to 9-bit, the pattern is less random, and distorted guitar sounds are produced.

 

The settings I will use are $8x, and AUDCTL=$D0.  This engages 16-bit mode and the 9-bit polycounter.  However, unlike other examples, in this case the first channel is played and the second is silenced.  This is an undocumented POKEY setting, and I have a note table constructed.  Demo song coming soon.

Edited by Synthpopalooza
  • Like 1
Link to comment
Share on other sites

OK, here is my latest ... a rendition of the opening level theme from Namco's Rolling Thunder.

 

Channel layout is as follows:

 

Channel 0:  $8x distortion, 9-bit polycounter, 16-bit mode, clocked at 1.79 mhz - guitar lead

Channel 1:  silent.  Frequency set to 0.

Channel 2   $Cx distortion, saw wave, no modulation - bass channel

Channel 3   $Ax distortion, square wave, no modulation - accompaniment

 

AUDCTL is set to $D0 ... engaging the 9-bit poly-counter, 16-bit mode on channels 0 and 1, and clocking channel 0 at 1.79 mhz.  Unlike other 16-bit examples, in this case channel 0 is played while channel 1 is silenced, and the frequency set to a constant 0.  This is a mostly undocumented POKEY setting. 

 

Technical explanation ... well, best I can tell, frequencies divisible by 7 seem to produce the desired distorted guitar tones.  I actually found 2 sets of usable frequencies here and made a short table:

 

Distorted guitar
AUDCTL=$D0, AUDC0=$8x, AUDC1=$00

Table 1:

c#2 - 94
d - 89
d# - 83
e - 78
f - 73
f# - 69
g - 64
g# - 61
a - 57
a# - 53
b - 50
c3 - 47
c# - 44
d = 41
d# - 38
e - 36
f - 33
f# - 31
g - 29
g# - 27
a - 25
a# - 23

Table 2 (frequencies divisible by 7):

f#3 - 252
g - 245
g# - 231
a - 217
a# - 203
b - 189
c4 - 182
c# - 168
d - 161
d# - 147
e - 140
f - 133
f# - 126
g - 119
g# - 112
a - 105
a# - 98
b - 91
c4 - 84

 

The notes in the lead are from table 2.  Table 1 produces the same guitar, but the timbre sounds a bit more muted.

 

Attached is a .mp3 of the Altirra emulator, plus 7800 executables.  Both Prosystem and A7800 fail to do the 9-bit poly emulation, white noise is played instead.  The mp3 demonstrates how it should sound on real hardware.  A test on real hardware would be appreciated ... maybe finally we can get a decent port of Rolling Thunder on the 7800.  :)

 

There are other frequencies available here, which can be accessed by altering the frequency of channel 1.  There is a lot to be explored here!

 

rollingthunder-intro.A78 rollingthunder-intro.asm rollingthunder-intro.bin rolling thunder.mp3

Edited by Synthpopalooza
  • Like 3
Link to comment
Share on other sites

I am working on another demo tune which uses the 2-tone filter.  It will be a famous tune from a Mario game.  :) the 2-tone filter lets you extend the octave range on the square wave distortion without loss of accuracy and you can vary the pulse width like on the hi pass filter.   Stsy tuned ...

Edited by Synthpopalooza
  • Like 2
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...