====== Documentation ====== * Patent: {{:documentation:patents:wo09416383a1_-_digital_signal_processor_architecture.pdf|wo09416383a1_-_digital_signal_processor_architecture.pdf}} * Dev Docs * [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/mgsfldr/mpgfldr/00mpg1.html#XREF15413|3DO Music and Audio Programmer's Guide]] * [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/mgsfldr/mpgfldr/02mpg.html#XREF40168|Understanding 3DO Audio]] * [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/mgsfldr/mpgfldr/02mpg001.html#XREF34622|What is 3DO Audio?]] * [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/mgsfldr/mpgfldr/02mpg002.html#XREF36740|Audio Hardware]] * [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/mgsfldr/mpgfldr/02mpg003.html#XREF14437|Audio Software]] * [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/mgsfldr/mpgfldr/10mpg.html#XREF10374|Tips and Techniques]] * [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/mgsfldr/mpgfldr/10mpg001.html#XREF33503|DSP Resources]] * [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/mgsfldr/mpgfldr/10mpg007.html#XREF42401|Timing]] * [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/mgsfldr/mpgfldr/10mpg008.html#XREF16832|Troubleshooting]] * [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/mgsfldr/mprfldr/00mpr1.html#XREF25646|3DO Music and Audio Programmer's Reference]] * [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/mgsfldr/mprfldr/01mpr.html#XREF16932|Audio Folio Calls]] * [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/mgsfldr/mprfldr/02mpr.html#XREF20449|Music Library Calls]] * [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/ppgfldr/mgsfldr/mprfldr/03mpr.html#XREF41103|Instrument Templates]] * [[:documentation:file_formats:sdk:dsp|DSP File Format]] ====== General Details ====== * 16bit words * 20bit ALU * 20bit accumulator * 512 words of "N" memory (iNstruction memory) * 256 words of "I" memory (Internal memory) * 128 words of "EI" memory (external input memory) * 16 words of "EO" memory (external output memory) * 13 DMA input channels (from DRAM), buffered by 8 sample deep FIFO * 4 DMA output channels (to DRAM) * 2 modes: one for audio processing (//cyclic//) and one for general purpose processing (//free-running//) ====== Status Flags ====== ^Flag^Name^Description| |N|negative|Set if the ALU resuilt is negative (the high bit is set).| |V|overflow|After an ALU 'add', set if and only if the signs of the inputs are identical and th esign of the result is different from the signs of the inputs. After an ALU 'subtract', set if and only if the signs of the inputs are opposite and the sign of the result is the same as the sign of the subtrahend.| |C|carry|Set if the carry result from the ALU is set.| |Z|zero|Set if the high-order 16 bits of the ALU result are zero.| |X|exact|Set if the low-order four bits of the ALU result are zero.| ====== Instructions ====== From page 27 of the {{:documentation:patents:wo09416383a1_-_digital_signal_processor_architecture.pdf|patent:}} Instruction words can either be arithmetic or control instructions. if bit 15 is 0, then the instruction is an arithmetic instruction, and if bit 15 is 1, the instruction is a control instruction. ===== Formats ===== Found in Figure 7 on page 95 of patent {{:documentation:patents:wo09416383a1_-_digital_signal_processor_architecture.pdf|WO09416383A1}}. Descriptions of fields are in the specific sections found below. ==== Control Instruction Format ==== ^15^14:13^12^11:10^9:0| |1|MODE|FLG_SEL|FLAG_MASK|BCH_ADDRESS| ==== Arithmetic Instruction Format ==== ^15^14:13^12^11:10^9:8^7:4^3:0| |0|NUM_OPS|M2_SEL|ALU_MUX_A|ALU_MUX_B|ALU|BS| ==== Immediate Operand Format ==== ^15^14^13^12:0^^^^| |1|1|JST-FY|IMMEDIATE_VAL||||| ==== Non-Registered Operand Format ==== ^15^14^13^12^11^10^9:0| |1|0|0|X|WB1|D_I|OP_ADDRESS (DIRECT OR INDIRECT)| ==== Registered 1 or 2 Operand Format ==== ^15^14^13^12^11^10^9^8:5^4^3:0| |1|0|1|WB2|WB1|NUM_RGS|R2_D_I|R2|R1_D_I|R1| ==== Registered 3 Operand Format ==== ^15^14^13:10^9^8:5^4^3:0| |0|R3_D_I|R3|R2_D_I|R2|R1_D_I|R1| ===== Control Instructions ===== ==== Conditional Branch ==== Inputs for conditional branch are the status flags, mode bits, flag select, and flag mask. The patent includes pseudo code for determining if a branch is to be taken. A_C refers to bit 15 of the instruction. Md0 = (!MODE1 && !MODE0); Md1 = (!MODE1 && MODE0); Md2 = ( MODE1 && !MODE0); Md3 = ( MODE1 && MODE.0); Stat0 = ((FLAG_SELECT && C) || (!FLAG_SELECT && N)); Stat1 = ((FLAG_SELECT && Z) || (!FLAG_SELECT && V)); New_Stat0 = (Stat0 != Md2); New_Stat1 = (Stat1 != Md2); tmp_dcare0 = (!FLAG_MASK0 || (FLAG_MASK0 && New_Stat1)); tmp_dcare1 = (!FLAG_MASK1 || (FLAG_MASK1 && New_Stat0)); Really_Dcare = (!FLAG_MASK1 && !FLAG_MASK0); Md12_Success = (tmp_dcare1 && tmp_dcare0 && (MODE1 != MODE0) && !Really_Dcare); Super_Duper0 = (A_C && Md1 && !FLAG_SELECT && Really_Dcare); Super_Duper1 = (A_C && Md1 && FLAG_SELECT && Really_Dcare); All_Zero = (Super_Duper0 && Z && X); Not_All_Zero = (Super_Duper1 && !(Z && X)); Sd_Success = (All_Zero || Not_All_Zero); Nvtest = ((((N != V) || (Z && FLAG_MASK0)) != FLAG_MASK1) && !FLAG_SELECT); Tmp_Cz = (C && !Z); Cztest = ((Tmp_Cz != FLAG_MASK0) && FLAG_SELECT && FLAG_MASK1); Xactest = ((X != FLAG_MASK0) && FLAG_SELECT && FLAG_MASK1); Md3_Success = ((Nvtest || Cztest || Xactest) && Md3); Branch = ((Md12_Success || Md3_Success || Sd_Success) && A_C); ^Condition^Logic^15^14^13^12^11^10^9:0^^^^^^^^^| ^ ^ ^1^M1^M0^S^FM1^FM0^BCH_ADDRESS^^^^^^^^^| |all zero|X and Z|1|0|1|0|0|0| |||||||||| |overflow|V|1|0|1|0|0|1| |||||||||| |negative|N|1|0|1|0|1|0| |||||||||| |negative and overflow|N and V|1|0|1|0|1|1| |||||||||| |not all zero|!X or !Z|1|0|1|1|0|0| |||||||||| |equal to zero|Z|1|0|1|1|0|1| |||||||||| |carry|C|1|0|1|1|1|0| |||||||||| |carry and zero|C and Z|1|0|1|1|1|1| |||||||||| | | | | | | | | | |||||||||| |high (unsigned)|!X and !Z|1|1|0|0|0|0| |||||||||| |not overflow|!V|1|1|0|0|0|1| |||||||||| |positive|!N|1|1|0|0|1|0| |||||||||| |negative and overflow both not set|!N and !V|1|1|0|0|1|1| |||||||||| |low or the same (unsigned)|X or Z|1|1|0|1|0|0| |||||||||| |not equal to zero|!Z|1|1|0|1|0|1| |||||||||| |carry clear|!C|1|1|0|1|1|0| |||||||||| |carry and zero both not set|!C and !Z|1|1|0|1|1|1| |||||||||| | | | | | | | | | |||||||||| |less than (signed)|(N xor V)|1|1|1|0|0|0| |||||||||| |less than or equal (signed)|(N xor V) or Z|1|1|1|0|0|1| |||||||||| |greater than or equal (signed)|!(N xor V) or Z|1|1|1|0|1|0| |||||||||| |greater than (signed)|!(N xor V) and !Z|1|1|1|0|1|1| |||||||||| |unsigned overflow|C and !Z|1|1|1|1|0|0| |||||||||| |not unsigned overflow|!C or Z|1|1|1|1|0|1| |||||||||| |exact|X|1|1|1|1|1|0| |||||||||| |not exact|!X|1|1|1|1|1|1| |||||||||| ==== JUMP ==== Branch always to BCH_ADDRESS ^15^14^13^12^11^10^9^8^7^6^5^4^3^2^1^0| ^A_C^MODE^^FLAG_SEL^FLAG_MASK^^BCH_ADDRESS^^^^^^^^^| |1|0|0|0|0|1|X|X|X|X|X|X|X|X|X|X| ==== JSR ==== Jump to subroutine at BCH_ADDRESS; store current PC in SUBR register. ^15^14^13^12^11^10^9^8^7^6^5^4^3^2^1^0| ^A_C^MODE^^FLAG_SEL^FLAG_MASK^^BCH_ADDRESS^^^^^^^^^| |1|0|0|0|1|0|X|X|X|X|X|X|X|X|X|X| ==== BFM ==== Branch from a branch target stream to a new BCH_ADDRESS. ^15^14^13^12^11^10^9^8^7^6^5^4^3^2^1^0| ^A_C^MODE^^FLAG_SEL^FLAG_MASK^^BCH_ADDRESS^^^^^^^^^| |1|0|0|0|1|1|X|X|X|X|X|X|X|X|X|X| ==== MOVEREG ==== Move the following operand to the specified register, director or indirect. ^15^14^13^12^11^10^9^8^7^6^5^4^3^2^1^0| ^A_C^MODE^^FLAG_SEL^FLAG_MASK^^BCH_ADDRESS^^^^^^^^^| |1|0|0|1|0|0|X|X|X|X|X|X|X|X|X|X| ==== MOVE ==== Move the following operand to the specified address, direct or indirect. ^15^14^13^12^11^10^9^8^7^6^5^4^3^2^1^0| ^A_C^MODE^^FLAG_SEL^FLAG_MASK^^BCH_ADDRESS^^^^^^^^^| |1|0|0|1|1|0|X|X|X|X|X|X|X|X|X|X| or ^15^14^13^12^11^10^9^8^7^6^5^4^3^2^1^0| ^A_C^MODE^^FLAG_SEL^FLAG_MASK^^BCH_ADDRESS^^^^^^^^^| |1|0|0|1|1|1|X|X|X|X|X|X|X|X|X|X| ==== NOP ==== No operation ^15^14^13^12^11^10^9^8^7^6^5^4^3^2^1^0| ^A_C^MODE^^FLAG_SEL^FLAG_MASK^^SUB_OP^^^-^-^-^-^-^-^-| |1|0|0|0|0|0|0|0|0|-|-|-|-|-|-|-| ==== BAC ==== Branch to address indicated by accumulator ACC (13:4) ^15^14^13^12^11^10^9^8^7^6^5^4^3^2^1^0| ^A_C^MODE^^FLAG_SEL^FLAG_MASK^^SUB_OP^^^-^-^-^-^-^-^-| |1|0|0|0|0|0|0|0|1|-|-|-|-|-|-|-| ==== RBASE ==== Change Register base value that is specified in 5:0 of instruction. ^15^14^13^12^11^10^9^8^7^6^5^4^3^2^1^0| ^A_C^MODE^^FLAG_SEL^FLAG_MASK^^SUB_OP^^^-^RBASE_VAL^^^^^| |1|0|0|0|0|0|0|1|0|-|X|X|X|X|X|X| ==== RMAP ==== Change register mapping latch to that specified in 2:0 of instruction. ^15^14^13^12^11^10^9^8^7^6^5^4^3^2^1^0| ^A_C^MODE^^FLAG_SEL^FLAG_MASK^^SUB_OP^^^-^-^-^-^RMAP_VAL^^| |1|0|0|0|0|0|0|1|1|-|-|-|-|X|X|X| ==== RTS ==== Return from subroutine to main instruction sequence. PC = SUBR. ^15^14^13^12^11^10^9^8^7^6^5^4^3^2^1^0| ^A_C^MODE^^FLAG_SEL^FLAG_MASK^^SUB_OP^^^-^-^-^-^-^-^-| |1|0|0|0|0|0|1|0|0|-|-|-|-|-|-|-| ==== OP_MASK ==== Change operand mask bits to those specified in 4:0 of instruction. ^15^14^13^12^11^10^9^8^7^6^5^4^3^2^1^0| ^A_C^MODE^^FLAG_SEL^FLAG_MASK^^SUB_OP^^^-^-^OPERAND_MASK_VAL^^^^| |1|0|0|0|0|0|1|0|1|-|-|X|X|X|X|X| ==== SLEEP ==== Wait until reset by underflow output of counter or external reset signal. ^15^14^13^12^11^10^9^8^7^6^5^4^3^2^1^0| ^A_C^MODE^^FLAG_SEL^FLAG_MASK^^SUB_OP^^^-^-^-^-^-^-^-| |1|0|0|0|0|0|1|1|1|-|-|-|-|-|-|-| ===== Arithmetic Instructions ===== ==== Format ==== ^15^14:13^12^11:10^9:8^7:4^3:0| |0|NUM_OPS|M2_SEL|ALU_MUX_A|ALU_MUX_B|ALU|BS| ==== NUM_OPS ====
indicate the number of operands which follow the instruction
==== M2_SEL ====
indicates whether an ACC/carry word or one of the operands is to be used for the second input of the multiplier
==== ALU_MUX_A / ALU_MUX_B ====
indicate which selections should be made by the dual multiplexer in providing operands to the ALU; bits 11:10 (ALU_MUX_A) select the source for 'A' input port of the ALU and bits 9:8 (ALU_MUX_B) select the source for the 'B' in put port of the ALU.
==== ALU (ASEL) ==== The ALU function. ^ASEL^Type^Function| |0000|arithmetic|A| |0001|arithmetic|-B| |0010|arithmetic|A + B| |0011|arithmetic|A + carry| |0100|arithmetic|A - B| |0101|arithmetic|A - borrow| |0110|arithmetic|A + 1| |0111|arithmetic|A - 1| |1000|logical|A| |1001|logical|NOT A| |1010|logical|A AND B| |1011|logical|A NAND B| |1100|logical|A OR B| |1101|logical|A NOR B| |1110|logical|A XOR B| |1111|logical|A XNOR B| ==== BS (BSEL) ====
For all BSELs except 1000, the shift type (arithmetic or logical) is determined by bit 7, which is the same as the high order bit of ASEL. Basically, if the ALU function is arithmetic, so will the shift be arithmetic. If the ALU function is logical, so will the shift be logical. If BSEL = 1000, then an operand is loaded which specifies both the shift type and a new BSEL explicitly. If the newly loaded operand is itself 1000, then the barrel shifter performs a 1-bit left rotate of bits 19:4 with bit 19 being rotated into the carry bit. \\ \\ The "clip on overflow" function of the barrel shifter essentially prevents the ALU from exceeding the largest positive or negative number which can be represented in 20 bits. In this function, if the overflow (V) output of ALU is set, the barrel shifter will output the largest positive number if the sign bit from the ALU is negative, or the largest negative number if the sign bit from the ALU is positive. Clip on overflow is useful esspecially in digital filter applications.
^BSEL^Function| |0000|No shift| |0001|Left shift 1| |0010|Left shift 2| |0011|Left shift 3| |0100|Left shift 4| |0101|Left shift 5| |0110|Left shift 8| |0111|Clip on overflow| |1000|Load operand| |1001|Right shift 16| |1010|Right shift 8| |1011|Right shift 5| |1100|Right shift 4| |1101|Right shift 3| |1110|Right shift 2| |1111|Right shift 1| ===== Immediate Operand ===== ^15^14^13^12:0^^^^| |1|1|JST-FY|IMMEDIATE_VAL||||| ==== JST-FY ==== Justify bit (bit 13) indicates whether the 13bit immediate value is to be left or right justified in the 16bit field. If it is to be left justified, then zeros are added to the right, and if it is to be right justified, then the value is sign extended to the left. ==== IMMEDIATE_VAL ==== The value used for the instruction in question. ===== Non-Registered Operand ===== ^15^14^13^12^11^10^9:0| |1|0|0|X|WB1|D_I|OP_ADDRESS (DIRECT OR INDIRECT)| ===== Registered 1 or 2 Operand ===== ^15^14^13^12^11^10^9^8:5^4^3:0| |1|0|1|WB2|WB1|NUM_RGS|R2_D_I|R2|R1_D_I|R1| ===== Registered 3 Operand ===== ^15^14^13:10^9^8:5^4^3:0| |0|R3_D_I|R3|R2_D_I|R2|R1_D_I|R1| ====== Register Mapping ====== ^===Address===^Description| |0x000 - 0x07F|external registers in (EI memory). Read only (by the DSP).| |0x080 - 0x0FF|Mirror of 0x000 - 0x07F.| |0x100 - 0x1FF|internal registers (I memory). Read/write (by the DSP)| |0x200 - 0x2FF|Mirror of 0x100 - 0x1FF.| |0x300 - 0x3FF|external registers out (EO memory). Write only (by the DSP).| |0x000 - 0x06F|CPU coefficient space| |0x0D0 - 0x0DE|EIFIFO status words| |0x0E0 - 0x0E3|EOFIFO status words| |0x0EA|PRNG / pseudo random noise generator (white noise)| |0x0EB|audio output status read (including AUDLOCK, LFTFULL, RGTFULL)| |0x0EC|semaphore status. Can only be read by either the CPU or DSP. **bit 0:** the CPU was the last to write to the semaphore data word. **bit 1:** the DSP was the last to write to the semaphore data word. **bit 2:** the CPU has acknowledge the current data word. **bit 3:** the DSP has acknowledge the current data word. When either the CPU or DSP writes to the semaphore data word the DSP automatically sets the correct status bit and clears all others. When either the CPU or the DSP writes to the semaphore ACK address the appropriate ACK bit in the semaphore status register is set.| |0x0ED|semaphore data word. Can be read or written to by either CPU or DSP.| |0x0EE|PC / program counter| |0x0EF|DSP clock counter value| |0x0F0 - 0x0FE|input FIFOs| |0x070 - 0x07E|read corresponding input FIFO in 0x0F0 - 0x0FE but without removing the input word from the FIFO| |0x300 - 0x30F|"quick-out" latches, readable by external CPU| |0x3EB|write AUDLOCK; MSB sets/clears| |0x3EC|semaphore ACK| |0x3ED|semaphore write| |0x3EE|CPU interrupt register. Any write to this address sends an interrupt to the external CPU; the data written to this address is sent as the interrupt word.| |0x3EF|DSP clock counter reload value. Writes to this address change the DSP clock counter reload value, but do not reset the clock immediately.This changes the basic cycle time of a program running in the DSP. Only direct writes to this address are effective.| |0x3F0 - 0x3F3|Output FIFOs, which may be used for audio reverb or data streams.| |0x3FD|Flush output FIFO. Bits 3:0 flush output FIFOs 3:0 respectively. Forces a DMA request.| |0x3FE - 0x3FF|Left and right audio outputs.|