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.