flycast/docs/neil_corlett_aica_notes.txt

1067 lines
40 KiB
Plaintext

-----------------------------------------------------------------------------
Neill Corlett's Yamaha AICA notes
Based on:
- The official AICA spec
- Yamato's aica_v08.txt (yamato@20to4.net)
- Much experimentation
-----------------------------------------------------------------------------
LOGARITHMIC VOLUMES
Like many Yamaha sound chips, the AICA uses logarithmic volume levels.
Here's how that works:
A value of 0 means no attenuation, or full volume. From there, every
increment of a constant amount decreases the volume level by 3dB. Of course,
"3dB" in the literature is just a fancy way of saying "half". And the values
aren't logarithmic at all, but a log/linear approximation.
To convert a "logarithmic" attenuation level to a volume multiplier:
1. You first need to know what increment constitutes a 3dB decrease. We'll
call this I. This is going to always be a power of 2.
2. Divide (by which I mean shift) the attenuation level by this constant to
get the "exponent", and the remaining lowest bits are the "mantissa".
3. Invert all bits in the mantissa, then add I to it.
4. Shift the mantissa left to whatever precision you want.
5. Shift the mantissa right by the exponent.
One of the advantages of logarithmic attenuation levels is that you can apply
several volumes on top of each other by adding them, and this has the same
effect as if you'd multiplied the linear volume levels together. I suspect
this is what's happening, though I haven't tested specifically for it yet.
-----------------------------------------------------------------------------
RESAMPLING
...appears to be linear.
-----------------------------------------------------------------------------
AMPLITUDE ENVELOPE CALCULATION
This is a typical 4-stage envelope: Attack, Decay, Sustain, Release. The
envelope gets louder during attack, and can only remain the same or quieter
during Decay, Sustain, and Release. (There is no increase sustain mode.)
The envelope uses a logarithmic attenuation level where 0 means no
attenuation (full volume) and every increment of 0x40 decreases the volume
by 3dB. The level can range from 0x000 to 0x3BF. Note that if the
attenuation level exceeds 0x3BF _at any time_, the channel will become
inactive and the attenuation level will appear as 0x1FFF.
"EFFECTIVE RATE" refers to the following:
- If KRS == 0xF: EFFECTIVE RATE = RATE*2
- If KRS < 0xF: EFFECTIVE RATE = (KRS+OCT+RATE)*2+FNS
(where FNS is bit 9 of SampleRatePitch)
EFFECTIVE RATE is truncated to the range of 0x00-0x3C if necessary.
After a key on, the attack attenuation level begins at 0x280. Note that a
key on event is completely ignored unless the channel is either inactive
(attenuation level exceeds 0x3BF) or is presently in the release state.
During attack, subtract ((currentlevel >> N)+1) from the current level at
each step, where N is the following:
STEP mod 4 is
EFFECTIVE RATE 0 1 2 3
------------------------------------
0x30 or less 4 4 4 4
0x31 3 4 4 4
0x32 3 4 3 4
0x33 3 3 3 4
0x34 3 3 3 3
0x35 2 3 3 3
0x36 2 3 2 3
0x37 2 2 2 3
0x38 2 2 2 2
0x39 1 2 2 2
0x3A 1 2 1 2
0x3B 1 1 1 2
0x3C or greater 1 1 1 1
Once the envelope level reaches 0, transition to the decay state.
Decay is linear in the attenuation level. Simply add the following constants
to the attenuation level at each step:
STEP mod 4 is
EFFECTIVE RATE 0 1 2 3
------------------------------------
0x30 or less 1 1 1 1
0x31 2 1 1 1
0x32 2 1 2 1
0x33 2 2 2 1
0x34 2 2 2 2
0x35 4 2 2 2
0x36 4 2 4 2
0x37 4 4 4 2
0x38 4 4 4 4
0x39 8 4 4 4
0x3A 8 4 8 4
0x3B 8 8 8 4
0x3C or greater 8 8 8 8
The step timing, for both attack and decay, is as follows:
EFFECTIVE RATE Step occurs every N samples
--------------------------------------------------
0x00 Never
0x01 Never
0x02 8192, 4096, 4096
0x03 8192, 4096, 4096, 4096, 4096, 4096, 4096
0x04 4096
0x05 4096, 4096, 4096, 2048, 2048
0x06 (same as 0x02 shifted right by 1)
... ...
0x30 and up 2
During decay, when the attenuation level reaches the "decay level", defined
as DL << 5, transition to the sustain state.
Sustain follows the same formula as decay and continues until either the
envelope attenuation level exceeds 0x3BF, or a key off event occurs.
After a key off, transition to the release state. Release also follows the
same formula as decay. When the envelope attenuation level exceeds 0x3BF,
the channel becomes inactive.
If "voff" is set, then this envelope is still computed, but the attenuation
has no effect. However, the channel will still end abruptly once the level
exceeds 0x3BF.
-----------------------------------------------------------------------------
FILTER ENVELOPE CALCULATION
Filter envelopes follow the same step timings as amplitude envelopes (key
scaling is also shared between filter and amplitude), and likely the same
step sizes as in the decay phases of amplitude envelopes (based on a few
trials).
The only difference is that instead of an attenuation level, it uses a 13-bit
lowpass value.
- Start at FLV0
- Attack: Add or subtract the attack step size until you reach FLV1
- Decay: Add or subtract the decay (1) step size until you reach FLV2
- Sustain: Add or subtract the sustain (2) step size until you reach FLV3
- Wait for a key off
- Release: Add or subtract the release step size
If "lpoff" is set, then this envelope is still computed, but the filter
itself has no effect.
-----------------------------------------------------------------------------
LOW FREQUENCY OSCILLATOR (LFO)
There are 6 components to the LFO:
- The "reset" bit, meaning the LFO phase is zeroed on every sample loop start
- The LFO frequency (0x00-0x1F)
- Pitch modulation waveform type
- Pitch modulation depth
- Amplitude modulation waveform type
- Amplitude modulation depth
Here is the LFO period, in samples, for every frequency value:
f=0x00:0x3FC00 f=0x08:0x0FC00 f=0x10:0x03C00 f=0x18:0x00C00
f=0x01:0x37C00 f=0x09:0x0BC00 f=0x11:0x03400 f=0x19:0x00A00
f=0x02:0x2FC00 f=0x0A:0x0DC00 f=0x12:0x02C00 f=0x1A:0x00800
f=0x03:0x27C00 f=0x0B:0x09C00 f=0x13:0x02400 f=0x1B:0x00600
f=0x04:0x1FC00 f=0x0C:0x07C00 f=0x14:0x01C00 f=0x1C:0x00400
f=0x05:0x1BC00 f=0x0D:0x06C00 f=0x15:0x01800 f=0x1D:0x00300
f=0x06:0x17C00 f=0x0E:0x05C00 f=0x16:0x01400 f=0x1E:0x00200
f=0x07:0x13C00 f=0x0F:0x04C00 f=0x17:0x01000 f=0x1F:0x00100
LFO pitch depth:
The pitch can vary by a maximum of plus or minus (base phaseinc)>>(10-d)
d=0: do not apply pitch modulation
d=1: base phaseinc of 0x40000 can sway from 0x3FE00 to 0x40200
...
d=7: base phaseinc of 0x40000 can sway from 0x38000 to 0x48000
LFO pitch waveform:
0: sawtooth, starting in the middle, going higher
1: square, high pitch for first half, low pitch for second half
2: triangle, starting in the middle, going higher, much like sin(x)
3: noise
LFO amplitude depth:
Amplitude modulation adds positive values to the envelope attenuation, so it
can only make the resulting output softer, not louder.
d=7: can add up to 24dB or 0x200 to envelope attenuation
d=6: can add up to 12dB or 0x100 to envelope attenuation
d=5: can add up to 6dB or 0x080 to envelope attenuation
d=4: can add up to 3dB or 0x040 to envelope attenuation
d=3: can add up to 0x020 to envelope attenuation
d=2: can add up to 0x010 to envelope attenuation
d=1: can add up to 0x008 to envelope attenuation
d=0: do not apply amplitude modulation
LFO amplitude waveform:
0: sawtooth, starting at 0 (no attenuation), going up (more attenuation)
1: square, 0 for first half, max attenuation second half
2: triangle, starting at 0, going down then up
3: noise
LFO phase resets on every sample loop start if the reset bit is set.
It never resets in any other circumstances (not even on key on).
-----------------------------------------------------------------------------
RESONANT LOWPASS FILTER
If lpoff=0, the channel output is run through a resonant lowpass filter. The
algorithm works like this:
out = f * in + (1.0 - f + q) * prev_out - q * prev_prev_out
Where f and q are coefficients. Exactly how f and q are computed, I'm still
not 100% sure. I have a fairly good idea for f:
f = (((filtervalue & 0xFF) | 0x100) << 4) >> ((filtervalue>>8)^0x1F)
Where filtervalue is the filter envelope level, and f becomes a linear value
in the range of 0x0000 (0.0) to 0x1FFF (almost 1.0).
I'm less certain about q. For now, I intend to simply use the Q register
value, where 0x00=0.0 and 0x20=1.0 (max is 0x1F).
-----------------------------------------------------------------------------
ADPCM SAMPLE FORMAT
The ADPCM sample format is standard Yamaha ADPCM. It's the same format used
in the YMZ280B.
-----------------------------------------------------------------------------
REGISTERS
The AICA registers are accessible starting at 0x800000 on the ARM7 side and
0xA0700000 on the SH4 side. Register addresses in this document will usually
refer to an offset from either 0x800000 or 0xA0700000.
There are 64 channels and a set of registers associated with each, a set of
common registers, and a set of registers associated with the effects DSP.
-----------------------------------------------------------------------------
CHANNEL REGISTERS
The area at 0x0000-0x1FFF contains the channel registers. There are 32
32-bit registers for each channel, but only the first 18 are used, and only
the lowest 16 bits have any effect.
Channel 0's registers start at 0x0000, channel 1's at 0x0080, and so on.
All register writes take effect immediately. NONE of the channel registers
are temporarily stored until key-on (as was the case on the PSX SPU).
When you read from a channel register, you'll simply get the last value that
was written to it, EXCEPT for bits which are not saved (always return 0).
These bits are clearly labeled below.
-----------------------------------------------------------------------------
0x00 - PlayControl
bit 15 = key on execute (KYONEX) [NOY SAVED, always 0 when read]
Writing a 1 bit here will execute a key on for every channel that
has KYONB=1, and a key off for every channel that has KYONB=0,
simultaneously. There's no way to single out individual
channels. (Though it works out since redundant key on/key off
events are ignored.)
bit 14 = key on bit (KYONB)
Set this to either 1 or 0 to "mark" a channel for key on or off.
bit 13-11 = unused [NOT SAVED, always 0 when read]
bit 10 = noise enable (SSCTL)
0 means read sample data from RAM, as per usual
1 means use random data instead of actually reading RAM.
This seems to only affect what bytes are read. If you have the
sample format set to 16-bit, you'll get random 16-bit samples.
If you have the format set to ADPCM, you'll get random ADPCM
samples, but I think they're still run through the ADPCM decoder.
bit 9 = sample loop (LPCTL) 1=enabled, 0=disabled
bit 8-7 = sample format (PCMS)
0 = 16-bit signed little-endian
1 = 8-bit signed
2 = 4-bit Yamaha ADPCM
3 = prohibited
Actual behavior seems to be "sample data is all zeroes".
bit 6-0 = highest 7 bits of sample start address (SA) (in bytes)
-----------------------------------------------------------------------------
0x04 - SampleAddrLow
bit 15-0 = lowest 7 bits of sample start address (SA) (in bytes)
-----------------------------------------------------------------------------
0x08 - LoopStart
bit 15-0 = Loop start address (in samples)
Very low values of this may not work depending on the pitch and
loop mode.
-----------------------------------------------------------------------------
0x0C - LoopEnd
bit 15-0 = Loop end address (in samples)
If sample looping is disabled, this acts as the total sample size.
Very high values may not work depending on the pitch and loop
mode.
Also, you can't set this to 0xFFFF if you expect the interpolation
to work.
-----------------------------------------------------------------------------
0x10 - AmpEnv1
bit 15-11 = sustain rate (D2R) rate, 0x00-0x1F
bit 10-6 = decay rate (D1R), 0x00-0x1F
bit 5 = unused [NOT SAVED, always 0 when read]
bit 4-0 = attack rate (AR), 0x00-0x1F
-----------------------------------------------------------------------------
0x14 - AmpEnv2
bit 15 = unused [NOT SAVED, always 0 when read]
bit 14 = link (LPSLNK), 1=on 0=off
If this bit is set, then the envelope transitions to the decay
state when the sample loop start address is exceeded.
bit 13-10 = key rate scaling (KRS), 0x0-0xF
See the amplitude envelope notes for details on this.
0xF means that all scaling is OFF.
bit 9-5 = decay level (DL), 0x00-0x1F
bit 4-0 = release rate (RR), 0x00-0x1F
-----------------------------------------------------------------------------
0x18 - SampleRatePitch
bit 15 = unused [SAVED]
bit 14-11 = octave (OCT), signed value, -0x8 to 0x7
bit 10-0 = FNS
This is basically a phase increment value, just computed in a peculiar way.
phaseinc = (FNS ^ 0x400) << ((unsigned OCT value) ^ 0x8)
There's 18 fractional phase bits, so phaseinc=0x40000 is the base frequency,
or 44100Hz.
Supposedly if the signed OCT value is 2 or higher, and the sample format is
ADPCM, the actual octave is one higher.
-----------------------------------------------------------------------------
0x1C - LFOControl
bit 15 = reset (LFORE) 1=on, 0=off
If set, the LFO phase is reset at the start of EACH SAMPLE LOOP.
bit 14-10 = frequency (LFOF)
bit 9-8 = pitch modulation waveform (PLFOWS)
bit 5-7 = pitch modulation depth (PLFOS)
bit 4-3 = amplitude modulation waveform (ALFOWS)
bit 2-0 = amplitude modulation depth (ALFOS)
See the LFO notes for more details.
-----------------------------------------------------------------------------
0x20 - DSPChannelSend
bit 15-8 = unused [NOT SAVED, always 0 when read]
bit 7-4 = DSP send level, 0x0-0xF
Scales the output of this channel to one of the effect send buses.
0xF is full volume (no attenuation), every level beneath that adds
3dB, and 0x0 means no output.
bit 3-0 = DSP send channel, 0x0-0xF
This affects which DSP MIXS register will receive this channel's
output.
I have verified that bit 19 of MIXS corresponds to bit 15 of a
single 16-bit sample played at the maximum possible volume.
-----------------------------------------------------------------------------
0x24 - DirectPanVolSend
bit 15-12 = unused [SAVED]
bit 11-8 = Direct send volume (DISDL), 0x0-0xF
Affects how much of this channel is being sent directly to the
dry output. 0xF is full volume (no attenuation), every level
beneath that adds 3dB, and 0x0 means no output. (I have verified
this.)
bit 7-5 = unused [SAVED]
bit 4-0 = Direct send pan (DIPAN), 0x00-0x1F
0x00 or 0x10 is center, 0x0F is full right, 0x1F is full left
0x00-0x0F: each step beyond 0x00 attenuates the left side by 3db
(right side remains at same volume)
0x10-0x1F: each step beyond 0x10 attenuates the right side by 3db
(left side remains at same volume)
-----------------------------------------------------------------------------
0x28 - LPF1Volume
bit 15-8 = constant attenuation (I think this may be TL)
this value *4 seems to be added to the envelope attenuation
(as in, 0x00-0xFF here corresponds to 0x000-0x3FF when referring
to the envelope attenuation)
every 0x10 on the constant attenuation is 3dB
bit 7 = unknown [SAVED]
bit 6 = voff
if this bit is set to 1, the constant attenuation, envelope, and
LFO volumes will not take effect. however, the note will still
end when the envelope level reaches zero in the release state.
bit 5 = lpoff
1 = turn off lowpass filter.
bit 4-0 = Q, 0x00-0x1F
filter resonance value Q = (0.75*value)-3, from -3 to 20.25 db
0x1F = 20.25dB
0x1C = 18dB
0x18 = 15dB
0x10 = 9dB
0x0C = 6dB
0x08 = 3dB
0x04 = 0dB
0x00 = -3dB
-----------------------------------------------------------------------------
0x2C - LPF2
bit 15-13 = unused [NOT SAVED, always 0 when read]
bit 12-0 = filterValue0 (FLV0): starting filter frequency
attack start
-----------------------------------------------------------------------------
0x30 - LPF3
bit 15-13 = unused [NOT SAVED, always 0 when read]
bit 12-0 = filterValue1 (FLV1): stage 1 filter frequency
decay start time
-----------------------------------------------------------------------------
0x34 - LPF4
bit 15-13 = unused [NOT SAVED, always 0 when read]
bit 12-0 = filterValue2 (FLV2): stage 2 filter frequency
sustain start time
-----------------------------------------------------------------------------
0x38 - LPF5
bit 15-13 = unused [NOT SAVED, always 0 when read]
bit 12-0 = filterValue3 (FLV3): stage 3 filter frequency
KeyOff time
-----------------------------------------------------------------------------
0x3C - LPF6
bit 15-13 = unused [NOT SAVED, always 0 when read]
bit 12-0 = filterValue4 (FLV4): release filter frequency
-----------------------------------------------------------------------------
0x40 - LPF7
bit 15-13 = unused [NOT SAVED, always 0 when read]
bit 12-8 = LPF attack rate (FAR), 0x00-0x1F
bit 7-5 = unused [NOT SAVED, always 0 when read]
bit 4-0 = LPF decay rate (FD1R), 0x00-0x1F
----------------------------------------------------------------------------
0x44 - LPF8
bit 15-13 = unused [NOT SAVED, always 0 when read]
bit 12-8 = LPF sustain rate (FD2R), 0x00-0x1F
bit 7-5 = unused [NOT SAVED, always 0 when read]
bit 4-0 = LPF release rate (FRR), 0x00-0x1F
-----------------------------------------------------------------------------
0x48 to 0x7C - unused
-----------------------------------------------------------------------------
COMMON REGISTERS
-----------------------------------------------------------------------------
0x2000-0x2044 - DSP Output Mixer registers
These determine how loudly the DSP effect output channels are played.
bit 15-12 = unused
bit 11-8 = Effect output level (EFSDL), 0x0-0xF
0xF is no attenuation (full volume), and each value below that
increases the attenuation by 3dB.
bit 7-5 = unused
bit 4-0 = Effect output pan (EFPAN), 0x00-0x1F
This works the same as the direct output pan register.
The first 16 registers (0x2000-0x203C) correspond to mixer outputs 0-15.
0x2040 is CDDA output left. 0x2044 is CDDA output right.
-----------------------------------------------------------------------------
0x2800 - MasterVolume
bit 15 = MONO (1=mono, 0=stereo)
In mono mode, pan attenuation values do not take effect.
bit 14-10 = unused
bit 9 = MEM8MB (1=8MB memory, 0=2MB memory)
bit 8 = DAC18B (1=use 18-bit DAC, 0=use 16-bit DAC)
bit 7-4 = LSI version (VER)
Read this to get the LSI version of the chip. Should be 1.
bit 3-0 = Master volume (MVOL)
0xF=no attenuation (full volume)
Every value beneath 0xF decreases the volume by 3dB.
Whenever you read this register, the result should be 0x0010.
-----------------------------------------------------------------------------
0x2804 - RingBufferAddress
bit 15 = $T (used for LSI testing?)
bit 14-13 = Ring buffer size (RBL)
0 = 8Kwords
1 = 16Kwords
2 = 32Kwords
3 = 64Kwords (where "word" means 16-bit)
bit 12 = unused
bit 11-0 = Ring buffer pointer (RBP)
This corresponds to bits 22-11 of an actual RAM address.
Each increment of RBP represents 2Kbytes of memory.
-----------------------------------------------------------------------------
0x2808 - MIDIInput
bit 15-13 = unused
bit 12 = MIDI Output FIFO is full (MOFUL) 1=yes, 0=no
bit 11 = MIDI Output FIFO is empty (MOEMP) 1=yes, 0=no
bit 10 = MIDI Input FIFO has overflowed (MIOVF) 1=yes, 0=no
bit 9 = MIDI Input FIFO is full (MIFUL) 1=yes, 0=no
bit 8 = MIDI Input FIFO is empty (undocumented!) 1=yes, 0=no
bit 7-0 = MIDI Input Buffer (MIBUF)
Data coming in from the MIDI port in a 4-byte FIFO.
Note that when you read this register all at once, the status flags represent
the state of the input FIFO _before_ you read that next byte.
-----------------------------------------------------------------------------
0x280C - ChnInfoReq
bit 15 = unused
bit 14 = Amplitude or Filter select (AFSEL)
0 = we will be monitoring the amplitude envelope
1 = we will be monitoring the filter envelope
bit 13-8 = Monitor select (MSLC), 0x00-0x3F
Selects a channel to monitor using the monitor regs below.
bit 7-0 = MIDI Output Buffer (MOBUF)
Probably best not to write stuff here under normal circumstances
-----------------------------------------------------------------------------
0x2810 - PlayStatus
This register refers to the channel selected by MSLC above.
Also it can refer to either the amplitude or filter envelope, depending on
the AFSEL bit.
bit 15 = Loop end flag (LP)
Set to 1 when the sample loop end is reached.
Cleared to 0 upon reading.
bit 14-13 = Current envelope state (SGC)
0=attack, 1=decay, 2=sustain, 3=release
bit 12-0 = Envelope level (EG)
For amplitude envelope, this is generally in the range of
0x0000-0x03BF. (0x000 means full volume/no attenuation.)
Any higher attenuation level is returned as 0x1FFF.
For filter envelope, you'll get all 13 bits of the current
lowpass value.
(every 0x40 on the envelope attenuation level is 3dB)
-----------------------------------------------------------------------------
0x2814 - PlayPos
bit 15-0 = Current sample position from the requested channel (CA)
-----------------------------------------------------------------------------
0x2880 - ?
has to do with DMA and other obscure stuff
bit 15-9 = DMEA 22:16
bit 8 = unused
bit 7-5 = TSCD 2:0
bit 4 = $T (used for LSI testing?)
bit 3-0 = MRWINH
Setting any of the bits of MRWINH to 1 prohibits sound memory
access from various devices:
bit 3 = main CPU
bit 2 = sound CPU (yes, it will lock up if you set this to 1)
bit 1 = sound samples
bit 0 = effects processor
-----------------------------------------------------------------------------
0x2884 - ?
has to do with DMA and other obscure stuff
bit 15-1 = DMEA 15:1
bit 0 = unused
-----------------------------------------------------------------------------
0x2888 - ?
has to do with DMA and other obscure stuff
bit 15 = GA
bit 14-1 = DRGA 14:1
bit 0 = unused
-----------------------------------------------------------------------------
0x288C - ?
has to do with DMA and other obscure stuff
bit 15 = DI
bit 14-1 = DLG 14:1
bit 0 = EX
-----------------------------------------------------------------------------
0x2890 - TimerAControl
bit 15-11 = unused
bit 10-8 = Timer A prescale (TACTL)
0 = Timer increments every sample
1 = Timer increments every 2 samples
2 = Timer increments every 4 samples
3 = Timer increments every 8 samples
4 = Timer increments every 16 samples
5 = Timer increments every 32 samples
6 = Timer increments every 64 samples
7 = Timer increments every 128 samples
bit 7-0 = Timer A value (TIMA)
Can be written directly, maybe also read, not sure.
Counts up at the rate specified by TACTL.
When it overflows from 0xFF->0x00, an interrupt occurs.
-----------------------------------------------------------------------------
0x2894 - TimerBControl
bit 15-11 = unused
bit 10-8 = Timer B prescale (TBCTL), similar to TACTL
bit 7-0 = Timer B value (TIMB), similar to TIMA
-----------------------------------------------------------------------------
0x2898 - TimerCControl
bit 15-11 = unused
bit 10-8 = Timer C prescale (TCCTL), similar to TACTL
bit 7-0 = Timer C value (TIMC), similar to TIMA
-----------------------------------------------------------------------------
0x289C - Sound CPU Interrupt Enable (SCIEB)
0x28A0 - Sound CPU Interrupt Pending (SCIPD)
0x28A4 - Sound CPU Interrupt Reset (SCIRE)
The following bits apply to all 3 registers:
bit 15-11 = unused
bit 10 = One-sample interval interrupt
bit 9 = MIDI output interrupt
bit 8 = Timer C interrupt
bit 7 = Timer B interrupt
bit 6 = Timer A interrupt
bit 5 = CPU interrupt
bit 4 = DMA end interrupt
bit 3 = MIDI input interrupt
bit 2 = reserved
bit 1 = reserved
bit 0 = External interrupt pin (used for SCSI in the devkit)
Writing SCIEB determines which of the above interrupts are enabled.
(1=on, 0=off). Reading may also work, not sure.
Reading SCIPD tells you which interrupts are pending (have been signaled).
(1=on, 0=off)
Writing SCIPD allows you to signal interrupts yourself, but it only works for
bit 5, supposedly. (1=on, 0=off)
Writing SCIRE resets (acknowledges) whichever interrupts are set to 1 in the
value you write. Probably meaning it clears the corresponding bits of SCIPD.
Reading this is unlikely to work.
-----------------------------------------------------------------------------
0x28A8 - SCILV0 (usually initialized to 0x18)
0x28AC - SCILV1 (usually initialized to 0x50)
0x28B0 - SCILV2 (usually initialized to 0x08)
bit 15-8 = unused
bit 7 = refers collectively to bits 7-10 of SCIEB/SCIPD/SCIRE.
bit 6-0 = refers to bits 6-0 of SCIEB/SCIPD/SCIRE.
When an interrupt happens, the corresponding bits in SCILV0-2 are what forms
the INTREQ number. For instance:
bit 7 6 5 4 3 2 1 0
misc. TimerA SCPU DMA MIDI - - Ext.
--------------------------------------------------
SCILV0 0 0 0 1 1 0 0 0 = 0x18
SCILV1 0 1 0 1 0 0 0 0 = 0x50
SCILV2 0 0 0 0 1 0 0 0 = 0x08
| | |
| | +-----> MIDI INTREQ = 5
| +----------> DMA INTREQ = 3
+------------------------> Timer A INTREQ = 2
No, nothing to do with overclocking or burning. ;)
-----------------------------------------------------------------------------
0x28B4 - Main CPU Interrupt Enable (MCIEB)
0x28B8 - Main CPU Interrupt Pending (MCIPD)
0x28BC - Main CPU Interrupt Reset (MCIRE)
Same as SCIEB/SCIPD/SCIRE, but refers to the Main CPU.
The usual application of this is to set bit 5 of MCIEB (enable CPU interrupt)
and then set bit 5 of MCIPD (set pending CPU interrupt). That sends an
interrupt to the SH4 side.
-----------------------------------------------------------------------------
0x2C00: ARMReset
bit 15-1 = unused
bit 0 = Reset ARM CPU
There are actually other bits in this register, but they're inaccessible from
the ARM side, and undefined on the AICA. There's probably no use accessing
this reg on the ARM side anyway.
-----------------------------------------------------------------------------
0x2D00 - INTRequest
bit 15-8 = unused
bit 7-3 = unknown
bit 0-2 = Current interrupt request level (INTREQ)
Whenever there's an interrupt, the INTREQ number (determined by SCILV0-2) is
stored here.
-----------------------------------------------------------------------------
0x2D04 - INTClear
bit 15-9 = unused
bit 8 = RP
bit 7-0 = M7-M0
Writing 0x01 to M7-M0 signals an end-of-interrupt to the AICA.
Sometimes this is done 4 times, perhaps to clear a queue.
-----------------------------------------------------------------------------
0x2E00 - RTCHi
bit 15-0 = RTC bits 31-16
Realtime clock, counts seconds.
-----------------------------------------------------------------------------
0x2E04 - RTCLo
bit 15-0 = RTC bits 15-0
Realtime clock, counts seconds.
-----------------------------------------------------------------------------
DSP REGISTERS
All values used internally in the DSP are linear integers, signed, 2's
complement. By default, external ringbuffer memory is read and written in a
special floating-point format, but all internal calculations are integer.
Every DSP register described here is a 32-bit register, but only the lowest
16 bits are used.
0x3000-0x31FF: Coefficients (COEF), 128 registers, 13 bits each
0x3000: bits 15-3 = COEF(0)
0x3004: bits 15-3 = COEF(1)
...
0x31FC: bits 15-3 = COEF(127)
You could interpret these as 16-bit signed (2's complement)
coefficients with the lowest 3 bits are always 0.
Each of the 128 COEFs is used by the corresponding instruction
(MPRO).
0x3200-0x32FF: External memory addresses (MADRS), 64 registers, 16 bits each
0x3200: bits 15-0 = MADRS(0)
...
0x3204: bits 15-0 = MADRS(1)
0x32FC: bits 15-0 = MADRS(63)
These are memory offsets that refer to locations in the
external ringbuffer. Every increment of a MADRS register
represents 2 bytes.
0x3400-0x3BFF: DSP program (MPRO), 128 registers, 64 bits each
0x3400: bits 15-0 = bits 63-48 of first instruction
0x3404: bits 15-0 = bits 47-32 of first instruction
0x3408: bits 15-0 = bits 31-16 of first instruction
0x340C: bits 15-0 = bits 15-0 of first instruction
0x3410: bits 15-0 = bits 63-48 of second instruction
...
0x3BFC: bits 15-0 = bits 15-0 of last instruction
0x4000-0x43FF: Temp buffer (TEMP), 128 registers, 24 bits each
0x4000: bits 7-0 = bits 7-0 of TEMP(0)
0x4004: bits 15-0 = bits 23-8 of TEMP(0)
0x4008: bits 7-0 = bits 7-0 of TEMP(1)
...
0x43FC: bits 15-0 = bits 23-8 of TEMP(127)
The temp buffer is configured as a ring buffer, so pointers
referring to it decrement by 1 each sample.
0x4400-0x44FF: Memory data (MEMS), 32 registers, 24 bits each
0x4400: bits 7-0 = bits 7-0 of MEMS(0)
0x4404: bits 15-0 = bits 23-8 of MEMS(0)
0x4408: bits 7-0 = bits 7-0 of MEMS(1)
...
0x44FC: bits 15-0 = bits 23-8 of MEMS(31)
Used for holding data that was read out of the ringbuffer.
0x4500-0x457F: Mixer input data (MIXS), 16 registers, 20 bits each
0x4500: bits 3-0 = bits 3-0 of MIXS(0)
0x4504: bits 15-0 = bits 19-4 of MIXS(0)
0x4508: bits 3-0 = bits 3-0 of MIXS(1)
...
0x457C: bits 15-0 = bits 19-4 of MIXS(15)
These are the 16 send buses coming from the 64 main channels.
0x4580-0x45BF: Effect output data (EFREG), 16 registers, 16 bits each
0x4580: bits 15-0 = EFREG(0)
0x4584: bits 15-0 = EFREG(1)
...
0x45BC: bits 15-0 = EFREG(15)
These are the 16 sound outputs.
0x45C0-0x45C7: External input data stack (EXTS), 2 registers, 16 bits each
0x45C0: bits 15-0 = EXTS(0)
0x45C4: bits 15-0 = EXTS(1)
These come from CDDA left and right, respectively.
-----------------------------------------------------------------------------
DSP PROGRAM
The DSP contains a 128-step program. All 128 steps are executed in order on
every sample. There's no branching or looping.
The instruction word format (MPRO) is as follows:
bit 63-57 = TRA [6:0]
bit 56 = TWT
bit 55-49 = TWA [6:0]
bit 48 = unused
--------
bit 47 = XSEL
bit 46-45 = YSEL [1:0]
bit 44-39 = IRA [5:0]
bit 38 = IWT
bit 37-33 = IWA [4:0]
bit 32 = unused
--------
bit 31 = TABLE
bit 30 = MWT
bit 29 = MRD
bit 28 = EWT
bit 27-24 = EWA [3:0]
bit 23 = ADRL
bit 22 = FRCL
bit 21-20 = SHFT [1:0]
bit 19 = YRL
bit 18 = NEGB
bit 17 = ZERO
bit 16 = BSEL
--------
bit 15 = NOFL
bit 14-9 = MASA [5:0]
bit 8 = ADREB
bit 7 = NXADR
bit 6-0 = unused
Here's what happens on each step. In the following description, I will be
referring to these internal registers:
MDEC_CT.... 16-bit unsigned register which is decremented on every sample
INPUTS..... 24-bit signed input value
B.......... 26-bit signed addend
X.......... 24-bit signed multiplicand
Y.......... 13-bit signed multiplier
ACC........ 26-bit signed accumulator
SHIFTED.... 24-bit signed shifted output value
Y_REG...... 24-bit signed latch register
FRC_REG.... 13-bit fractional address
ADRS_REG... 12-bit whole address
In the course of one step, all of the following occur in order:
(Beginning of step)
- Input read
A 24-bit value (INPUTS) is read from either MEMS, MIXS, or EXTS, depending
on the value of IRA:
IRA 0x00-0x1F: one of the MEMS registers (0x00-0x1F)
IRA 0x20-0x2F: one of the MIXS registers (0x0-0xF)
IRA 0x30-0x31: one of the EXTS registers (0 or 1)
other values: undefined
If the source register is less than 24 bits, it's promoted to 24-bit by
shifting left.
- Input write
If IWT is set, then the memory data from a MRD (either 2 or 3 instructions
ago) is copied into the MEMS register indicated by IWA (0x00-0x1F).
If NOFL was set 2 instructions ago (only), the value is simply promoted
from 16 to 24-bit by shifting left. Otherwise, it's converted from 16-bit
float format to 24-bit integer. (See float notes)
- B selection
A 26-bit value (B) is read from one of two sources:
If BSEL=0: The TEMP register indicated by ((TRA + MDEC_CT) & 0x7F).
This value is sign-extended from 24 to 26 bits, not shifted.
If BSEL=1: The accumulator (ACC), already 26 bits.
If NEGB=1, this value is then made negative. (B becomes 0-B)
If ZERO=1, this value becomes zero, regardless of all other bits.
- X selection
A 24-bit value (X) is read from one of two sources:
If XSEL=0: One of the TEMP registers indicated by ((TRA + MDEC_CT) & 0x7F).
If XSEL=1: The INPUTS register.
- Y selection
A 13-bit value (Y) is read from one of four sources:
If YSEL=0: Y becomes FRC_REG
If YSEL=1: Y becomes this instruction's COEF
If YSEL=2: Y becomes bits 23-11 of Y_REG
If YSEL=3: Y becomes bits 15-4 of Y_REG, ZERO-EXTENDED to 13 bits.
- Y latch
If YRL is set, Y_REG becomes INPUTS.
- Shift of previous accumulator
A 24-bit value (SHIFTED) is set to one of the following:
If SHFT=0: SHIFTED becomes ACC, with saturation
If SHFT=1: SHIFTED becomes ACC*2, with saturation
If SHFT=2: SHIFTED becomes ACC*2, with the highest bits simply cut off
If SHFT=3: SHIFTED becomes ACC, with the highest bits simply cut off
If saturation is enabled, SHIFTED is clipped to the range
-0x800000...0x7FFFFF.
- Multiply and accumulate
A 26-bit value (ACC) becomes ((X * Y) >> 12) + B.
The multiplication is signed. I don't think the addition includes
saturation.
- Temp write
If TWT is set, the value SHIFTED is written to the temp buffer address
indicated by ((TWA + MDEC_CT) & 0x7F).
- Fractional address latch
If FRCL is set, FRC_REG (13-bit) becomes one of the following:
If SHFT=3: FRC_REG = lowest 12 bits of SHIFTED, ZERO-EXTENDED to 13 bits.
Other values of SHFT: FRC_REG = bits 23-11 of SHIFTED.
- Memory operations
If either MRD or MWT are set, we are performing a memory operation (on the
external ringbuffer) and we'll need to compute an address.
Start with the 16-bit value of the MADRS register indicated by MASA
(0x00-0x3F).
If TABLE=0, add the 16-bit value MDEC_CT.
If ADREB=1, add the 12-bit value ADRS_REG, zero-extended.
If NXADR=1, add 1.
If TABLE=0, mod the address so it's within the proper ringbuffer size.
For a 8Kword ringbuffer: AND by 0x1FFF
For a 16Kword ringbuffer: AND by 0x3FFF
For a 32Kword ringbuffer: AND by 0x7FFF
For a 64Kword ringbuffer: AND by 0xFFFF
If TABLE=1, simply AND the address by 0xFFFF.
Shift the address left by 1 (so it's referring to a word offset).
Add (RBP<<11).
This is the address, in main memory, you'll be reading or writing.
If MRD is set, read the 16-bit word at the calculated address and put it
in a temporary place. It will then be accessible by the instruction either
2 or 3 steps ahead. That instruction will have to use a IWT to get the
result. Don't perform any conversions yet; let the IWT handle it later on.
If MWT is set, write the value of SHIFTED into memory at the calculated
address. If NOFL=1, simply shift it right by 8 to make it 16-bit.
Otherwise, convert from 24-bit integer to 16-bit float (see float notes).
- Address latch
If ADRL is set, ADRS_REG (12-bit) becomes one of the following:
If SHFT=3: ADRS_REG = INPUTS >> 16 (signed shift with sign extension).
Other values of SHFT: ADRS_REG = bits 23-12 of SHIFTED.
- Effect output write
If EWT is set, write (SHIFTED >> 8) into the EFREG register specified by
EWA (0x0-0xF).
(End of step)
Supposedly, external memory reads and writes (MRD/MWT) are only allowed on
odd steps (prohibited on step 0, allowed on step 1, etc.), but I found that
MWT seems to work on any step. I'm just not sure if it's guaranteed to write
anything meaningful. I doubt it would hurt to allow MRD/MWT on every step in
an emulator.
-----------------------------------------------------------------------------
DSP FLOATING-POINT FORMAT
When reading/writing external memory, the default (unless NOFL is specified)
is to use a 16-bit floating-point format, as follows:
bit 15 = sign
bit 14-11 = exponent
bit 10-0 = mantissa
To convert from 16-bit float to 24-bit integer (on read):
- Take the mantissa and shift it left by 11
- Make bit 23 be the sign bit
- Make bit 22 be the reverse of the sign bit
- Shift right (signed) by the exponent
To convert from 24-bit integer to 16-bit float (on write):
- While the top 2 bits are the same, shift left
The number of times you have to shift becomes the exponent
- Shift right (signed) by 11
- Set bits 14-11 to the exponent value
-----------------------------------------------------------------------------
TODO:
- Obsess over the lowpass f and q coefficients some more
-----------------------------------------------------------------------------