SVP Reference Guide (2008-02-06)
From Sega Retro
This is a copy of an "unofficial" document containing original research, for use as a source on Sega Retro. This page likely exists for historical purposes - the contents should ideally be copy-edited and wikified to make better use of Sega Retro's software. Original source: https://web.archive.org/web/20090402221733/www.sharemation.com/TascoDLX/SVP%20Reference%20Guide%202008.02.06.txt |
=================== SVP Reference Guide (annotated) by Tasco Deluxe < tasco.deluxe @ gmail.com > Final Update: 2008.02.06 -- fully revised, many corrections [Previous update: 2007.02.11 -- released to the public] [Previous update: 2007.01.10 (unpublished) -- revised and corrected] [Previous update: 2006.04.18 (unpublished) -- revised] [Previous update: 2005.07.18 (unpublished) -- added annotation] [First edition: 2004.03.18 (unpublished)] ============================================ Copyright (c) 2004 - 2008, Tasco Deluxe. Some rights reserved. This work is licensed under the Creative Commons Attribution License. To view a copy of this license, visit http://creativecommons.org/licenses/by/2.5/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. DO NOT modify or redistribute this document without reading the license. Attribution should be in the form of name (Tasco Deluxe) AND email address (tasco.deluxe @ gmail.com). *** Disclaimer*** All information herein was obtained by reverse engineering code from the US version of Virtua Racing for the Sega Genesis system. Some information may be incorrect and/or incomplete. Use at your own risk! ### Preface ### This documentation is based on software analysis. No hardware tests have been performed as of yet. SVP code in the US version and EUROPE version of Virtua Racing is identical. However, an alternate EUROPE version exists with slightly modified SVP code. SVP code in the JAPAN version has not been seen. * The changes in the alternate version's SVP code are very slight. A function call is added to SVP commands 0006 and 0007. The function allows the processing of parameters written by the M68000 related to the rendering of 2D bitmaps. This functionality hasn't been examined very closely. ### Info ### Chip: Sega Virtua Processor (SVP) Part: Sega 315-5750 Type: DSP - custom reportedly based on Samsung SSP16xx core (!precise core model is unknown!) Clock: Unknown (!reported to be 23MHz, but unconfirmed!) (!clock of 23MHz can be derived from dividing the M68000's clock [VCLK] by 3!) The SVP includes an arithmetic-logic unit (ALU) and a 16x16->32 multiplier. The exact architecture of the SVP is currently unconfirmed. ### SVP Memory ### NOTES: = Preliminary! Additional memory may be accessible. * 1 Word equals 16 bits (2 bytes) Internal -------- RAM Bank A (RAM0) 256 Words RAM Bank B (RAM1) 256 Words Instruction RAM (IRAM) 1 KWord (!may also be known as Program Memory [PRAM]!) External -------- ROM 64 KWord for code and data / up to 1 MWord for data (programmable access) Data RAM (DRAM) 64 KWord (!more may be technically possible, but VR uses 64 KWord!) ### SVP Registers ### NOTES: = Preliminary! Actual register capabilities may differ. Additional capabilities may exist. = Explanation of registers can be found in the SVP Register Guide. = Internal size of Accumulator register may be larger than stated. * Unless stated otherwise, registers are 16-bit Primary Registers ----------------- r_0 Null Register (!a.k.a. REG0!) r_1 Multiplier Input X r_2 Multiplier Input Y r_3 Accumulator (High) r_4 Status Register (!a.k.a. ST!) r_5 Stack Register (!in VR, used solely for function calls [return addresses]!) r_6 Program Counter (!a.k.a. PC!) r_7 Product Register (!a.k.a. P!) [read-only, 32 bits] r_8 Programmable Memory Access Register 0 // External Status [r] / External Control [w] r_9 Programmable Memory Access Register 1 // ??? r_a Programmable Memory Access Register 2 // ??? r_b Programmable Memory Access Register 3 // External Command Register [r/w] r_c Programmable Memory Access Register 4 r_d ??? (!Not used in VR!) r_e Programmable Memory Access Control Register r_f Accumulator Low - Extension Register (!also used in connection with r_e!) acc Accumulator Register [alias, 32 bits, a concatenation of r_3 and r_f] Pointer Registers ----------------- p_A0 Pointer Register 0, RAM bank A [8-bit] p_A1 Pointer Register 1, RAM bank A [8-bit] p_A2 Pointer Register 2, RAM bank A [8-bit] p_B0 Pointer Register 0, RAM bank B [8-bit] p_B1 Pointer Register 1, RAM bank B [8-bit] p_B2 Pointer Register 2, RAM bank B [8-bit] dp_A0 Data Pointer Register 0, RAM bank A dp_A1 Data Pointer Register 1, RAM bank A dp_A2 Data Pointer Register 2, RAM bank A dp_A3 Data Pointer Register 3, RAM bank A dp_B0 Data Pointer Register 0, RAM bank B dp_B1 Data Pointer Register 1, RAM bank B dp_B2 Data Pointer Register 2, RAM bank B dp_B3 Data Pointer Register 3, RAM bank B ### SVP Instructions ### Addressing Modes ---------------- NOTES: = Addressing modes are listed for reference with Instruction Encodings. = Modes marked as ??? are not referenced in VR's SVP code. Some modes are assumed based on pattern. KEY ~~~~~~~~~~~~~~~~~~~~~~ '[ ]' RAM accessed '( )' ROM accessed '??++' Post-increment '??--' Post-decrement (modulo-affected -- see Register Guide) '??+!' Post-increment (modulo-affected -- see Register Guide) ~~~~~~~~~~~~~~~~~~~~~~ ptr_A? ====== 0 = [p_A0] 1 = [p_A1] 2 = [p_A2] 3 = dp_A0 4 = [p_A0++] 5 = [p_A1++] 6 = [p_A2++] 7 = dp_A1 8 = [p_A0--] 9 = [p_A1--] a = [p_A2--] b = dp_A2 c = [p_A0+!] d = [p_A1+!] e = [p_A2+!] f = dp_A3 ptr_B? ====== 0 = [p_B0] 1 = [p_B1] 2 = [p_B2] 3 = dp_B0 4 = [p_B0++] 5 = [p_B1++] 6 = [p_B2++] 7 = dp_B1 8 = [p_B0--] 9 = [p_B1--] a = [p_B2--] b = dp_B2 c = [p_B0+!] d = [p_B1+!] e = [p_B2+!] f = dp_B3 *ptr_A? ======= 0 = ([p_A0]++) 1 = ([p_A1]++) 2 = ([p_A2]++) 3 = (dp_A0++) 4 = ??? 5 = ??? 6 = ??? 7 = (dp_A1++) 8 = ??? 9 = ??? a = ??? b = (dp_A2++) c = ??? d = ??? e = ??? f = (dp_A3++) *ptr_B? ======= 0 = ([p_B0]++) 1 = ([p_B1]++) 2 = ([p_B2]++) 3 = (dp_B0++) 4 = ??? 5 = ??? 6 = ??? 7 = (dp_B1++) 8 = ??? 9 = ??? a = ??? b = (dp_B2++) c = ??? d = ??? e = ??? f = (dp_B3++) Condition Codes --------------- NOTES: = Additional condition codes (such as overflow [OV]) may exist but are not referenced by VR's SVP code. z result is zero nz result is not zero s result is signed [negative] ns result is not signed [positive or zero] Flags are set based on the result of an instruction. LD instructions do not affect flags. Instruction Set --------------- NOTES: = Unused instructions are not described here. Consider this list incomplete. = The instruction mnemonics listed are reportedly the same as those used in the SSP1610 manual. SYNTAX: instruction destination, source Operand descriptions: reg primary register r_0 thru r_f [some registers may be invalid for certain instructions] ptr pointer register p_?? [see Addressing Modes] (ptr) pointer reference ptr_?? [see Addressing Modes] ((ptr)) pointer double-reference *ptr_?? [see Addressing Modes] imm immediate word 16-bit data [immediately follows the instruction word] short imm short immediate word 8-bit data, zero-extended to 16 bits where appropriate [encoded in instruction word] RAM indexed RAM word 16-bit RAM word, referenced by 8-bit index [encoded in instruction word] r_3 accumulator high register r_3 register, implied [generally for arithmetic/logic instructions] acc accumulator register r_f:r_3 registers, implied [generally for multiply instructions] (r_3) r_3 indirect 16-bit ROM word, referenced by 16-bit index in r_3 Instruction List: ld Load data - ld reg, reg - ld reg, (ptr) - ld (ptr), reg - ld r_3, RAM - ld RAM, r_3 - ld reg, imm - ld (ptr), imm - ld reg, ((ptr)) - ld reg, ptr - ld ptr, reg - ld ptr, short imm - ld reg, (r_3) special cases: - ld acc, r_7 (encoded as ld r_3, r_7 -- value in r_7 is shifted left once before load) - nop (encoded as ld r_0, r_0 -- no operation) add Add - add r_3, reg - add r_3, (ptr) - add r_3, RAM - add r_3, imm - add r_3, ((ptr)) - add r_3, short imm special case: - add acc, r_7 (encoded as add r_3, r_7 -- value in r_7 is shifted left once before add) sub Subtract - sub r_3, reg - sub r_3, (ptr) - sub r_3, RAM - sub r_3, imm - sub r_3, ((ptr)) - sub r_3, short imm and Logical AND - and r_3, reg - and r_3, (ptr) - and r_3, RAM - and r_3, imm - and r_3, short imm * NOTE: and r_3, short 0x00 is used often in VR's SVP code and may be used to clear acc. * There is a little discrepancy about the use of . and r_3, r_3 . versus . and r_3, r_0 . Both instruction set the flags based on r_3. The former instruction is used once in VR's SVP code but its doubtful that it has a different effect. or Logical OR - or r_3, reg - or r_3, RAM - or r_3, imm - or r_3, short imm eor Logical Exclusive OR - eor r_3, reg - eor r_3, (ptr) - eor r_3, imm - eor r_3, ((ptr)) cmp Compare - cmp r_3, (ptr) - cmp r_3, RAM - cmp r_3, imm - cmp r_3, short imm mld Load multiplier - mld acc, (ptr), (ptr) * set acc to zero * load X and Y registers (r_1 and r_2) with referenced values mpya Multiply and Accumulate - mpya acc, (ptr), (ptr) * add value in product register (r_7) to acc * load X and Y registers (r_1 and r_2) with referenced values NOTE: The value added to acc is the value previously in the product register. mpys Multiply and Subtract - mpys acc, (ptr), (ptr) * subtract value in product register (r_7) from acc * load X and Y registers (r_1 and r_2) with referenced values NOTE: The value subtracted from acc is the value previously in the product register. bra Branch to absolute address - bra imm - bra z, imm [conditional] - bra nz, imm [conditional] - bra s, imm [conditional] - bra ns, imm [conditional] call Call subroutine (absolute address) - call imm - call z, imm [conditional] - call nz, imm [conditional] - call s, imm [conditional] - call ns, imm [conditional] shr Logical shift right - shr acc shl Logical shift left - shl acc neg Negate (2's complement) - neg acc - neg nz, acc [conditional] abs Absolute value - abs acc setie Set Interrupt Enable flag - setie Instruction Encodings --------------------- In general, the encoding format (16 bits) is: 3 bits indicate the instruction type 4 bits indicate the instruction variant 1 bit indicates the RAM bank 8 bits indicate operands or variable data * Some instructions are followed by 16 bits of immediate data, nnnn. Operand/variable data is listed as xy. Depending on the instruction, x and y can either be interpreted as separate 4-bit values (referring to registers and/or addressing modes), or a single 8-bit value (as an index or variable data). If either x or y do not appear in the listing, it is considered unused and is probably ignored (commonly, the value is zero). NOTES: = All instructions described below are contained in VR's SVP code. = Instructions listed as ??? without any notation are NOT referenced by VR's SVP code. = In any case where a listed instruction is questionable, a note will follow. Instruction Encoding List: 00xy ld r_x, r_y 01xy ??? 02xy ld r_x, ptr_Ay 03xy ld r_x, ptr_By 04xy ld ptr_Ay, r_x 05xy ld ptr_By, r_x 06xy ld r_3, A[xy] 07xy ld r_3, B[xy] 08xy nnnn ld r_x, nnnn 09xy ??? 0axy ld r_x, *ptr_Ay 0bxy ld r_x, *ptr_By 0cxy nnnn ld ptr_Ay, nnnn 0dxy nnnn ld ptr_By, nnnn 0exy ld A[xy], r_3 0fxy ld B[xy], r_3 10xy ??? 11xy ??? 12xy ld r_x, p_Ay 13xy ld r_x, p_By 14xy ld p_Ay, r_x 15xy ld p_By, r_x 16xy ??? 17xy ??? 18xy ld p_A0, xy 19xy ld p_A1, xy 1axy ld p_A2, xy 1bxy ??? 1cxy ld p_B0, xy 1dxy ld p_B1, xy 1exy ld p_B2, xy 1fxy ??? 20xy sub r_3, r_y 21xy ??? 22xy sub r_3, ptr_Ay 23xy sub r_3, ptr_By 24xy ??? 25xy ??? 26xy sub r_3, A[xy] 27xy sub r_3, B[xy] 28xy nnnn sub r_3, nnnn 29xy ??? 2axy sub r_3, *ptr_Ay 2bxy sub r_3, *ptr_By 2cxy ??? 2dxy ??? 2exy ??? 2fxy ??? 30xy ??? 31xy ??? 32xy ??? 33xy ??? 34xy ??? 35xy ??? 36xy ??? 37xy mpys ptr_Ay, ptr_Bx 38xy sub r_3, xy 39xy ??? 3axy ??? 3bxy ??? 3cxy ??? 3dxy ??? 3exy ??? 3fxy ??? 40xy ??? 41xy ??? 42xy ??? 43xy ??? 44xy ??? 45xy ??? 46xy ??? 47xy ??? 48xy nnnn ... x=0 call nnnn x=5 call nz, nnnn x=7 call ns, nnnn 49xy nnnn ... x=5 call z, nnnn x=7 call s, nnnn 4axy ld r_x, (r_3) 4bxy ??? 4cxy nnnn ... x=0 bra nnnn x=5 bra nz, nnnn x=7 bra ns, nnnn 4dxy nnnn ... x=5 bra z, nnnn x=7 bra s, nnnn 4exy ??? 4fxy ??? 50xy ??? 51xy ??? 52xy ??? 53xy ??? 54xy ??? 55xy ??? 56xy ??? 57xy ??? 58xy ??? 59xy ??? 5axy ??? 5bxy ??? 5cxy ??? 5dxy ??? 5exy ??? 5fxy ??? 60xy cmp r_3, r_y 61xy ??? 62xy cmp r_3, ptr_Ay 63xy cmp r_3, ptr_By 64xy ??? 65xy ??? 66xy cmp r_3, A[xy] 67xy cmp r_3, B[xy] 68xy nnnn cmp r_3, nnnn 69xy ??? 6axy ??? 6bxy ??? 6cxy ??? 6dxy ??? 6exy ??? 6fxy ??? 70xy ??? 71xy ??? 72xy ??? 73xy ??? 74xy ??? 75xy ??? 76xy ??? 77xy ??? 78xy cmp r_3, xy 79xy ??? 7axy ??? 7bxy ??? 7cxy ??? 7dxy ??? 7exy ??? 7fxy ??? 80xy add r_3, r_y 81xy ??? 82xy add r_3, ptr_Ay 83xy add r_3, ptr_By 84xy ??? 85xy ??? 86xy add r_3, A[xy] 87xy add r_3, B[xy] 88xy nnnn add r_3, nnnn 89xy ??? 8axy add r_3, *ptr_Ay 8bxy add r_3, *ptr_By 8cxy ??? 8dxy ??? 8exy ??? 8fxy ??? 90xy ... xy=02 shr acc xy=03 shl acc xy=06 neg acc xy=07 abs acc xy=56 neg nz, acc (!not 100% on the condition, but probable!) 91xy ??? 92xy ??? 93xy ??? 94xy ... xy=05 setie 95xy ??? 96xy ??? 97xy mpya acc, ptr_Ay, ptr_Bx 98xy add r_3, xy 99xy ??? 9axy ??? 9bxy ??? 9cxy ??? 9dxy ??? 9exy ??? 9fxy ??? a0xy and r_3, r_y a1xy ??? a2xy and r_3, ptr_Ay a3xy and r_3, ptr_By a4xy ??? a5xy ??? a6xy and r_3, A[xy] a7xy and r_3, B[xy] a8xy nnnn and r_3, nnnn a9xy ??? aaxy ??? abxy ??? acxy ??? adxy ??? aexy ??? afxy ??? b0xy ??? b1xy ??? b2xy ??? b3xy ??? b4xy ??? b5xy ??? b6xy ??? b7xy mld acc, ptr_Ay, ptr_Bx b8xy and r_3, xy b9xy ??? baxy ??? bbxy ??? bcxy ??? bdxy ??? bexy ??? bfxy ??? c0xy or r_3, r_y c1xy ??? c2xy ??? c3xy ??? c4xy ??? c5xy ??? c6xy or r_3, A[xy] c7xy or r_3, B[xy] c8xy nnnn or r_3, nnnn c9xy ??? caxy ??? cbxy ??? ccxy ??? cdxy ??? cexy ??? cfxy ??? d0xy ??? d1xy ??? d2xy ??? d3xy or r_3, p_By d4xy ??? d5xy ??? d6xy ??? d7xy ??? d8xy or r_3, xy d9xy ??? daxy ??? dbxy ??? dcxy ??? ddxy ??? dexy ??? dfxy ??? e0xy eor r_3, r_y e1xy ??? e2xy eor r_3, ptr_Ay e3xy eor r_3, ptr_By e4xy ??? e5xy ??? e6xy ??? e7xy ??? e8xy nnnn eor r_3, nnnn e9xy ??? eaxy eor r_3, *ptr_Ay ebxy eor r_3, *ptr_By ecxy ??? edxy ??? eexy ??? efxy ??? f0xy ??? f1xy ??? f2xy ??? f3xy ??? f4xy ??? f5xy ??? f6xy ??? f7xy ??? f8xy ??? f9xy ??? faxy ??? fbxy ??? fcxy ??? fdxy ??? fexy ??? ffxy ??? Instruction Timings ------------------- The timings of SVP instructions are unconfirmed, but the DSP, generally, should be able to execute one instruction per clock cycle. Memory timing may be significant but it has not been evaluated.