scu-dsp-asm is an assembler for SCU DSP mnemonics, using SEGA syntax.
Usage:
scu-dsp-asm input-file.asm output-file.bin
Alternately, use the -s
(source code) command-line argument to
emit a C-syntax source code fragment:
scu-dsp-asm -s input-file.asm output-file.inc
If no arguments are given, scu-dsp-asm starts a basic REPL.
Wherever possible, scu-dsp-asm attempts to preserve compatibility with
the same source code used with the SEGA-authored dspasm.exe
,
except in the cases where dspasm.exe
behavior is considered a
bug.
100% of the documented dspasm.exe features are supported, as well as miscellaneous undocumented features.
scu-dsp-asm correctly assembles all of the examples in the test/ directory in this repository, with caveats listed below.
scp-dsp-asm has not been tested exhaustively, and the test programs do not cover 100% of the possible SCU DSP instructions or arguments.
For example, the following are not legal:
DMA D0,M0,#$02 DMA M1,D0,#$02
Instead, they should be written as:
DMA D0,MC0,#$02 DMA MC1,D0,#$02
dspasm.exe
generates the same code given either the former or
latter example as input. scu-dsp-asm, however, rejects the former
example as invalid: it misleads what the result of the operation is.
This change is not consistent with what is written in the SCU manual (ST-97-R5-072694).
Under seemingly-random circumstances, dspasm.exe
emits the
undefined X-bus opcode 001
. Given:
MOV M3,A MOV 1,PL
The dspasm.exe
-generated code is:
00000000100001101101010100000001 ^
However, the correct code should be:
00000000000001101101010100000001 ^
This is particularly interesting because the example mnemonics did not contain any X-bus operation to start with.
It is suspected that this feature is not useful.
Contrast to what is written in the SCU manual (ST-97-R5-072694), the
default DMA "add mode" for both dspasm.exe and scp-dsp-asm is
2
. E.g:
DMA
is a synonym forDMA2
DMAH
is a synonym forDMAH2
In "Sega Developers Conference Conference Proceedings March 5-7, 1996" pdf page 48, printed page 3-14, slide 25:
You need to modify your object code, either by hand or with a custom tool.
This is completely incorrect, and both scu-dsp-asm and dspasm.exe will
emit "add mode 1" via the DMA1
and DMAH1
mnemonics.
All of the SEGA-authored documentation on this topic is invalid. The the correct relationship between DMA "add mode" mnemonics and bus address offsets is shown below. The right columns represent the increment added to the bus address after each bus transfer:
mnemonic | D0 → [RAM] | [RAM] → D0 |
---|---|---|
DMA0 | 0 bytes | 0 bytes |
DMA1 | 0 bytes | 2 bytes |
DMA2 | 4 bytes | 4 bytes |
DMA4 | 4 bytes | 8 bytes |
DMA8 | 0 bytes | 16 bytes |
DMA16 | 0 bytes | 32 bytes |
DMA32 | 4 bytes | 64 bytes |
DMA64 | 4 bytes | 128 bytes |
Note that the DMA transfer length is always decremented by 1 after 4 bytes are transferred, regardless of the size of the bus transfer.
Note that selecting DMA1 on a 4-byte bus does not generate misaligned writes; instead, the following happens:
uint32_t src[] = { 1, 2, 3, 4, ... };
extern uint32_t dst[];
dst[0] = src[0];
dst[0] = src[1];
dst[1] = src[2];
dst[1] = src[3];
...
// dst = { 2, 2, 4, 4, ... };
The SCU manual (ST-97-R5-072694) contains this contradictory text:
Only add numbers 0 and 1 are valid for the A-Bus and the write unit is 32bit. [...] Write unit is 16bit; 32bit data is divided in half and written at intervals of 16X (0-64).
"Multiply the 'add number' by the [number of bytes per transfer] depending on the value of WA0/RA0" is completely incorrect. The text in the original Japanese document is also incorrect.
In both scu-dsp-asm and dspasm.exe
, ALU, X-bus, Y-bus, and D1-bus mnemonics
may appear in any order in a single OP instruction and/or line of source code.
From a grammar perspective, it is impossible to disambiguate which bus a NOP
is referring to. For example, this is valid code:
NOP NOP NOP NOP MOV MUL,P
Even though it visually might appear that the X-bus operation might be
simultaneously NOP
and MOV MUL,P
, due to syntactical ambiguity the
assembler is not able to generate an error for this case.
There is no restriction on the number of NOP
values that can appear on a
single line.
Feel free to use this syntax feature if desired stylistically, but be aware
scu-dsp-asm is not able to verify intent, and does not/can not generate errors
related to a "conflict" between a NOP
mnemonic and any other bus operation.
In both scu-dsp-asm and dspasm.exe
, neither of these characters mean
anything in the grammar. If encountered, they are ignored.
For example, all of the following is valid source code:
MVI #1,MC0 MVI 1:,MC0 MVI #foobar,MC0 MVI #foobar:,MC0 MVI #1+1:,MC0 MVI #(1+1):,MC0
Feel free to use these characters if desired stylistically, but be aware that scu-dsp-asm does not generate errors regardless of how they are used.