----------------------------------------------------------------------------- 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 -----------------------------------------------------------------------------