Skip to content

UART Commands

UART Register Map

The UART will be implemented first, though future options include MIDI or a Memory-Mapped IO solution. UART was chosen for a good compromise between simplicity in attaching the card to various systems, speed, and large command space.

To keep things simple, commands are always 2-bytes. The first byte is the command; and the second is the data. This does mean certain interactions, such as loading samples, are less efficient. As these interactions are not as time-critical, it seems worth it for the simplicity.

Though this may change, at present, an acknowledgement byte is sent back after every byte is sent. For command-data stanzas, $01 means the command was read, and $02 means the data was read.

Bank Select

Hex Command Bits
$FF Select Command Bank 7:0

This selects command banks for different functions. and provides a means for expansion as well as efficient use of register writes to save on bytes.

Banks:

  • $00 = Performance (Default)
  • $01 = Envelopes
  • $02 = LFOs
  • $03 = Wave Frames Load
  • $04 = Sample Load
  • $05 = Arpeggiator (Proposed)
  • $FE = System / Global
  • $FF = Reset

Performance

The performance bank is the default bank and where most musical interactions will occur. Each command includes the channel number as the lowest 3-bits. This was done to help reduce the amount of commands required for interactions that generally needed to be fast or are time-critical. One speed trade-off that was done was to avoid packed commands. Each command does a single thing rather than having a command have multiple functions which would require bitmasking and keeping track of more state on the computer side.

Number Hex Command Bits
00 $00-07 Note Ctrl 1:0: Note Modes
01 $08-0F Channel Mode 3:0: Modes
02 $10-17 Frame/PWM/Sample Number 7:0
03 $18-1F Note MIDI Number 6:0
04 $20-27 Semitone 7:0, Signed
05 $28-2F Volume 6:0 (7:0 for distortion)
06 $30-37 Pitch Glide 7:0
07 $38-3F Pitch Slide 7:0, Signed
08 $38-3F Frame Glide 7:0
09 $38-3F Frame Slide 7:0, Signed

... | FF | $FF | Select Command Bank | 7:0 |

Channel Control Note Modes

  • $00 = Off
  • $01 = Rel
  • $02 = Legato
  • $0F = On

Channel Modes

  • $00 = Cyclic Wavetable
  • $01 = PWM
  • $02 = Ramp

  • $03..07 = Reserved

  • $08 = Modern LFSR Noise

  • $09 = GameBoy Style LFSR Noise
  • $0A = rand() Noise
  • $0B = Bitshift Noise

  • $0C = Sample, One-Shot

  • $0D = Sample, Forward Loop
  • $0E = Sample, Ping-Pong Loop

  • $0F..$FF = Reserved

Volume

Actual volume can only go to 127 as the waves are 8-bit but sinusoidal meaning each half of the wave is only up to 127 in amplitude. However, increasing the volume beyond 127 can create distortion somewhat akin to wave-folding.

Envelopes

Envelopes configuration. As with performance bank, the command includes the channel number.

Number Hex Command Bits
00 $40-47 Vol Env Speed Divisor 7:0
01 $48-4F Vol Env Start Vol 7:0
02 $48-4F Vol Env Attack 7:0
03 $50-57 Vol Env Decay 7:0
04 $58-5F Vol Env Sustain 7:0
05 $60-67 Vol Env Release 7:0
06 $40-47 Mod Env Speed Divisor 7:0
07 $48-4F Mod Env Top Frame 7:0
08 $48-4F Mod Env Attack 7:0
09 $50-57 Mod Env Decay 7:0
0A $58-5F Mod Env Sustain 7:0
0B $60-67 Mod Env Release 7:0

LFOs

Number Hex Command Bits
0D $68-6F Vol LFO Types 7:5
0E $70-77 Vol LFO Frame 7:0
0F $78-7F Vol LFO Speed 7:0
10 $80-87 Vol LFO Amplitude 7:0
11 $88-8F Pitch LFO Types 7:5
12 $90-97 Pitch LFO Frame 7:0
13 $98-9F Pitch LFO Speed 7:0
14 $A0-A7 Pitch LFO Amplitude 7:0
15 $A8-AF Frame Mod LFO Types 7:5
16 $B0-B7 Frame LFO Frame 7:0
17 $B8-BF Frame LFO Speed 7:0
18 $C0-C7 Frame LFO Amplitude 7:0

LFO Types

  • 0 = Off
  • 1 = Sine
  • 2 = Tri
  • 3 = Saw
  • 4 = Square
  • 5 = Random
  • 6 = Cross-Mod, Aligned Frame
  • 7 = Cross-Mod, Free Frame

Frame Manipulation Bank

Hex Command Bits
$00 Frame Command 7:0
$01 Frame Number 7:0
$02 Sample Position 5:0
$03 Sample 7:0

Enabling the stride means the frame position will auto-increment after each frame command. This allows for populating the frames without having to set the position each time.

Writes done using stride will wrap over on the same frame if more than 64 samples are written.

Frame Commands

  • $00 = Read Next Sample, Stride 1
  • $01 = Begin Wave Write, Stride 1
  • $02 = End Wave Write, Calculate Size

The byte returned after the message was sent will be the byte requested.

Sample Manipulation Bank

Hex Command Bits
$00 Sample Command 7:0
$01 Sample Number 3:0
$02 Sample Pitch Offset Low 7:0 Signed
$03 Sample Pitch Offset High 15:8 Signed
$04 Sample Length Low 7:0
$05 Sample Length High 13:8
$06 Sample Position Low 7:0
$07 Sample Position High 13:8
$08 Sample 7:0

Samples are 16k in length.

Enabling the stride means the frame position will auto-increment after each frame command. This allows for populating the frames without having to set the position each time.

Sample Commands

  • $0 = Read Next Sample, Stride 1
  • $1 = Begin Wave Write, Stride 1

The byte returned after the message was sent will be the byte requested.

Arpeggiator Bank

The arp is a powerful tool to allow the TurboWave to do anything from the classic console arps (SID, NES, etc.) to short sequences.

For speed, consider if it should be inversted (presented as speed rather than a divisor). The implementation is really how many skips for the timed ISR

Number Hex Command Bits
00 $00-07 Arp Mode 3:0
01 $00-0F Arp Frame 7:0
02 $10-17 Arp Length 7:0
03 $10-1F Arp Speed 7:0

Arp Modes

  • $0 = Off
  • $1 = Up
  • $2 = Down
  • $3 = Up/Down
  • $4 = In Order
  • $5 = Reverse
  • $F = Random

Global Settings Bank

Global non-channel miscellaneous settings

Hex Command Bits
$00 Set Speed uS Low 7:0
$01 Set Speed uS High 15:0

Set Speed

Sets the update rate of the main timer on the TurboWave. This timer is used for automation (envelopes, LFOs, etc.). It may be advantageous to set this to something other than the default, for instance, for certain automation speeds to match the song speed or an update rate on the device on the other side.

On the X16, for instance, setting the update-rate to 16.67ms (16667 us) would match vsync.