mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 11:51:49 +09:00
650 lines
19 KiB
Plaintext
650 lines
19 KiB
Plaintext
1 byte = 2 pixels
|
||
|
||
560x448@4bpp = 125 440 bytes
|
||
560x448@8bpp = 250 880 bytes
|
||
|
||
-> 262144 bytes (256 kB)
|
||
|
||
[USER AREA | HW AREA]
|
||
|
||
Number of pheripherals = 8, of which the computer itself is considered as
|
||
a peripheral.
|
||
|
||
HW AREA = [Peripherals | MMIO | INTVEC]
|
||
|
||
User area: 8 MB, hardware area: 8 MB
|
||
|
||
8192 kB
|
||
User Space
|
||
1024 kB
|
||
Peripheral #8
|
||
1024 kB
|
||
Peripheral #7
|
||
...
|
||
1024 kB (where Peripheral #0 would be)
|
||
MMIO and Interrupt Vectors
|
||
128 kB
|
||
MMIO for Peri #8
|
||
128 kB
|
||
MMIO for Peri #7
|
||
...
|
||
128 kB (where Peripheral #0 would be)
|
||
MMIO for the computer
|
||
130816 bytes
|
||
MMIO for Ports, etc.
|
||
256 bytes
|
||
Vectors for 64 interrupts
|
||
|
||
--------------------------------------------------------------------------------
|
||
|
||
IO Device
|
||
|
||
Endianness: little
|
||
Note: Always takes up the peripheral slot of zero
|
||
|
||
Latching: latching is used to "lock" the fluctuating values when you attempt to read them so you would get
|
||
reliable values when you try to read them, especially the multibyte values where another byte would
|
||
change after you read one byte, e.g. System uptime in nanoseconds
|
||
|
||
MMIO
|
||
|
||
0..31 RO: Raw Keyboard Buffer read. Won't shift the key buffer
|
||
32..33 RO: Mouse X pos
|
||
34..35 RO: Mouse Y pos
|
||
36 RO: Mouse down? (1 for TRUE, 0 for FALSE)
|
||
37 RW: Read/Write single key input. Key buffer will be shifted. Manual writing is
|
||
usually unnecessary as such action must be automatically managed via LibGDX
|
||
input processing.
|
||
Stores ASCII code representing the character, plus:
|
||
(1..26: Ctrl+[alph])
|
||
3 : Ctrl+C
|
||
4 : Ctrl+D
|
||
8 : Backspace
|
||
(13: Return)
|
||
19: Up arrow
|
||
20: Down arrow
|
||
21: Left arrow
|
||
22: Right arrow
|
||
38 RW: Request keyboard input be read (TTY Function). Write nonzero value to enable, write zero to
|
||
close it. Keyboard buffer will be cleared whenever request is received, so
|
||
MAKE SURE YOU REQUEST THE KEY INPUT ONLY ONCE!
|
||
39 WO: Latch Key/Mouse Input (Raw Input function). Write nonzero value to latch.
|
||
Stores LibGDX Key code
|
||
40..47 RO: Key Press buffer
|
||
stores keys that are held down. Can accomodate 8-key rollover (in keyboard geeks' terms)
|
||
0x0 is written for the empty area; numbers are always sorted
|
||
48..51 RO: System flags
|
||
48: 0b r000 000t
|
||
t: STOP button (should raise SIGTERM)
|
||
r: RESET button (should reset the system)
|
||
|
||
64..67 RO: User area memory size in bytes
|
||
68 WO: Counter latch
|
||
0b 0000 00ba
|
||
a: System uptime
|
||
b: RTC
|
||
72..79 RO: System uptime in nanoseconds
|
||
80..87 RO: RTC in microseconds
|
||
|
||
88 RW: Rom mapping
|
||
|
||
89 RW: BMS flags
|
||
0b P000 b0ca
|
||
a: 1 if charging (accepting power from the AC adapter)
|
||
c: 1 if battery is detected
|
||
b: 1 if the device is battery-operated
|
||
|
||
P: 1 if CPU halted (so that the "smart" power supply can shut itself down)
|
||
|
||
note: only the high nybbles are writable!
|
||
|
||
if the device is battery-operated but currently running off of an AC adapter and there is no battery inserted,
|
||
the flag would be 0000 1001
|
||
|
||
90 RO: BMS calculated battery percentage where 255 is 100%
|
||
91 RO: BMS battery voltage multiplied by 10 (127 = "12.7 V")
|
||
|
||
1024..2047 RW: Reserved for integrated peripherals (e.g. built-in status display)
|
||
|
||
4076..4079 RW: 8-bit status code for the port
|
||
4080..4083 RO: 8-bit status code for connected device
|
||
|
||
4084..4091 RO: Block transfer status
|
||
0b nnnnnnnn a000 mmmm
|
||
|
||
n-read: size of the block from the other device, LSB (4096-full block size is zero)
|
||
m-read: size of the block from the other device, MSB (4096-full block size is zero)
|
||
a-read: if the other device hasNext (doYouHaveNext), false if device not present
|
||
|
||
n-write: size of the block I'm sending, LSB (4096-full block size is zero)
|
||
m-write: size of the block I'm sending, MSB (4096-full block size is zero)
|
||
a-write: if there's more to send (hasNext)
|
||
|
||
4092..4095 RW: Block transfer control for Port 1 through 4
|
||
0b 00ms abcd
|
||
|
||
m-readonly: device in master setup
|
||
s-readonly: device in slave setup
|
||
|
||
a: 1 for send, 0 for receive
|
||
|
||
b-write: 1 to start sending if a-bit is set; if a-bit is unset, make other device to start sending
|
||
b-read: if this bit is set, you're currently receiving something (aka busy)
|
||
|
||
c-write: I'm ready to receive
|
||
c-read: Are you ready to receive?
|
||
|
||
d-read: Are you there? (if the other device's recipient is myself)
|
||
|
||
NOTE: not ready AND not busy (bits b and d set when read) means the device is not connected to the port
|
||
|
||
4096..8191 RW: Buffer for block transfer lane #1
|
||
8192..12287 RW: Buffer for block transfer lane #2
|
||
12288..16383 RW: Buffer for block transfer lane #3
|
||
16384..20479 RW: Buffer for block transfer lane #4
|
||
|
||
65536..131071 RO: Mapped to ROM
|
||
|
||
--------------------------------------------------------------------------------
|
||
|
||
VRAM Bank 0 (256 kB)
|
||
|
||
Endianness: little
|
||
|
||
From the start of the memory space:
|
||
250880 bytes
|
||
Framebuffer
|
||
3 bytes
|
||
Initial background (and the border) colour RGB, of which only the lower 4 bits per each channel are used
|
||
1 byte
|
||
command (writing to this memory address changes the status)
|
||
1: reset palette to default
|
||
2: fill framebuffer with given colour (arg1)
|
||
3: do '1' then do '2' (with arg1) then do '4' (with arg2)
|
||
4: fill framebuffer2 with given colour (arg1)
|
||
|
||
16: copy Low Font ROM (char 0–127) to mapping area
|
||
17: copy High Font ROM (char 128–255) to mapping area
|
||
18: write contents of the font ROM mapping area to the Low Font ROM
|
||
19: write contents of the font ROM mapping area to the High Font ROM
|
||
20: reset Low Font ROM to default
|
||
21: reset High Font ROM to default
|
||
12 bytes
|
||
argument for "command" (arg1: Byte, arg2: Byte)
|
||
write to this address FIRST and then write to "command" to execute the command
|
||
1134 bytes
|
||
unused
|
||
(1920) !!PENDING FOR REMOVAL!!
|
||
mapped to font ROM
|
||
Font Mapping area holds 128 characters in consecutive order, each character is always 15 bytes.
|
||
(designer's note: it's still useful to divide the char rom to two halves, lower half being characters ROM and upper half being symbols ROM)
|
||
2 bytes
|
||
Cursor position in: (y*80 + x)
|
||
2560 bytes
|
||
Text foreground colours
|
||
2560 bytes
|
||
Text background colours
|
||
2560 bytes
|
||
Text buffer of 80x32 (7x14 character size, and yes: actual character data is on the bottom)
|
||
512 bytes
|
||
Palette stored in following pattern: 0b rrrr gggg, 0b bbbb aaaa, ....
|
||
Palette number 255 is always full transparent (bits being all zero)
|
||
|
||
(DRAFT) Optional Sprite Card (VRAM Bank 1 (256 kB))
|
||
250880 bytes
|
||
One of:
|
||
Secondary layer
|
||
Other 8-bit of the primary framebuffer (4K colour mode)
|
||
|
||
SPRITE FORMAT DRAFT 1
|
||
|
||
533 bytes: Sprite attribute table
|
||
(41 sprites total, of which 1 is GUI cursor)
|
||
12 bytes - signed fixed point
|
||
X-position
|
||
Y-position
|
||
Transform matrix A..D
|
||
1 bytes
|
||
0b 0000 00vp
|
||
(p: 0 for above-all, 1 for below-text, v: show/hide)
|
||
10496 bytes: Sprite table
|
||
256 bytes
|
||
16x16 texture for the sprite
|
||
235 bytes:
|
||
unused
|
||
|
||
SPRITE FORMAT DRAFT 2
|
||
|
||
DMA Sprite Area - 18 bytes each, total of ??? sprites
|
||
1 byte
|
||
Sprite width
|
||
1 byte
|
||
Sprite height
|
||
12 bytes - signed fixed point
|
||
Affine transformation A,B,C,D,X,Y
|
||
1 byte
|
||
Attributes
|
||
0b 0000 00vp
|
||
(p: 0 for above-all, 1 for below-text, v: show/hide)
|
||
3 bytes
|
||
Pointer to raw pixmap data in Scratchpad Memory
|
||
|
||
MMIO
|
||
|
||
0..1 RO
|
||
Framebuffer width in pixels
|
||
2..3 RO
|
||
Framebuffer height in pixels
|
||
4 RO
|
||
Text mode columns
|
||
5 RO
|
||
Text mode rows
|
||
6 RW
|
||
Text-mode attributes
|
||
0b 0000 00rc (r: TTY Raw mode, c: Cursor blink)
|
||
7 RW
|
||
Graphics-mode attributes
|
||
0b 0000 rrrr (r: Resolution/colour depth)
|
||
8 RO
|
||
Last used colour (set by poking at the framebuffer)
|
||
9 RW
|
||
current TTY foreground colour (useful for print() function)
|
||
10 RW
|
||
current TTY background colour (useful for print() function)
|
||
11 RO
|
||
Number of Banks, or VRAM size (1 = 256 kB, max 4)
|
||
12 RW
|
||
Graphics Mode
|
||
0: 560x448, 256 Colours, 1 layer
|
||
1: 280x224, 256 Colours, 4 layers
|
||
2: 280x224, 4096 Colours, 2 layers
|
||
3: 560x448, 256 Colours, 2 layers (if bank 2 is not installed, will fall back to mode 0)
|
||
4: 560x448, 4096 Colours, 1 layer (if bank 2 is not installed, will fall back to mode 0)
|
||
4096 is also known as "direct colour mode" (4096 colours * 16 transparency -> 65536 colours)
|
||
Two layers are grouped to make a frame, "low layer" contains RG colours and "high layer" has BA colours,
|
||
Red and Blue occupies MSBs
|
||
13 RW
|
||
Layer Arrangement
|
||
If 4 layers are used:
|
||
Num LO<->HI
|
||
0 1234
|
||
1 1243
|
||
2 1324
|
||
3 1342
|
||
4 1423
|
||
5 1432
|
||
6 2134
|
||
7 2143
|
||
8 2314
|
||
9 2341
|
||
10 2413
|
||
11 2431
|
||
12 3124
|
||
13 3142
|
||
14 3214
|
||
15 3241
|
||
16 3412
|
||
17 3421
|
||
18 4123
|
||
19 4132
|
||
20 4213
|
||
21 4231
|
||
22 4312
|
||
23 4321
|
||
If 2 layers are used:
|
||
Num LO<->HI
|
||
0 12
|
||
1 12
|
||
2 12
|
||
3 12
|
||
4 12
|
||
5 12
|
||
6 12
|
||
7 21
|
||
8 21
|
||
9 21
|
||
10 21
|
||
11 21
|
||
12 12
|
||
13 12
|
||
14 21
|
||
15 21
|
||
16 12
|
||
17 21
|
||
18 12
|
||
19 12
|
||
20 21
|
||
21 21
|
||
22 12
|
||
23 21
|
||
If 1 layer is used, this field will do nothing and always fall back to 0
|
||
14..15 RW
|
||
framebuffer scroll X
|
||
16..17 RW
|
||
framebuffer scroll Y
|
||
18 RO
|
||
Busy flags
|
||
1: Codec in-use
|
||
2: Draw Instructions being decoded
|
||
19 WO
|
||
Write non-zero value to initiate the Draw Instruction decoding
|
||
20..21 RO
|
||
Program Counter for the Draw Instruction decoding
|
||
1024..2047 RW
|
||
horizontal scroll offset for scanlines
|
||
2048..4095 RW
|
||
!!NEW!! Font ROM Mapping Area
|
||
Format is always 8x16 pixels, 1bpp ROM format (so that it would be YY_CHR-Compatible)
|
||
(designer's note: it's still useful to divide the char rom to two halves, lower half being characters ROM and upper half being symbols ROM)
|
||
65536..131071 RW
|
||
Draw Instructions
|
||
|
||
Text-mode-font-ROM is immutable and does not belong to VRAM
|
||
Even in the text mode framebuffer is still being drawn onto the screen, and the texts are drawn on top of it
|
||
|
||
Copper Commands (suggestion withdrawn)
|
||
|
||
WAITFOR 3,32
|
||
80·03 46 00 (0x004603: offset on the framebuffer)
|
||
SCROLLX 569
|
||
A0·39 02 00
|
||
SCROLLY 321
|
||
B0·41 01 00
|
||
SETPAL 5 (15 2 8 15)
|
||
C0·05·F2 8F (0x05: Palette number, 0xF28F: RGBA colour)
|
||
SETBG (15 2 8 15)
|
||
D0·00·F2 8F (0xF28F: RGBA colour)
|
||
END (pseudocommand of WAITFOR)
|
||
80·FF FF FF
|
||
|
||
--------------------------------------------------------------------------------
|
||
|
||
TSVM MOV file format
|
||
|
||
Endianness: Little
|
||
|
||
\x1F T S V M M O V
|
||
[METADATA]
|
||
[PACKET 0]
|
||
[PACKET 1]
|
||
[PACKET 2]
|
||
...
|
||
|
||
|
||
where:
|
||
|
||
METADATA -
|
||
uint16 WIDTH
|
||
uint16 HEIGHT
|
||
uint16 FPS (0: play as fast as can)
|
||
uint32 NUMBER OF FRAMES
|
||
uint16 GLOBAL PACKET TYPE (will be deprecated; please use 255,0)
|
||
byte[12] RESERVED
|
||
|
||
Packet Types:
|
||
<video>
|
||
0,0: 256-Colour frame
|
||
1,0: 256-Colour frame with palette data
|
||
2,0: 4096-Colour frame (stored as two byte-planes)
|
||
4,t: iPF no-alpha indicator (see iPF Type Numbers for details)
|
||
5,t: iPF with alpha indicator (see iPF Type Numbers for details)
|
||
16,0: Series of JPEGs
|
||
18,0: Series of PNGs
|
||
20,0: Series of TGAs
|
||
21,0: Series of TGA/GZs
|
||
255,0: Every frame specifies the type
|
||
<audio>
|
||
0,16: Raw PCM Mono
|
||
1,16: Raw PCM Stereo
|
||
2,16: ADPCM Mono
|
||
3,16: ADPCM Stereo
|
||
<special>
|
||
255,255: sync packet (wait until the next frame)
|
||
|
||
Packet Type High Byte (iPF Type Numbers)
|
||
0..7: iPF Type 1..8
|
||
|
||
|
||
|
||
|
||
GLOBAL TYPE 0 Packet -
|
||
uint32 SIZE OF FRAMEDATA
|
||
* FRAMEDATA COMPRESSED IN GZIP
|
||
|
||
GLOBAL TYPE 1 Packet -
|
||
byte[512] Palette Data
|
||
uint32 SIZE OF FRAMEDATA
|
||
* FRAMEDATA COMPRESSED IN GZIP
|
||
|
||
GLOBAL TYPE 2 Packet -
|
||
uint32 SIZE OF FRAMEDATA BYTE-PLANE 1
|
||
* FRAMEDATA COMPRESSED IN GZIP
|
||
uint32 SIZE OF FRAMEDATA BYTE-PLANE 2
|
||
* FRAMEDATA COMPRESSED IN GZIP
|
||
|
||
GLOBAL iPF Packet -
|
||
uint32 SIZE OF FRAMEDATA
|
||
* FRAMEDATA COMPRESSED IN GZIP // only the actual gzip (and no UNCOMPRESSED SIZE) of the "Blocks.gz" is stored
|
||
|
||
GLOBAL TYPE 16+ Packet -
|
||
uint32 SIZE OF FRAMEDATA BYTE-PLANE 1
|
||
* FRAMEDATA (COMPRESSED IN GZIP for TGA/GZ)
|
||
|
||
GLOBAL TYPE 255 Packet -
|
||
uint16 TYPE OF PACKET // follows the Metadata Packet Type scheme
|
||
uint32 SIZE OF PACKET
|
||
* FRAMEDATA or PACKET
|
||
|
||
Sync Packet (subset of GLOBAL TYPE 255 Packet) -
|
||
uint16 0xFFFF (type of packet for Global Type 255)
|
||
|
||
|
||
|
||
Frame Timing
|
||
If the global type is not 255, each packet is interpreted as a single full frame, and then will wait for the next
|
||
frame time; For type 255 however, the assumption no longer holds and each frame can have multiple packets, and thus
|
||
needs explicit "sync" packet for proper frame timing.
|
||
|
||
|
||
NOTE FROM DEVELOPER
|
||
In the future, the global packet type will be deprecated.
|
||
|
||
--------------------------------------------------------------------------------
|
||
|
||
TSVM Interchangeable Picture Format (aka iPF Type 1/2)
|
||
|
||
Image is divided into 4x4 blocks and each block is serialised, then the entire iPF blocks are gzipped
|
||
|
||
|
||
# File Structure
|
||
\x1F T S V M i P F
|
||
[HEADER]
|
||
[Blocks.gz]
|
||
|
||
- Header
|
||
uint16 WIDTH
|
||
uint16 HEIGHT
|
||
uint8 HAS ALPHA
|
||
uint8 IPF Type
|
||
0: Type 1 (4:2:0 chroma subsampling)
|
||
1: Type 2 (4:2:2 chroma subsampling)
|
||
byte[10] RESERVED
|
||
uint32 UNCOMPRESSED SIZE
|
||
|
||
- *.gz
|
||
literally a .gz of the iPF bytes
|
||
|
||
- Blocks
|
||
4x4 pixels are sampled, then divided into YCoCg planes.
|
||
CoCg planes are "chroma subsampled" by 4:2:0, then quantised to 4 bits (8 bits for CoCg combined)
|
||
Y plane is quantised to 4 bits
|
||
|
||
By doing so, CoCg planes will reduce to 4 pixels
|
||
For the description of packing, pixels in Y plane will be numbered as:
|
||
0 1 2 3
|
||
4 5 6 7
|
||
8 9 A B
|
||
C D E F
|
||
|
||
Bits are packed like so:
|
||
|
||
uint8 [Cg-Top Left | Co-Top Left]
|
||
uint16 [Y1 | Y0 | Y5 | Y4]
|
||
uint8 [Cg-Top Right | Co-Top Right]
|
||
uint16 [Y3 | Y2 | Y7 | Y6]
|
||
uint8 [Cg-Bottom Left | Co-Bottom Left]
|
||
uint16 [Y9 | Y8 | YD | YC]
|
||
uint8 [Cg-Bottom Right | Co-Bottom Right]
|
||
uint16 [YB | YA | YF | YE]
|
||
(total: 16 bytes)
|
||
|
||
If has alpha, append following bytes for alpha values
|
||
uint16 [a1 | a0 | a5 | a4]
|
||
uint16 [a3 | a2 | a7 | a6]
|
||
uint16 [a9 | a8 | aD | aC]
|
||
uint16 [aB | aA | aF | aE]
|
||
(total: 24 bytes)
|
||
|
||
Subsampling mask:
|
||
|
||
Least significant byte for top-left, most significant for bottom-right
|
||
For example, this default pattern
|
||
|
||
00 00 01 01
|
||
00 00 01 01
|
||
10 10 11 11
|
||
10 10 11 11
|
||
|
||
turns into:
|
||
|
||
01010000 -> 0x30
|
||
01010000 -> 0x30
|
||
11111010 -> 0xFA
|
||
11111010 -> 0xFA
|
||
|
||
which packs into: [ 30 | 30 | FA | FA ] (because little endian)
|
||
|
||
--------------------------------------------------------------------------------
|
||
|
||
Sound Adapter
|
||
|
||
Endianness: little
|
||
|
||
0..114687 RW: Sample bin
|
||
114688..131071 RW: Instrument bin (256 instruments, 64 bytes each)
|
||
131072..196607 RW: Play data 1
|
||
196608..262143 RW: Play data 2
|
||
|
||
Sample bin: just raw sample data thrown in there. You need to keep track of starting point for each sample
|
||
|
||
Instrument bin: Registry for 256 instruments, formatted as:
|
||
Uint16 Sample Pointer
|
||
Uint16 Sample length
|
||
Uint16 Sampling rate at C3
|
||
Uint16 Loop start
|
||
Uint16 Loop end
|
||
Bit16 Flags
|
||
0b h000 00pp
|
||
h: sample pointer high bit
|
||
pp: loop mode. 0-no loop, 1-loop, 2-backandforth, 3-oneshot (ignores note length unless overridden by other notes)
|
||
Bit32 Unused
|
||
Bit16x24 Volume envelopes
|
||
Byte 1: Volume
|
||
Byte 2: Second offset from the prev point, in 3.5 Unsigned Minifloat
|
||
|
||
Play Data: play data are series of tracker-like instructions, visualised as:
|
||
|
||
rr||NOTE|Ins|E.Vol|E.Pan|EE.ff|
|
||
63||FFFF|255|3+ 64|3+ 64|16 FF| (8 bytes per line, 512 bytes per pattern, 256 patterns on 128 kB block)
|
||
|
||
notes are tuned as 4096 Tone-Equal Temperament. Tuning is set per-sample using their Sampling rate value.
|
||
|
||
|
||
Sound Adapter MMIO
|
||
|
||
0..1 RW: Play head #1 position
|
||
2..3 RW: Play head #1 length param
|
||
4 RW: Play head #1 master volume
|
||
5 RW: Play head #1 master pan
|
||
6..9 RW: Play head #1 flags
|
||
|
||
10..11 RW:Play head #2 position
|
||
12..13 RW:Play head #2 length param
|
||
14 RW: Play head #2 master volume
|
||
15 RW: Play head #2 master pan
|
||
16..19 RW:Play head #2 flags
|
||
|
||
... auto-fill to Play head #4
|
||
|
||
32 ??: ???
|
||
|
||
Sound Hardware Info
|
||
- Sampling rate: 30000 Hz
|
||
- Bit depth: 8 bits/sample, unsigned
|
||
- Always operate in stereo (mono samples must be expanded to stereo before uploading)
|
||
|
||
Play Head Position
|
||
- Tracker mode: Cuesheet Counter
|
||
- PCM mode: Number of buffers uploaded and received by the adapter
|
||
|
||
Length Param
|
||
PCM Mode: length of the samples to upload to the speaker
|
||
Tracker mode: unused
|
||
|
||
Play Head Flags
|
||
Byte 1
|
||
- 0b mrqp ssss
|
||
m: mode (0 for Tracker, 1 for PCM)
|
||
r: reset parameters; always 0 when read
|
||
resetting will:
|
||
set position to 0,
|
||
set length param to 0,
|
||
unset play bit
|
||
q: purge queues (likely do nothing if not PCM); always 0 when read
|
||
p: play (0 if not -- mute all output)
|
||
|
||
ssss: PCM Mode set PCM Queue Size
|
||
0 - 4 samples
|
||
1 - 6 samples
|
||
2 - 8 samples
|
||
3 - 12 samples
|
||
4 - 16 samples
|
||
5 - 24 samples
|
||
6 - 32 samples
|
||
7 - 48 samples
|
||
8 - 64 samples
|
||
9 - 96 samples
|
||
10 - 128 samples
|
||
11 - 192 samples
|
||
12 - 256 samples
|
||
13 - 384 samples
|
||
14 - 512 samples
|
||
15 - 768 samples
|
||
|
||
NOTE: changing from PCM mode to Tracker mode or vice versa will also reset the parameters as described above
|
||
Byte 2
|
||
- PCM Mode: Write non-zero value to start uploading; always 0 when read
|
||
|
||
Byte 3 (Tracker Mode)
|
||
- BPM (24 to 280. Play Data will change this register)
|
||
Byte 4 (Tracker Mode)
|
||
- Tick Rate (Play Data will change this register)
|
||
|
||
Uploaded PCM data will be stored onto the queue before being consumed by hardware.
|
||
If the queue is full, any more uploads will be silently discarded.
|
||
|
||
|
||
32768..65535 RW: Cue Sheet (2048 cues)
|
||
Byte 1..15: pattern number for voice 1..15
|
||
Byte 16: instruction
|
||
1 xxxxxxx - Go back (128, 1-127) patterns to form a loop
|
||
01 xxxxxx -
|
||
001 xxxxx -
|
||
0001 xxxx - Skip (16, 1-15) patterns
|
||
00001 xxx -
|
||
000001 xx -
|
||
0000001 x -
|
||
0000000 1 -
|
||
0000000 0 - No operation
|
||
|
||
65536..131071 RW: PCM Sample buffer |