The SP0256 can address 60Kbytes (480Kbits) of internal or external ROM, however, usally the ROMs are only 2Kbytes (16Kbit). The ROM contains plain program code, without any kind of data arrays.
The upper 4bit of the program counter cannot be zero, so the memory starts at byte-address 1000h, and ends at FFFFh. The first 512 bytes are entrypoints, usually containing JUMP opcodes for up to 256 allophones or words.
The opcodes and their parameters are transferred serially, LSB first (except, for some reason, the JUMP/CALL/SETPAGE "Target" values are MSB first).
The JUMP/CALL/RET opcodes can address only byte-aligned addresses, however, opcodes aren't always multiples of 8bits in size, so following opcodes may begin on any bit boundary.
0000b SETPAGE/RET Set Page for JUMP/CALL, or Return from CALL 0001b SETMODE Set the MODE bits and Repeat MSBs 0010b LOAD_23 Load Pitch, Amplitude, 2-3 Coefficients 0011b LOAD_56 Load Pitch, Amplitude, 5-6 Coefficients 0100b LOAD_56D Load Pitch, Amplitude, 5-6 Coefficients, Delta 0101b SETMSB_3 Load Amplitude, MSBs of 3 Coefficients 0110b SETMSB_23 Load Amplitude, MSBs of 2 or 3 Coeffcients 0111b LOAD_PA Load Pitch, Amplitude 1000b LOAD_ALL Load All Parameters (at full 8bit precision) 1001b DELTA_56 Add Delta to Amplitude, Pitch, 5 or 6 Coefficients 1010b SETMSB_3P Load Amplitude, MSBs of 3 Coefficients, Pitch 1011b DELTA_23 Add Delta to Amplitude, Pitch, 2 or 3 Coefficients 1100b SETMSB_3D Load Amplitude, MSBs of 3 Coefficients, Delta 1101b CALL Jump to Subroutine (12-bit PAGE-Relative Address) 1110b JUMP Jump to 12-bit PAGE-Relative Address 1111b PAUSE Silent Pause
Each opcode starts with a 4bit parameter field, followed by the 4bit opcode number, eventually followed by further Nbit parameter(s).
- Opcode 1110b - JUMP - Jump to 12-bit PAGE-Relative Address
- Opcode 1101b - CALL - Jump to Subroutine (12-bit PAGE-Relative Address)
4 Target bit8-11 (in reversed bit-order!) 4 Opcode (must be 1110b or 1101b) 8 Target bit0-7 (in reversed bit-order!) 0..7 Byte-alignment for next opcode (should be padded with 0 bits)
Jumps to the specified memory address, Target bit12-15 are taken from the PAGE register (which is usually 01h, set like so on power up, but can be set to other values in range 01h..0Fh via SETPAGE). CALL pushes the 16bit byte-aligned return address onto stack, and marks the stack as not empty. The previous contents of the stack are lost (the stack is only one entry deep).
- Opcode 0000b with Zero-Operand - RET - Return from Subroutine (or HALT)
4 Zero for RET (00h=Return) 4 Opcode (must be 0000b) 0..7 Byte-alignment for next opcode (should be padded with 0 bits)
If the stack was not empty: Jumps to the pushed return address (ie. to the next byte after the most recent CALL opcode), and marks the stack as empty. If the stack was already empty: Enters HALT state until/unless new data is/was input via /ALD pin. As soon as new data is available, it jumps to 1000h+data*2. Note: HALT state stops program execution, but does not stop the sound generator - to obtain silence, issue a short PAUSE (or another opcode that sets amplitude=0).
- Opcode 0000b with Nonzero-Operand - SETPAGE - Set the PAGE register
4 Target bit12-15 (in reversed bit-order!) (01h..0Fh=Page) The above target bits are used for ALL following JUMP/CALL opcodes 4 Opcode (must be 0000b)
The PAGE register retains its setting until the next SETPAGE is encountered. (Note that address loads via ALD appear to ignore PAGE, and set the four MSBs to $1000. They do not modify the PAGE register, so subsequent JUMP/CALL instructions will jump relative to the current value in PAGE.)
- Opcode 0001b - SETMODE - Set the MODE bits and Repeat MSBs
2 Repeat Count bit4-5 (expands the next ONE opcode that uses 4bit repeat) 1 WIDTH for ALL following opcodes (0=Smaller, 1=Bigger bit-width) 1 EXTRA for ALL following opcodes (0=Exclude, 1=Include optional params) 4 Opcode (must be 0001b)
Some opcodes have coefficient parameters of variable width (for example "3/6" means 3bit or 6bit), the smaller width is used when WIDTH=0, the bigger when WIDTH=1. Some opcodes have optional parameters (for example "(8)" means an optional 8bit parameter), which is included in the opcode only when EXTRA=1.
- Opcode 1111b - PAUSE - Silent Pause
4 Repeat Count 4 Opcode (must be 1111b)
Provides a silent pause of varying length. The pause behaves identially to a pitch with Amplitude=0 and Period=64. All coefficients are cleared, as well.
- Opcode 0111b - LOAD_PA - Load Pitch, Amplitude
4 Repeat Count 4 Opcode (must be 0111b) 6 Amplitude MSBs (upper 3bit are exponent) 8 Pitch (00h=Noise)
- Opcode 1000b - LOAD_ALL - Load All Parameters (at full 8bit precision)
4 Repeat Count 4 Opcode (must be 1000b) 8 Amplitude unsigned (upper 3bit are exponent) 8 Pitch unsigned (00h=Noise) 8 Coeff B0 signed ;\coeff pair 0 8 Coeff F0 signed ;/ 8 Coeff B1 signed ;\coeff pair 1 8 Coeff F1 signed ;/ 8 Coeff B2 signed ;\coeff pair 2 8 Coeff F2 signed ;/ 8 Coeff B3 signed ;\coeff pair 3 8 Coeff F3 signed ;/ 8 Coeff B4 signed ;\coeff pair 4 8 Coeff F4 signed ;/ 8 Coeff B5 signed ;\coeff pair 5 8 Coeff F5 signed ;/ (8) Amplitude Interpolation, signed ;\when EXTRA=1 only (8) Pitch Interpolation, signed ;/
Notes: The pitch and amplitude deltas that are available when EXTRA=1 are applied every pitch period, not just once. Wraparound may occur. If the Pitch goes to zero, the periodic excitation switches to noise.
- Opcode 0010b - LOAD_23 - Load Pitch, Amplitude, 2-3 Coefficients
- Opcode 0011b - LOAD_56 - Load Pitch, Amplitude, 5-6 Coefficients
- Opcode 0100b - LOAD_56D - Load Pitch, Amplitude, 5-6 Coefficients, Delta
4 Repeat Count 4 Opcode (must be 0010b or 0011b or 0100b) 6 Amplitude MSBs (upper 3bit are exponent) 8 Pitch (00h=Noise) 3/6 Coeff B0 Bit4/1..6 unsigned ;\coeff pair 0 ;\ 5/6 Coeff F0 Bit3/2..7 signed ;/ ; 3/6 Coeff B1 Bit4/1..6 unsigned ;\coeff pair 1 ; opcode LOAD_56D, 5/6 Coeff F1 Bit3/2..7 signed ;/ ; and LOAD_56 only 3/6 Coeff B2 Bit4/1..6 unsigned ;\coeff pair 2 ; 5/6 Coeff F2 Bit3/2..7 signed ;/ ;/ 4/6 Coeff B3 Bit3/1..6 unsigned ;\coeff pair 3 6/7 Coeff F3 Bit2/1..7 signed ;/ 7/8 Coeff B4 Bit1/0..7 signed ;\coeff pair 4 6/8 Coeff F4 Bit2/0..7 signed ;/ (8) Coeff B5 Bit0..7 signed ;\coeff pair 5 ;\when EXTRA=1 only (8) Coeff F5 Bit0..7 signed ;/ ;/ 5 Amplitude Interpolation LSBs, unsigned ;\opcode LOAD_56D only 5 Pitch Interpolation LSBs, unsigned ;/
Sets the unspecified coefficients to 0. The "unsigned" B0,B1,B2,B3 values are zero-expanded from N bits to (N+1) bits, and are then copied to the upper (N+1) bits of the register.
- Opcode 0110b - SETMSB_23 - Load Amplitude, MSBs of 2 or 3 Coeffcients
- Opcode 0101b - SETMSB_3 - Load Amplitude, MSBs of 3 Coefficients
- Opcode 1010b - SETMSB_3P - Load Amplitude, MSBs of 3 Coefficients, Pitch
- Opcode 1100b - SETMSB_3D - Load Amplitude, MSBs of 3 Coefficients, Delta
4 Repeat Count 4 Opcode (must be 0101b or 0110b or 1010b or 1100b) 6 Amplitude MSBs (upper 3bit are exponent)  Pitch (00h=Noise) ;-Opcode SETMSB_3P only 5/6 New F0 MSBs signed ;\ 5/6 New F1 MSBs signed ; Opcode SETMSB_3/3P/3D only 5/6 New F2 MSBs signed ;/ 6/7 New F3 MSBs signed ;\ 6/8 New F4 MSBs signed ; Opcode SETMSB_23 only (8) New F5 MSBs signed (when EXTRA=1 only) ;/ (0) Set F5=0 and B5=0 (when EXTRA=0 only)  Amplitude Interpolation LSBs, unsigned ;\Opcode SETMSB_3D only  Pitch Interpolation LSBs, unsigned ;/
All other coefficient bits are unaffected (ie. all coefficients that aren't accessed by the specific opcode, as well as LSBs of accessed coefficients).
- Opcode 1001b - DELTA_56 - Add Delta to Amplitude, Pitch, 5 or 6 Coefficients
- Opcode 1011b - DELTA_23 - Add Delta to Amplitude, Pitch, 2 or 3 Coefficients
4 Repeat Count 4 Opcode (must be 1001b or 1011b) 4 Amplitude Interpolation 6 MSBs signed 5 Pitch Interpolation LSBs signed 3/4 B0 4,7 MSBs signed ;\ ;\ 3/4 F0 5,6 MSBs signed ;/ ; 3/4 B1 4,7 MSBs signed ;\ ; opcode DELTA_56 only 3/4 F1 5,6 MSBs signed ;/ ; 3/4 B2 4,7 MSBs signed ;\ ; 3/4 F2 5,6 MSBs signed ;/ ;/ 3/4 B3 5,7 MSBs signed ;\ 4/5 F3 6,7 MSBs signed ;/ 4/5 B4 x,8 MSBs signed ;\ <---- DELTA_56: x=6, and DELTA_23: x=7 (?) 4/5 F4 6,8 MSBs signed ;/ (5) B5 (8) MSBs signed ;\ ;\when EXTRA=1 only (5) F5 (8) MSBs signed ;/ ;/
Performs a delta update, adding small 2s complement numbers to a series of coefficients. The 2s complement updates for the various filter coefficients only update some of the MSBs -- the LSBs are unaffected. The exact bits which are updated are noted above. Normal 2s complement arithmetic is performed, and no protection is provided against overflow. Adding 1 to the largest value for a bit field wraps around to the smallest value for that bitfield. Notes: The delta update is applied only once (even if the repeat count is bigger than 1).
The delta updates are applied to the 8-bit encoded forms of the coefficients, not the 10-bit decoded forms. The update to the amplitude register is a normal 2s complement update to the entire register. This means that any carry/borrow from the mantissa will change the value of the exponent. The update doesn't know anything about the format of that register.
Program Counter and Stack Note
As seen in the datasheets for external speech ROMs, the Program Counter & Stack seem to be part of the ROM (not of the microprocessor). So, when using external ROMs, one would theoretically have separate stacks for each ROM. NB. this explains why the Target values are reversed; apparently the ROMs use different bit-order (for memory addresses) than the microprocessor does for its own values (ie. the opcodes and voice-parameters).
The SP0256 opcodes were reverse engineered by Joe Zbiciak and Frank Palazzolo.
Repeat Count = 0
According to Joe and Frank, a repeat count of zero "causes the instruction to not execute" (and not to fetch any of its following paramters, so the opcode becomes only 8bits long; or to fetch, but not apply them?), however, they've also mentioned that "conflicting documentation suggests there's more going on".
Bit fields narrower than 8 bits are MSB justified unless specified otherwise, meaning that the least significant bits are the ones that are missing. These LSBs are filled with zeros.
When updating filter coefficients with a delta-update, the microsequencer performs plain 2s-complement arithmetic on the 8-bit value in the coefficient register file. No attention is paid to the format of the register.