237 lines
6.3 KiB
ReStructuredText
237 lines
6.3 KiB
ReStructuredText
###########
|
|
scu-dsp-asm
|
|
###########
|
|
|
|
scu-dsp-asm is an assembler for SCU DSP mnemonics, using SEGA syntax.
|
|
|
|
Usage:
|
|
|
|
.. code::
|
|
|
|
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:
|
|
|
|
.. code::
|
|
|
|
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.
|
|
|
|
Current status
|
|
==============
|
|
|
|
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.
|
|
|
|
Differences that affect source code
|
|
===================================
|
|
|
|
M0-M3 must not appear in in DMA source/destination arguments
|
|
------------------------------------------------------------
|
|
|
|
For example, the following are not legal:
|
|
|
|
.. code::
|
|
|
|
DMA D0,M0,#$02
|
|
DMA M1,D0,#$02
|
|
|
|
Instead, they should be written as:
|
|
|
|
.. code::
|
|
|
|
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).
|
|
|
|
Differences that affect code generation
|
|
=======================================
|
|
|
|
Spurious invalid X-bus opcode generation
|
|
----------------------------------------
|
|
|
|
Under seemingly-random circumstances, ``dspasm.exe`` emits the
|
|
undefined X-bus opcode ``001``. Given:
|
|
|
|
.. code::
|
|
|
|
MOV M3,A MOV 1,PL
|
|
|
|
The ``dspasm.exe``-generated code is:
|
|
|
|
.. code::
|
|
|
|
00000000100001101101010100000001
|
|
^
|
|
However, the correct code should be:
|
|
|
|
.. code::
|
|
|
|
00000000000001101101010100000001
|
|
^
|
|
|
|
This is particularly interesting because the example mnemonics did not
|
|
contain any X-bus operation to start with.
|
|
|
|
Motorola S-record output is not supported
|
|
-----------------------------------------
|
|
|
|
It is suspected that this feature is not useful.
|
|
|
|
Misleading, contradictory, and completely incorrect documentation
|
|
=================================================================
|
|
|
|
DMA default "add mode"
|
|
----------------------
|
|
|
|
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 for ``DMA2``
|
|
|
|
- ``DMAH`` is a synonym for ``DMAH2``
|
|
|
|
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.
|
|
|
|
DMA "add mode" and bytes
|
|
------------------------
|
|
|
|
All of the documentation you have read is invalid; this is the correct
|
|
relationship between DMA "add mode" mnemonics. The right columns represent the
|
|
the increment added an offset of RA0/WA0 after each bus transfer:
|
|
|
|
.. list-table::
|
|
:header-rows: 1
|
|
:stub-columns: 1
|
|
|
|
* - 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:
|
|
|
|
.. code:: c
|
|
|
|
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 = { 1, 1, 3, 3, ... };
|
|
|
|
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.
|
|
|
|
Syntax features that are supported, but with misleading consequences
|
|
====================================================================
|
|
|
|
``NOP`` mnemonics inside OP instructions
|
|
----------------------------------------
|
|
|
|
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:
|
|
|
|
.. 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.
|
|
|
|
Immediates with ``:``-suffixes or ``#``-prefixes
|
|
------------------------------------------------
|
|
|
|
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:
|
|
|
|
.. 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.
|