From c1242fbd6c0be8dc2ea33a6c4fd6992cf121022b Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Mon, 9 Aug 2021 17:08:07 -0700 Subject: [PATCH 01/49] docs/DSP: Update version and history The GFDL requires the history section to be updated. Although there was no actual release, this makes it attribution clearer and separates it from my changes. --- .../GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 4d561d59db..67fcd7ca5e 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -46,7 +46,7 @@ % Document front page material \title{\textbf{\Huge GameCube DSP User's Manual}} \author{Reverse-engineered and documented by Duddie \\ \href{mailto:duddie@walla.com}{duddie@walla.com}} -\date{\today\\v0.0.6} +\date{\today\\v0.0.7} % Title formatting commands \newcommand{\OpcodeTitle}[1]{\subsection{\textbf{\Large #1}}} @@ -239,6 +239,7 @@ The purpose of this documentation is purely academic and it aims at understandin 0.0.4 & 2005.05.12 & Duddie & Added preliminary DSP memory map and opcode syntax. \\ \hline 0.0.5 & 2018.04.09 & Lioncache & Converted document over to LaTeX. \\ \hline 0.0.6 & 2018.04.13 & BhaaL & Updated register tables, fixed opcode operations \\ \hline +0.0.7 & Mid 2020 & Tilka & Fixed typos and register names, and improved readability. \\ \hline \end{tabular} \end{table} From 2df33ddbbcafc4c07be618112009c047752481a5 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Mon, 9 Aug 2021 20:23:21 -0700 Subject: [PATCH 02/49] docs/DSP: Create .gitignore This is from https://github.com/github/gitignore/blob/master/TeX.gitignore (CC0) --- docs/DSP/GameCube_DSP_Users_Manual/.gitignore | 290 ++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 docs/DSP/GameCube_DSP_Users_Manual/.gitignore diff --git a/docs/DSP/GameCube_DSP_Users_Manual/.gitignore b/docs/DSP/GameCube_DSP_Users_Manual/.gitignore new file mode 100644 index 0000000000..3c5955276e --- /dev/null +++ b/docs/DSP/GameCube_DSP_Users_Manual/.gitignore @@ -0,0 +1,290 @@ +GameCube_DSP_Users_Manual.pdf + +## Core latex/pdflatex auxiliary files: +*.aux +*.lof +*.log +*.lot +*.fls +*.out +*.toc +*.fmt +*.fot +*.cb +*.cb2 +.*.lb + +## Intermediate documents: +*.dvi +*.xdv +*-converted-to.* +# these rules might exclude image files for figures etc. +# *.ps +# *.eps +# *.pdf + +## Generated if empty string is given at "Please type another file name for output:" +.pdf + +## Bibliography auxiliary files (bibtex/biblatex/biber): +*.bbl +*.bcf +*.blg +*-blx.aux +*-blx.bib +*.run.xml + +## Build tool auxiliary files: +*.fdb_latexmk +*.synctex +*.synctex(busy) +*.synctex.gz +*.synctex.gz(busy) +*.pdfsync + +## Build tool directories for auxiliary files +# latexrun +latex.out/ + +## Auxiliary and intermediate files from other packages: +# algorithms +*.alg +*.loa + +# achemso +acs-*.bib + +# amsthm +*.thm + +# beamer +*.nav +*.pre +*.snm +*.vrb + +# changes +*.soc + +# comment +*.cut + +# cprotect +*.cpt + +# elsarticle (documentclass of Elsevier journals) +*.spl + +# endnotes +*.ent + +# fixme +*.lox + +# feynmf/feynmp +*.mf +*.mp +*.t[1-9] +*.t[1-9][0-9] +*.tfm + +#(r)(e)ledmac/(r)(e)ledpar +*.end +*.?end +*.[1-9] +*.[1-9][0-9] +*.[1-9][0-9][0-9] +*.[1-9]R +*.[1-9][0-9]R +*.[1-9][0-9][0-9]R +*.eledsec[1-9] +*.eledsec[1-9]R +*.eledsec[1-9][0-9] +*.eledsec[1-9][0-9]R +*.eledsec[1-9][0-9][0-9] +*.eledsec[1-9][0-9][0-9]R + +# glossaries +*.acn +*.acr +*.glg +*.glo +*.gls +*.glsdefs +*.lzo +*.lzs + +# uncomment this for glossaries-extra (will ignore makeindex's style files!) +# *.ist + +# gnuplottex +*-gnuplottex-* + +# gregoriotex +*.gaux +*.glog +*.gtex + +# htlatex +*.4ct +*.4tc +*.idv +*.lg +*.trc +*.xref + +# hyperref +*.brf + +# knitr +*-concordance.tex +# TODO Uncomment the next line if you use knitr and want to ignore its generated tikz files +# *.tikz +*-tikzDictionary + +# listings +*.lol + +# luatexja-ruby +*.ltjruby + +# makeidx +*.idx +*.ilg +*.ind + +# minitoc +*.maf +*.mlf +*.mlt +*.mtc[0-9]* +*.slf[0-9]* +*.slt[0-9]* +*.stc[0-9]* + +# minted +_minted* +*.pyg + +# morewrites +*.mw + +# newpax +*.newpax + +# nomencl +*.nlg +*.nlo +*.nls + +# pax +*.pax + +# pdfpcnotes +*.pdfpc + +# sagetex +*.sagetex.sage +*.sagetex.py +*.sagetex.scmd + +# scrwfile +*.wrt + +# sympy +*.sout +*.sympy +sympy-plots-for-*.tex/ + +# pdfcomment +*.upa +*.upb + +# pythontex +*.pytxcode +pythontex-files-*/ + +# tcolorbox +*.listing + +# thmtools +*.loe + +# TikZ & PGF +*.dpth +*.md5 +*.auxlock + +# todonotes +*.tdo + +# vhistory +*.hst +*.ver + +# easy-todo +*.lod + +# xcolor +*.xcp + +# xmpincl +*.xmpi + +# xindy +*.xdy + +# xypic precompiled matrices and outlines +*.xyc +*.xyd + +# endfloat +*.ttt +*.fff + +# Latexian +TSWLatexianTemp* + +## Editors: +# WinEdt +*.bak +*.sav + +# Texpad +.texpadtmp + +# LyX +*.lyx~ + +# Kile +*.backup + +# gummi +.*.swp + +# KBibTeX +*~[0-9]* + +# TeXnicCenter +*.tps + +# auto folder when using emacs and auctex +./auto/* +*.el + +# expex forward references with \gathertags +*-tags.tex + +# standalone packages +*.sta + +# Makeindex log files +*.lpz + +# xwatermark package +*.xwm + +# REVTeX puts footnotes in the bibliography by default, unless the nofootinbib +# option is specified. Footnotes are the stored in a file with suffix Notes.bib. +# Uncomment the next line to have this generated file ignored. +#*Notes.bib From 35720284f39d502a151b760befd501ec42a59552 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 13 Jul 2021 14:15:26 -0700 Subject: [PATCH 03/49] docs/DSP: Fix various spelling/grammar/punctuation issues --- .../GameCube_DSP_Users_Manual.tex | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 67fcd7ca5e..90390078ff 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -529,7 +529,7 @@ Furthermore, it also contains control bits to configure the flow of certain oper \section{Product register} The product register is a register containing the intermediate product of a multiply or multiply and accumulation operation. -It's result should never be used for calculation although the register can be read or written. +Its result should never be used for calculation although the register can be read or written. It reflects the state of the internal multiply unit. The product is 40 bits with 1 bit of overflow. \begin{lstlisting}[language=C++] @@ -859,7 +859,7 @@ Opcode decoding uses special naming for bits and their decimal representations t \section{Conditional opcodes} Conditional opcodes are executed only when the condition described by their encoded conditional field has been met. -The groups of conditional instructions are, \Opcode{CALL}, \Opcode{JMP}, \Opcode{IF}, and \Opcode{RET}. +The groups of conditional instructions are: \Opcode{CALL}, \Opcode{JMP}, \Opcode{IF}, and \Opcode{RET}. \begin{table}[H] \centering @@ -887,7 +887,7 @@ The groups of conditional instructions are, \Opcode{CALL}, \Opcode{JMP}, \Opcode \textbf{Note:} -There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \texttt{ZR}/\texttt{NZ}. +There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} and \texttt{ZR}/\texttt{NZ}. \texttt{EQ}/\texttt{NE} pair operates on arithmetic zero flag (arithmetic 0) while \texttt{ZR}/\texttt{NZ} pair operates on logic zero flag (logic 0). \pagebreak{} @@ -1910,7 +1910,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \begin{DSPOpcodeDescription} \item Load immediate value \Value{I} to register \Register{\$D}. - Perform and additional operation depending on destination register. + Perform an additional operation depending on destination register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} @@ -1971,7 +1971,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \begin{DSPOpcodeDescription} \item Move value from data memory pointed by addressing register \Register{\$arS} to register \Register{\$D}. Decrements register \Register{\$arS}. - Perform additional operation depending on destination register. + Perform an additional operation depending on destination register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} @@ -1993,7 +1993,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \begin{DSPOpcodeDescription} \item Move value from data memory pointed by addressing register \Register{\$arS} to register \Register{\$D}. Increments register \Register{\$arS}. - Perform additional operation depending on destination register. + Perform an additional operation depending on destination register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} @@ -2015,7 +2015,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \begin{DSPOpcodeDescription} \item Move value from data memory pointed by addressing register \Register{\$arS} to register \Register{\$D}. Add indexing register \Register{\$ixS} to register \Register{\$arS}. - Perform additional operation depending on destination register. + Perform an additional operation depending on destination register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} @@ -2036,7 +2036,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \begin{DSPOpcodeDescription} \item Move value from data memory pointed by address \Address{M} (8-bit sign-extended) to register \Register{\$(0x18+D)}. - Perform additional operation depending on destination register. + Perform an additional operation depending on destination register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} @@ -2330,7 +2330,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \begin{DSPOpcodeDescription} \item Move value from register \Register{\$S} to register \Register{\$D}. - Perform additional operation depending on destination register. + Perform an additional operation depending on destination register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} @@ -2744,7 +2744,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - $acD =- $acD + $acD = -$acD FLAGS($acD) $pc++ \end{DSPOpcodeOperation} @@ -2981,7 +2981,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \begin{DSPOpcodeDescription} \item Store value from register \Register{\$S} to a memory pointed by address \Address{M}. - Perform additional operation depending on destination register. + Perform an additional operation depending on destination register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} @@ -3001,7 +3001,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \begin{DSPOpcodeDescription} \item Store value from source register \Register{\$S} to a memory location pointed by addressing - register \Register{\$arD}. Perform additional operation depending on source register. + register \Register{\$arD}. Perform an additional operation depending on source register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} @@ -3021,7 +3021,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \begin{DSPOpcodeDescription} \item Store value from source register \Register{\$S} to a memory location pointed by addressing - register \Register{\$arD}. Decrement register \Register{\$arD}. Perform additional operation depending on source register. + register \Register{\$arD}. Decrement register \Register{\$arD}. Perform an additional operation depending on source register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} @@ -3042,7 +3042,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \begin{DSPOpcodeDescription} \item Store value from source register \Register{\$S} to a memory location pointed by addressing - register \Register{\$arD}. Increment register \Register{\$arD}. Perform additional operation depending on source register. + register \Register{\$arD}. Increment register \Register{\$arD}. Perform an additional operation depending on source register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} @@ -3064,7 +3064,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \begin{DSPOpcodeDescription} \item Store value from source register \Register{\$S} to a memory location pointed by addressing register \Register{\$arD}. Add indexing register \Register{\$ixD} to register \Register{\$arD}. - Perform additional operation depending on source register. + Perform an additional operation depending on source register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} @@ -3085,7 +3085,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \begin{DSPOpcodeDescription} \item Store value from register \Register{\$(0x18+S)} to a memory pointed by address \Address{M} (8-bit sign-extended). - Perform additional operation depending on destination register. + Perform an additional operation depending on destination register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} @@ -3203,7 +3203,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Test hight part of secondary accumulator \Register{\$axR.h}. + \item Test high part of secondary accumulator \Register{\$axR.h}. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} @@ -3256,7 +3256,7 @@ There are two pairs of conditions that work similar: \texttt{EQ}/\texttt{NE} and \section{Extended opcodes} Extended opcodes do not exist on their own. These opcodes can only be attached to opcodes that -allow extending (8 lower bits of opcode not used by opcode). Extended opcodes do not modify the program counter (\Register{\$pc} register. +allow extending (8 lower bits of opcode not used by opcode). Extended opcodes do not modify the program counter (\Register{\$pc} register). \pagebreak{} From d9f8df3cbeeb9508da1e5919133359aff1163f3d Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 13 Jul 2021 14:17:15 -0700 Subject: [PATCH 04/49] docs/DSP: Fix typo in HALT encoding "I think I saw a two" --- .../DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 90390078ff..da6b9e56fc 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -1586,7 +1586,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcode}{HALT} \begin{DSPOpcodeBytefield}{16} - \monobitbox{4}{0000} & \monobitbox{4}{0000} & \monobitbox{4}{0020} & \monobitbox{4}{0001} + \monobitbox{4}{0000} & \monobitbox{4}{0000} & \monobitbox{4}{0010} & \monobitbox{4}{0001} \end{DSPOpcodeBytefield} \begin{DSPOpcodeFormat} From 2c73de7ada7df47c292b85da51f8cc8ac831bb7c Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 13 Jul 2021 15:13:36 -0700 Subject: [PATCH 05/49] docs/DSP: Add missing already-documented instructions to opcode table --- .../GameCube_DSP_Users_Manual.tex | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index da6b9e56fc..312fa4074a 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -3637,7 +3637,10 @@ CMPI & & * & 0000 001r 1000 0000 iiii iiii iiii iiii \\ ANDCF & & * & 0000 001r 1010 0000 iiii iiii iiii iiii \\ ANDF & & * & 0000 001r 1100 0000 iiii iiii iiii iiii \\ & & & \\ -ILRR & & * & 0000 001r 0001 mmaa \\ +ILRR & & * & 0000 001r 0001 00aa \\ +ILRRD & & * & 0000 001r 0001 01aa \\ +ILRRI & & * & 0000 001r 0001 10aa \\ +ILRRN & & * & 0000 001r 0001 11aa \\ & & & \\ ADDIS & & * & 0000 010d iiii iiii \\ CMPIS & & * & 0000 011d iiii iiii \\ @@ -3706,6 +3709,7 @@ MULMV & & * & 1001 a11r xxxx xxxx \\ & & & \\ MULX & & * & 101b a000 xxxx xxxx \\ ??? & & & 1010 r001 xxxx xxxx \\ +TST & & & 1011 r001 xxxx xxxx \\ MULXMVZ & & * & 101b a01r xxxx xxxx \\ MULXAC & & * & 101b a10r xxxx xxxx \\ MULXMV & & * & 101b a11r xxxx xxxx \\ @@ -3739,7 +3743,7 @@ MV & & * & xxxx xxxx 0001 ddss \\ S[N] & & * & xxxx xxxx 001r rnaa \\ L[N] & & * & xxxx xxxx 01dd diss \\ LS[NM|M|N] & & * & xxxx xxxx 10dd ba0r \\ -SL & & * & xxxx xxxx 10dd ba1r \\ +SL[NM|M|N] & & * & xxxx xxxx 10dd ba1r \\ LD[NM|M|N] & & & xxxx xxxx 11mn barr \\ LD2[NM|M|N] & & & xxxx xxxx 11rm ba11 \end{longtable} From bb1ecd2a817d1f57127179924dd81ec25c40e8bb Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Fri, 20 Aug 2021 16:17:34 -0700 Subject: [PATCH 06/49] docs/DSP: Add RTI to opcode list --- docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 312fa4074a..12ea60a361 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -3628,6 +3628,7 @@ IF cc & & * & 0000 0010 0111 cccc \\ JMP cc & & * & 0000 0010 1001 cccc \\ CALL cc & & * & 0000 0010 1011 cccc \\ RET cc & & * & 0000 0010 1101 cccc \\ +RTI & & * & 0000 0010 1111 1111 \\ & & & \\ ADDI & & * & 0000 001r 0000 0000 iiii iiii iiii iiii \\ XORI & & * & 0000 001r 0010 0000 iiii iiii iiii iiii \\ From 13051ee2912d27f757d16b72fe4eb423ea2e3d4e Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Thu, 15 Jul 2021 11:30:37 -0700 Subject: [PATCH 07/49] docs/DSP: Elaborate on SBSET and SBCLR --- .../GameCube_DSP_Users_Manual.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 12ea60a361..9272431ffa 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -2921,11 +2921,11 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Set bit of status register \Register{\$sr}. Bit number is calculated by adding 6 to immediate value \Value{I}. + \item Set bit of status register \Register{\$sr}. Bit number is calculated by adding 6 to immediate value \Value{I}; thus, bits 6 through 13 (\texttt{LZ} through \texttt{AM}) can be set with this instruction. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - $sr |= (I + 6) + $sr |= 1 << (I + 6) $pc++ \end{DSPOpcodeOperation} \end{DSPOpcode} @@ -2940,11 +2940,11 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Clear bit of status register \Register{\$sr}. Bit number is calculated by adding 6 to immediate value \Value{I}. + \item Clear bit of status register \Register{\$sr}. Bit number is calculated by adding 6 to immediate value \Value{I}; thus, bits 6 through 13 (\texttt{LZ} through \texttt{AM}) can be cleared with this instruction. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - $sr &= ~(I + 6) + $sr &= ~(1 << (I + 6)) $pc++ \end{DSPOpcodeOperation} \end{DSPOpcode} From 000f7b102a3fc420d8bffce810de12fb8cf9754f Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sat, 17 Jul 2021 15:05:19 -0700 Subject: [PATCH 08/49] docs/DSP: Fix SBCLR and SBSET being backwards Dolphin has them with SBCLR as 1200 and SBSET as 1300 since the inital megacommit: https://github.com/dolphin-emu/dolphin/blob/775dc8a9c0c83f7a2f776e97f5b90385c759535a/Source/Plugins/Plugin_DSP_LLE/Src/opcodes.cpp#L67-L68 --- .../GameCube_DSP_Users_Manual.tex | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 9272431ffa..5ab87afe0b 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -2911,28 +2911,9 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} -\begin{DSPOpcode}{SBSET} - \begin{DSPOpcodeBytefield}{16} - \monobitbox{4}{0001} & \monobitbox{4}{0010} & \monobitbox{4}{0000} & \monobitbox{4}{0iii} - \end{DSPOpcodeBytefield} - - \begin{DSPOpcodeFormat} - SBSET #I - \end{DSPOpcodeFormat} - - \begin{DSPOpcodeDescription} - \item Set bit of status register \Register{\$sr}. Bit number is calculated by adding 6 to immediate value \Value{I}; thus, bits 6 through 13 (\texttt{LZ} through \texttt{AM}) can be set with this instruction. - \end{DSPOpcodeDescription} - - \begin{DSPOpcodeOperation} - $sr |= 1 << (I + 6) - $pc++ - \end{DSPOpcodeOperation} -\end{DSPOpcode} - \begin{DSPOpcode}{SBCLR} \begin{DSPOpcodeBytefield}{16} - \monobitbox{4}{0001} & \monobitbox{4}{0011} & \monobitbox{4}{0000} & \monobitbox{4}{0iii} + \monobitbox{4}{0001} & \monobitbox{4}{0010} & \monobitbox{4}{0000} & \monobitbox{4}{0iii} \end{DSPOpcodeBytefield} \begin{DSPOpcodeFormat} @@ -2949,6 +2930,25 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{SBSET} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{0001} & \monobitbox{4}{0011} & \monobitbox{4}{0000} & \monobitbox{4}{0iii} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + SBSET #I + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Set bit of status register \Register{\$sr}. Bit number is calculated by adding 6 to immediate value \Value{I}; thus, bits 6 through 13 (\texttt{LZ} through \texttt{AM}) can be set with this instruction. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $sr |= 1 << (I + 6) + $pc++ + \end{DSPOpcodeOperation} +\end{DSPOpcode} + \begin{DSPOpcode}{SI} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{0001} & \monobitbox{4}{0110} & \monobitbox{4}{mmmm} & \monobitbox{4}{mmmm} \\ @@ -3649,8 +3649,8 @@ LRIS & & * & 0000 1rrr iiii iiii \\ & & & \\ LOOPI & & * & 0001 0000 iiii iiii aaaa aaaa aaaa aaaa \\ BLOOPI & & * & 0001 0001 iiii iiii aaaa aaaa aaaa aaaa \\ -SBSET & & * & 0001 0010 ???? ?iii \\ -SBCLR & & * & 0001 0011 ???? ?iii \\ +SBCLR & & * & 0001 0010 ???? ?iii \\ +SBSET & & * & 0001 0011 ???? ?iii \\ LSL/LSR & & * & 0001 010r 0sss ssss \\ ASL/ASR & & * & 0001 010r 1sss ssss \\ SI & & * & 0001 0110 iiii iiii mmmm mmmm mmmm mmmm \\ From 5a0155a1cb5ff3f0e98e8dcc8444f92e8e821986 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sat, 17 Jul 2021 15:24:11 -0700 Subject: [PATCH 09/49] docs/DSP: Fix ANDCF and ANDF being swapped This was implemented in Dolphin in 7c4e6542533f7cef929ce86117b156c714820618. That change also noted that JZR/JNZ were swapped; this was already fixed in facd1dca128dcd159276b6973cb8d747ec0f9c51. --- .../GameCube_DSP_Users_Manual.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 5ab87afe0b..56a1b3e2dc 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -1100,7 +1100,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcode}{ANDCF} \begin{DSPOpcodeBytefield}{16} - \monobitbox{4}{0000} & \monobitbox{4}{001r} & \monobitbox{4}{1010} & \monobitbox{4}{0000} \\ + \monobitbox{4}{0000} & \monobitbox{4}{001r} & \monobitbox{4}{1100} & \monobitbox{4}{0000} \\ \monobitbox{4}{iiii} & \monobitbox{4}{iiii} & \monobitbox{4}{iiii} & \monobitbox{4}{iiii} \end{DSPOpcodeBytefield} @@ -1126,7 +1126,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcode}{ANDF} \begin{DSPOpcodeBytefield}{16} - \monobitbox{4}{0000} & \monobitbox{4}{001r} & \monobitbox{4}{1100} & \monobitbox{4}{0000} \\ + \monobitbox{4}{0000} & \monobitbox{4}{001r} & \monobitbox{4}{1010} & \monobitbox{4}{0000} \\ \monobitbox{4}{iiii} & \monobitbox{4}{iiii} & \monobitbox{4}{iiii} & \monobitbox{4}{iiii} \end{DSPOpcodeBytefield} @@ -3635,8 +3635,8 @@ XORI & & * & 0000 001r 0010 0000 iiii iiii iiii iiii \\ ANDI & & * & 0000 001r 0100 0000 iiii iiii iiii iiii \\ ORI & & * & 0000 001r 0110 0000 iiii iiii iiii iiii \\ CMPI & & * & 0000 001r 1000 0000 iiii iiii iiii iiii \\ -ANDCF & & * & 0000 001r 1010 0000 iiii iiii iiii iiii \\ -ANDF & & * & 0000 001r 1100 0000 iiii iiii iiii iiii \\ +ANDF & & * & 0000 001r 1010 0000 iiii iiii iiii iiii \\ +ANDCF & & * & 0000 001r 1100 0000 iiii iiii iiii iiii \\ & & & \\ ILRR & & * & 0000 001r 0001 00aa \\ ILRRD & & * & 0000 001r 0001 01aa \\ From cfc6de8545ac759ced50782ae409280feddbf8f0 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 13 Jul 2021 15:12:21 -0700 Subject: [PATCH 10/49] docs/DSP: Fix LOOPI, BLOOP, Jcc, and CALLcc opcode table operands --- .../GameCube_DSP_Users_Manual.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 56a1b3e2dc..c5bf0367ab 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -3617,7 +3617,7 @@ ADDARN & & * & 0000 0000 0001 bbaa \\ HALT & & * & 0000 0000 0010 0001 \\ & & & \\ LOOP & & * & 0000 0000 010r rrrr \\ -BLOOP & & * & 00000 0000 011r rrrr \\ +BLOOP & & * & 0000 0000 011r rrrr aaaa aaaa aaaa aaaa \\ & & & \\ LRI & & * & 0000 0000 100r rrrr iiii iiii iiii iiii \\ XXX & NOT USED & * & 0000 0000 101x xxxx \\ @@ -3625,8 +3625,8 @@ LR & & * & 0000 0000 110r rrrr mmmm mmmm mmmm mmmm \\ SR & & * & 0000 0000 111r rrrr mmmm mmmm mmmm mmmm \\ & & & \\ IF cc & & * & 0000 0010 0111 cccc \\ -JMP cc & & * & 0000 0010 1001 cccc \\ -CALL cc & & * & 0000 0010 1011 cccc \\ +JMP cc & & * & 0000 0010 1001 cccc aaaa aaaa aaaa aaaa \\ +CALL cc & & * & 0000 0010 1011 cccc aaaa aaaa aaaa aaaa \\ RET cc & & * & 0000 0010 1101 cccc \\ RTI & & * & 0000 0010 1111 1111 \\ & & & \\ @@ -3647,7 +3647,7 @@ ADDIS & & * & 0000 010d iiii iiii \\ CMPIS & & * & 0000 011d iiii iiii \\ LRIS & & * & 0000 1rrr iiii iiii \\ & & & \\ -LOOPI & & * & 0001 0000 iiii iiii aaaa aaaa aaaa aaaa \\ +LOOPI & & * & 0001 0000 iiii iiii \\ BLOOPI & & * & 0001 0001 iiii iiii aaaa aaaa aaaa aaaa \\ SBCLR & & * & 0001 0010 ???? ?iii \\ SBSET & & * & 0001 0011 ???? ?iii \\ From 6df892dca768cdca6a16b21859711bb5a7486a04 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 10 Aug 2021 09:16:48 -0700 Subject: [PATCH 11/49] docs/DSP: Expand DSP Memory Map section --- .../GameCube_DSP_Users_Manual.tex | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index c5bf0367ab..dcf8c18e2c 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -372,14 +372,17 @@ Each version of the License is given a distinguishing version number. If the Doc \section{DSP Memory Map} -The DSP accesses memory in words, so all addresses refer to words. A DSP word is 16 bits in size. +The DSP has two address spaces, one for data and one for instructions. The DSP accesses memory in words, so all addresses refer to words. A DSP word is 16 bits in size. +\subsection{Instruction Memory} Instruction Memory (IMEM) is divided into instruction RAM (IRAM) and instruction ROM (IROM). -Exception vectors are located at the top of the RAM and occupy the first 8 words. +Exception vectors are located at the top of the RAM and occupy the first 16 words, with 2 words available for each exception (enough for a \Opcode{JMP} instruction for each exception). DSP IRAM is mapped through as first 8KB of ARAM (Accelerator RAM), therefore the CPU can DMA DSP code to DSP IRAM. This usually occurs during boot time, as the DSP ROM is not enabled at cold reset and needs to be reenabled by a small stub executed in IRAM. +There are no DSP instructions that write to IMEM; however, the \texttt{ILLR} family of instructions can read from it. This is sometimes used for jump tables or indexing into a list of pointers (which may point into either IMEM or DMEM). + \begin{table}[htb] \centering \begin{tabular}{|l|l|} @@ -392,6 +395,25 @@ DSP IRAM is mapped through as first 8KB of ARAM (Accelerator RAM), therefore the \pagebreak{} +\subsection{Data Memory} +Data Memory (DMEM) is divided into data RAM (DRAM) and resampling coefficient data (COEF). Hardware registers (IFX) are also mapped into this space. + +It is possible to both read and write to DMEM, but coefficient data cannot be written to. + +\begin{table}[htb] +\centering +\begin{tabular}{|l|l|} +\hline +\begin{tabular}[c]{@{}l@{}}\texttt{0x0000}\\ \\ \\ \\ \\ \\ \\ \\ \texttt{0x0FFF}\end{tabular} & \texttt{DRAM} \\ \hline + & \\ \hline +\begin{tabular}[c]{@{}l@{}}\texttt{0x1000}\\ \\ \\ \\ \\ \\ \\ \\ \texttt{0x17FF}\end{tabular} & \texttt{COEF} \\ \hline + & \\ \hline +\begin{tabular}[c]{@{}l@{}}\texttt{0xFF00}\\ \\ \\ \\\\ \\ \\ \\ \texttt{0xFFFF}\end{tabular} & \texttt{IFX} \\ \hline +\end{tabular} +\end{table} + +\pagebreak{} + \chapter{Registers} \section{Register names} From b99fbf7e9c8359bdfa6149af1f01f9617b52bc1b Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 10 Aug 2021 14:18:42 -0700 Subject: [PATCH 12/49] docs/DSP: Sort hardware registers by address The actual documentation for registers is not changed in this commit; nor are any new registers added. This is purely to make later diffs more readable. --- .../GameCube_DSP_Users_Manual.tex | 146 +++++++++--------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index dcf8c18e2c..4eb5d9d05e 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -616,17 +616,12 @@ Hardware registers occupy the address space at \Address{0xFFxx} in DSP memory sp \begin{tabular}{|l|l|l|} \hline \textbf{Address} & \textbf{Name} & \textbf{Description} \\ \hline -\multicolumn{3}{|l|}{\textit{Mailboxes}} \\ \hline -\Address{0xFFFE} & \Register{CMBH} & CPU Mailbox H \\ \hline -\Address{0xFFFF} & \Register{CMBL} & CPU Mailbox L \\ \hline -\Address{0xFFFC} & \Register{DMBH} & DSP Mailbox H \\ \hline -\Address{0xFFFD} & \Register{DMBL} & DSP Mailbox L \\ \hline \multicolumn{3}{|l|}{\textit{DMA Interface}} \\ \hline -\Address{0xFFCE} & \Register{DSMAH} & Memory address H \\ \hline -\Address{0xFFCF} & \Register{DSMAL} & Memory address L \\ \hline -\Address{0xFFCD} & \Register{DSPA} & DSP memory address \\ \hline \Address{0xFFC9} & \Register{DSCR} & DMA control \\ \hline \Address{0xFFCB} & \Register{DSBL} & Block size \\ \hline +\Address{0xFFCD} & \Register{DSPA} & DSP memory address \\ \hline +\Address{0xFFCE} & \Register{DSMAH} & Memory address H \\ \hline +\Address{0xFFCF} & \Register{DSMAL} & Memory address L \\ \hline \multicolumn{3}{|l|}{\textit{Accelerator}} \\ \hline \Address{0xFFD4} & \Register{ACSAH} & Accelerator start address H \\ \hline \Address{0xFFD5} & \Register{ACSAL} & Accelerator start address L \\ \hline @@ -637,11 +632,62 @@ Hardware registers occupy the address space at \Address{0xFFxx} in DSP memory sp \Address{0xFFDD} & \Register{ACDAT} & Accelerator data \\ \hline \multicolumn{3}{|l|}{\textit{Interrupts}} \\ \hline \Address{0xFFFB} & \Register{DIRQ} & IRQ request \\ \hline +\multicolumn{3}{|l|}{\textit{Mailboxes}} \\ \hline +\Address{0xFFFC} & \Register{DMBH} & DSP Mailbox H \\ \hline +\Address{0xFFFD} & \Register{DMBL} & DSP Mailbox L \\ \hline +\Address{0xFFFE} & \Register{CMBH} & CPU Mailbox H \\ \hline +\Address{0xFFFF} & \Register{CMBL} & CPU Mailbox L \\ \hline \end{tabular} \end{table} \pagebreak{} +\section{DMA} + +The GameCube DSP is connected to the memory bus through a DMA channel. DMA can be used to transfer data between DSP memory (both instruction and data) and main memory. + +\RegisterBitOverview{0xFFC9}{DSCR}{DSP Address}{---- ---- ---- ----} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{W}{} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFCB}{DSBL}{DSP Address}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{W}{Length in bytes to transfer. Writing to this register starts a DMA transfer.} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFCD}{DSPA}{DSP Address}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{W}{Bits 15--0 of the DSP memory address} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFCE}{DSMAH}{Memory Address H}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R}{Bits 31--16 of the main memory address} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFCF}{DSMAL}{Memory Address L}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R}{Bits 15--0 of the main memory address} +\end{RegisterBitDescriptions} + +\pagebreak{} + +\section{Accelerator} + +The accelerator is used to transfer data from accelerator memory (ARAM) to DSP memory. The accelerator area can be marked with \Register{ACSA} (start) and \Register{ACEA} (end) addresses. +Current address for the accelerator can be set or read from the \Register{ACCA} register. Reading from accelerator memory is done by reading from the \Register{ACDAT} register. +This register contains data from ARAM pointed to by the \Register{ACCA} register. +After reading the data, \Register{ACCA} is incremented by one. +After \Register{ACCA} grows bigger than the area pointed to by \Register{ACEA}, it gets reset to a value from \Register{ACSA} and the \Exception{ACCOV} interrupt is generated. + +\pagebreak{} + \section{Interrupts} The DSP can raise interrupts at the CPU. Interrupts are usually used to signal that a DSP mailbox has been filled with new data. @@ -656,40 +702,6 @@ The DSP can raise interrupts at the CPU. Interrupts are usually used to signal t \section{Mailboxes} -\subsection{CPU Mailbox} - -The CPU Mailbox (CMB) is a register that allows sending 31 bits of information from the CPU to the DSP. - -\RegisterBitOverview{0xFFFE}{CMBH}{CPU Mailbox H}{Mddd dddd dddd dddd} - -\begin{RegisterBitDescriptions} -\RegisterBitDescription{15}{M}{R}{ - \begin{tabular}[c]{@{}l@{}} - \Value{1} - Mailbox contains mail from the CPU\\ \Value{0} - Mailbox empty - \end{tabular} -} -\RegisterBitDescription{14--0}{d}{R}{Bits 30--16 of the mail sent from the CPU} -\end{RegisterBitDescriptions} - -\RegisterBitOverview{0xFFFF}{CMBL}{CPU Mailbox L}{dddd dddd dddd dddd} - -\begin{RegisterBitDescriptions} -\RegisterBitDescription{15--0}{d}{R}{ - Bits 15--0 of mail sent from the CPU. Reading of this register by the DSP causes the \RegisterField{CMBH.M} - bit to be cleared. -} -\end{RegisterBitDescriptions} - -\textbf{Operation:} - -From the CPU side, software usually checks the \RegisterField{M} bit of \Register{CMBH}. It takes action only in the case that this bit is \Value{0}. -Said action is to write \Register{CMBH} first and then \Register{CMBL}. After writing to \Register{CMBL}, the mail is ready to be received by the DSP. - -From the DSP side, the DSP loops by probing the \RegisterField{M} bit. When this bit is \Value{1}, the DSP reads \Register{CMBH} first and then \Register{CMBL}. -After reading \Register{CMBL}, \RegisterField{CMBH.M} will be cleared. - -\pagebreak{} - \subsection{DSP Mailbox} The DSP mailbox (DMB) is an interface to send 31 bits of information from the DSP to the CPU. @@ -725,49 +737,37 @@ If the DSP does processing when the CPU receives a mail, then it waits for the \ \pagebreak{} -\subsection{DMA} +\subsection{CPU Mailbox} -The GameCube DSP is connected to the memory bus through a DMA channel. DMA can be used to transfer data between DSP memory (both instruction and data) and main memory. +The CPU Mailbox (CMB) is a register that allows sending 31 bits of information from the CPU to the DSP. -\RegisterBitOverview{0xFFCE}{DSMAH}{Memory Address H}{dddd dddd dddd dddd} +\RegisterBitOverview{0xFFFE}{CMBH}{CPU Mailbox H}{Mddd dddd dddd dddd} \begin{RegisterBitDescriptions} -\RegisterBitDescription{15--0}{d}{R}{Bits 31--16 of the main memory address} +\RegisterBitDescription{15}{M}{R}{ + \begin{tabular}[c]{@{}l@{}} + \Value{1} - Mailbox contains mail from the CPU\\ \Value{0} - Mailbox empty + \end{tabular} +} +\RegisterBitDescription{14--0}{d}{R}{Bits 30--16 of the mail sent from the CPU} \end{RegisterBitDescriptions} -\RegisterBitOverview{0xFFCF}{DSMAL}{Memory Address L}{dddd dddd dddd dddd} +\RegisterBitOverview{0xFFFF}{CMBL}{CPU Mailbox L}{dddd dddd dddd dddd} \begin{RegisterBitDescriptions} -\RegisterBitDescription{15--0}{d}{R}{Bits 15--0 of the main memory address} +\RegisterBitDescription{15--0}{d}{R}{ + Bits 15--0 of mail sent from the CPU. Reading of this register by the DSP causes the \RegisterField{CMBH.M} + bit to be cleared. +} \end{RegisterBitDescriptions} -\RegisterBitOverview{0xFFCD}{DSPA}{DSP Address}{dddd dddd dddd dddd} +\textbf{Operation:} -\begin{RegisterBitDescriptions} -\RegisterBitDescription{15--0}{d}{W}{Bits 15--0 of the DSP memory address} -\end{RegisterBitDescriptions} +From the CPU side, software usually checks the \RegisterField{M} bit of \Register{CMBH}. It takes action only in the case that this bit is \Value{0}. +Said action is to write \Register{CMBH} first and then \Register{CMBL}. After writing to \Register{CMBL}, the mail is ready to be received by the DSP. -\RegisterBitOverview{0xFFCB}{DSBL}{DSP Address}{dddd dddd dddd dddd} - -\begin{RegisterBitDescriptions} -\RegisterBitDescription{15--0}{d}{W}{Length in bytes to transfer. Writing to this register starts a DMA transfer.} -\end{RegisterBitDescriptions} - -\RegisterBitOverview{0xFFC9}{DSCR}{DSP Address}{---- ---- ---- ----} - -\begin{RegisterBitDescriptions} -\RegisterBitDescription{15--0}{d}{W}{} -\end{RegisterBitDescriptions} - -\pagebreak{} - -\section{Accelerator} - -The accelerator is used to transfer data from accelerator memory (ARAM) to DSP memory. The accelerator area can be marked with \Register{ACSA} (start) and \Register{ACEA} (end) addresses. -Current address for the accelerator can be set or read from the \Register{ACCA} register. Reading from accelerator memory is done by reading from the \Register{ACDAT} register. -This register contains data from ARAM pointed to by the \Register{ACCA} register. -After reading the data, \Register{ACCA} is incremented by one. -After \Register{ACCA} grows bigger than the area pointed to by \Register{ACEA}, it gets reset to a value from \Register{ACSA} and the \Exception{ACCOV} interrupt is generated. +From the DSP side, the DSP loops by probing the \RegisterField{M} bit. When this bit is \Value{1}, the DSP reads \Register{CMBH} first and then \Register{CMBL}. +After reading \Register{CMBL}, \RegisterField{CMBH.M} will be cleared. \pagebreak{} From 9a269929ec38fb27f77bb2a7093add553a53b5e6 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 10 Aug 2021 14:20:33 -0700 Subject: [PATCH 13/49] docs/DSP: Improve DMA hardware register information --- .../GameCube_DSP_Users_Manual.tex | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 4eb5d9d05e..cacb824809 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -618,7 +618,7 @@ Hardware registers occupy the address space at \Address{0xFFxx} in DSP memory sp \textbf{Address} & \textbf{Name} & \textbf{Description} \\ \hline \multicolumn{3}{|l|}{\textit{DMA Interface}} \\ \hline \Address{0xFFC9} & \Register{DSCR} & DMA control \\ \hline -\Address{0xFFCB} & \Register{DSBL} & Block size \\ \hline +\Address{0xFFCB} & \Register{DSBL} & Block length \\ \hline \Address{0xFFCD} & \Register{DSPA} & DSP memory address \\ \hline \Address{0xFFCE} & \Register{DSMAH} & Memory address H \\ \hline \Address{0xFFCF} & \Register{DSMAL} & Memory address L \\ \hline @@ -646,13 +646,15 @@ Hardware registers occupy the address space at \Address{0xFFxx} in DSP memory sp The GameCube DSP is connected to the memory bus through a DMA channel. DMA can be used to transfer data between DSP memory (both instruction and data) and main memory. -\RegisterBitOverview{0xFFC9}{DSCR}{DSP Address}{---- ---- ---- ----} +\RegisterBitOverview{0xFFC9}{DSCR}{DMA Control}{---- ---- ---- -tid} \begin{RegisterBitDescriptions} -\RegisterBitDescription{15--0}{d}{W}{} +\RegisterBitDescription{2}{t}{R}{Transfer currently in progress if set} +\RegisterBitDescription{1}{i}{R/W}{\begin{tabular}[c]{@{}l@{}}\Value{1} - DMA to/from IMEM\\ \Value{0} - DMA to/from DMEM\end{tabular}} +\RegisterBitDescription{0}{d}{R/W}{\begin{tabular}[c]{@{}l@{}}\Value{1} - DMA to CPU from DSP\\ \Value{0} - DMA from CPU to DSP\end{tabular}} \end{RegisterBitDescriptions} -\RegisterBitOverview{0xFFCB}{DSBL}{DSP Address}{dddd dddd dddd dddd} +\RegisterBitOverview{0xFFCB}{DSBL}{Block length}{dddd dddd dddd dddd} \begin{RegisterBitDescriptions} \RegisterBitDescription{15--0}{d}{W}{Length in bytes to transfer. Writing to this register starts a DMA transfer.} @@ -661,19 +663,19 @@ The GameCube DSP is connected to the memory bus through a DMA channel. DMA can b \RegisterBitOverview{0xFFCD}{DSPA}{DSP Address}{dddd dddd dddd dddd} \begin{RegisterBitDescriptions} -\RegisterBitDescription{15--0}{d}{W}{Bits 15--0 of the DSP memory address} +\RegisterBitDescription{15--0}{d}{R/W}{Bits 15--0 of the DSP memory address} \end{RegisterBitDescriptions} \RegisterBitOverview{0xFFCE}{DSMAH}{Memory Address H}{dddd dddd dddd dddd} \begin{RegisterBitDescriptions} -\RegisterBitDescription{15--0}{d}{R}{Bits 31--16 of the main memory address} +\RegisterBitDescription{15--0}{d}{R/W}{Bits 31--16 of the main memory address} \end{RegisterBitDescriptions} \RegisterBitOverview{0xFFCF}{DSMAL}{Memory Address L}{dddd dddd dddd dddd} \begin{RegisterBitDescriptions} -\RegisterBitDescription{15--0}{d}{R}{Bits 15--0 of the main memory address} +\RegisterBitDescription{15--0}{d}{R/W}{Bits 15--0 of the main memory address} \end{RegisterBitDescriptions} \pagebreak{} From c9ed9dd0a790ab13080a541b7393f94e8bbdba06 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 10 Aug 2021 14:24:46 -0700 Subject: [PATCH 14/49] docs/DSP: Adjust formatting of RegisterBitOverview --- .../GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index cacb824809..1335c01642 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -72,10 +72,10 @@ \newcommand{\RegisterBitOverview}[4]{ \begin{table}[H] \centering - \begin{tabular}{|lcl|} + \begin{tabular}{|lcr|} \hline - \Address{#1} & \Register{#2} & \multicolumn{1}{r|}{#3} \\ \hline - & \texttt{#4} & \\ \hline + \Address{#1} & \Register{#2} & {#3} \\ \hline + \multicolumn{3}{|c|}{\texttt{#4}} \\ \hline \end{tabular} \end{table} } From 2a9e1a3b5dcfab60deab57249b91b6a6e745d1b4 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 10 Aug 2021 15:47:30 -0700 Subject: [PATCH 15/49] docs/DSP: Document accelerator hardware registers --- .../GameCube_DSP_Users_Manual.tex | 168 +++++++++++++++--- 1 file changed, 145 insertions(+), 23 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 1335c01642..9c88f8b611 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -609,34 +609,49 @@ Exception vectors are located at address \Address{0x0000} in Instruction RAM. \section{Hardware registers} -Hardware registers occupy the address space at \Address{0xFFxx} in DSP memory space. Each register is 16 bits in width. +Hardware registers (IFX) occupy the address space at \Address{0xFFxx} in the Data Memory space. Each register is 16 bits in width. \begin{table}[htb] \centering \begin{tabular}{|l|l|l|} \hline -\textbf{Address} & \textbf{Name} & \textbf{Description} \\ \hline -\multicolumn{3}{|l|}{\textit{DMA Interface}} \\ \hline -\Address{0xFFC9} & \Register{DSCR} & DMA control \\ \hline -\Address{0xFFCB} & \Register{DSBL} & Block length \\ \hline -\Address{0xFFCD} & \Register{DSPA} & DSP memory address \\ \hline -\Address{0xFFCE} & \Register{DSMAH} & Memory address H \\ \hline -\Address{0xFFCF} & \Register{DSMAL} & Memory address L \\ \hline -\multicolumn{3}{|l|}{\textit{Accelerator}} \\ \hline -\Address{0xFFD4} & \Register{ACSAH} & Accelerator start address H \\ \hline -\Address{0xFFD5} & \Register{ACSAL} & Accelerator start address L \\ \hline -\Address{0xFFD6} & \Register{ACEAH} & Accelerator end address H \\ \hline -\Address{0xFFD7} & \Register{ACEAL} & Accelerator end address L \\ \hline -\Address{0xFFD8} & \Register{ACCAH} & Accelerator current address H \\ \hline -\Address{0xFFD9} & \Register{ACCAL} & Accelerator current address L \\ \hline -\Address{0xFFDD} & \Register{ACDAT} & Accelerator data \\ \hline -\multicolumn{3}{|l|}{\textit{Interrupts}} \\ \hline -\Address{0xFFFB} & \Register{DIRQ} & IRQ request \\ \hline -\multicolumn{3}{|l|}{\textit{Mailboxes}} \\ \hline -\Address{0xFFFC} & \Register{DMBH} & DSP Mailbox H \\ \hline -\Address{0xFFFD} & \Register{DMBL} & DSP Mailbox L \\ \hline -\Address{0xFFFE} & \Register{CMBH} & CPU Mailbox H \\ \hline -\Address{0xFFFF} & \Register{CMBL} & CPU Mailbox L \\ \hline +\textbf{Address} & \textbf{Name} & \textbf{Description} \\ \hline +\multicolumn{3}{|l|}{\textit{ADPCM Coefficients}} \\ \hline +\Address{0xFFA0} & \Register{COEF\_A1\_0} & A1 Coefficient \# 0 \\ \hline +\Address{0xFFA1} & \Register{COEF\_A2\_0} & A2 Coefficient \# 0 \\ \hline +\multicolumn{3}{|c|}{$\vdots$} \\ \hline +\Address{0xFFAE} & \Register{COEF\_A1\_7} & A1 Coefficient \# 7 \\ \hline +\Address{0xFFAF} & \Register{COEF\_A2\_7} & A2 Coefficient \# 7 \\ \hline +\multicolumn{3}{|l|}{\textit{DMA Interface}} \\ \hline +\Address{0xFFC9} & \Register{DSCR} & DMA control \\ \hline +\Address{0xFFCB} & \Register{DSBL} & Block length \\ \hline +\Address{0xFFCD} & \Register{DSPA} & DSP memory address \\ \hline +\Address{0xFFCE} & \Register{DSMAH} & Memory address H \\ \hline +\Address{0xFFCF} & \Register{DSMAL} & Memory address L \\ \hline +\multicolumn{3}{|l|}{\textit{Accelerator}} \\ \hline +\Address{0xFFD1} & \Register{FORMAT} & Accelerator sample format \\ \hline +\Address{0xFFD2} & \Register{ACUNK1} & Unknown, usually 3 \\ \hline +\Address{0xFFD3} & \Register{ACDATA1} & Alternative ARAM interface \\ \hline +\Address{0xFFD4} & \Register{ACSAH} & Accelerator start address H \\ \hline +\Address{0xFFD5} & \Register{ACSAL} & Accelerator start address L \\ \hline +\Address{0xFFD6} & \Register{ACEAH} & Accelerator end address H \\ \hline +\Address{0xFFD7} & \Register{ACEAL} & Accelerator end address L \\ \hline +\Address{0xFFD8} & \Register{ACCAH} & Accelerator current address H \\ \hline +\Address{0xFFD9} & \Register{ACCAL} & Accelerator current address L \\ \hline +\Address{0xFFDA} & \Register{SCALE} & ADPCM predictor and scale \\ \hline +\Address{0xFFDB} & \Register{YN1} & ADPCM YN1 \\ \hline +\Address{0xFFDC} & \Register{YN2} & ADPCM YN2 \\ \hline +\Address{0xFFDD} & \Register{ACDAT} & Accelerator data \\ \hline +\Address{0xFFDE} & \Register{GAIN} & Gain \\ \hline +\Address{0xFFDF} & \Register{ACUNK2} & Unknown, usually \Value{0x0C} \\ \hline +\Address{0xFFED} & \Register{AMDM} & ARAM DMA Request Mask \\ \hline +\multicolumn{3}{|l|}{\textit{Interrupts}} \\ \hline +\Address{0xFFFB} & \Register{DIRQ} & IRQ request \\ \hline +\multicolumn{3}{|l|}{\textit{Mailboxes}} \\ \hline +\Address{0xFFFC} & \Register{DMBH} & DSP Mailbox H \\ \hline +\Address{0xFFFD} & \Register{DMBL} & DSP Mailbox L \\ \hline +\Address{0xFFFE} & \Register{CMBH} & CPU Mailbox H \\ \hline +\Address{0xFFFF} & \Register{CMBL} & CPU Mailbox L \\ \hline \end{tabular} \end{table} @@ -688,6 +703,113 @@ This register contains data from ARAM pointed to by the \Register{ACCA} register After reading the data, \Register{ACCA} is incremented by one. After \Register{ACCA} grows bigger than the area pointed to by \Register{ACEA}, it gets reset to a value from \Register{ACSA} and the \Exception{ACCOV} interrupt is generated. +\RegisterBitOverview{0xFFD1}{FORMAT}{Accelerator sample format}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R/W}{\begin{tabular}[c]{@{}l@{}} +\Value{0x00} - ADPCM audio \\ +\Value{0x05} - u8 reads (D3) \\ +\Value{0x06} - u16 reads (D3) \\ +\Value{0x0A} - 16-bit PCM audio, u16 writes (D3) \\ +\Value{0x19} - 8-bit PCM audio +\end{tabular}} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFD2}{ACUNK1}{Unknown 1}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R/W}{Usually 3} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFD3}{ACDATA1}{Alternative ARAM interface}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R/W}{Reads from or writes to data pointed to by current accelerator address, and then increments the current address. It is unclear whether this respects the start and end addresses.} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFD4}{ACSAH}{Accelerator Start Address H}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R/W}{Bits 31--16 of the accelerator start address} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFD5}{ACSAL}{Accelerator Start Address L}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R/W}{Bits 15--0 of the accelerator start address} +\end{RegisterBitDescriptions} + +\pagebreak{} + +\RegisterBitOverview{0xFFD6}{ACEAH}{Accelerator End Address H}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R/W}{Bits 31--16 of the accelerator end address} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFD7}{ACEAL}{Accelerator End Address L}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R/W}{Bits 15--0 of the accelerator end address} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFD8}{ACCAH}{Accelerator Current Address H}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R/W}{Bits 31--16 of the accelerator current address} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFD9}{ACSAH}{Accelerator Current Address L}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R/W}{Bits 15--0 of the accelerator current address} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFDA}{SCALE}{ADPCM predictor and scale}{---- ---- -ppp ssss} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{6--4}{d}{R/W}{Used to decide which pair of coefficients to use (\Register{COEF\_A1\_p} and \Register{COEF\_A2\_p}, at $\Address{0xFFA0} + 2p$ and $\Address{0xFFA0} + 2p + 1$)} +\RegisterBitDescription{3--0}{s}{R/W}{The scale to use, as $2^s$} +\end{RegisterBitDescriptions} + +\pagebreak{} + +\RegisterBitOverview{0xFFDB}{YN1}{ADPCM YN1}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R/W}{Last value read by the accelerator, updated to the new value of \Register{ACDAT} when \Register{ACDAT} is read. Used when calculating ADPCM, but updated for all sample formats.} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFDC}{YN1}{ADPCM YN2}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R/W}{Second-last value read by the accelerator, updated to the previous value of \Register{YN1} when \Register{ACDAT} is read. Used when calculating ADPCM, but updated for all sample formats. Writing this value starts the accelerator.} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFDD}{ACDAT}{Accelerator data}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R}{Reads new data from the accelerator. When there is no data left, returns 0.} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFDE}{GAIN}{Gain}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R/W}{Exact behavior unknown} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFDF}{ACUNK2}{Unknown 2}{dddd dddd dddd dddd} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{15--0}{d}{R/W}{Usually \Value{0x0C}} +\end{RegisterBitDescriptions} + +\RegisterBitOverview{0xFFEF}{AMDM}{ARAM DMA Request Mask}{---- ---- ---- ---m} + +\begin{RegisterBitDescriptions} +\RegisterBitDescription{0}{m}{R/W}{\begin{tabular}[c]{@{}l@{}}\Value{0} - DMA with ARAM unmasked\\ \Value{1} - masked\end{tabular}} +\end{RegisterBitDescriptions} + \pagebreak{} \section{Interrupts} From ccc50859885f7f6161d028a991960061406643e6 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Wed, 11 Aug 2021 16:24:32 -0700 Subject: [PATCH 16/49] docs/DSP: Rename 'SLMN to 'SLNM This is for consistency with Dolphin, the opcode table, and 'LSNM. --- .../GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 9c88f8b611..0ead0fd656 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -3681,13 +3681,13 @@ allow extending (8 lower bits of opcode not used by opcode). Extended opcodes do \end{DSPOpcodeOperation} \end{DSPOpcode} -\begin{DSPOpcode}{'SLMN} +\begin{DSPOpcode}{'SLNM} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} & \monobitbox{4}{10dd} & \monobitbox{4}{111s} \end{DSPOpcodeBytefield} \begin{DSPOpcodeFormat} - 'SLMN $acS.m, $(0x18+D) + 'SLNM $acS.m, $(0x18+D) \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} From 16da6e214df9e4a34309df39c131f0e98a8cbfd4 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Wed, 11 Aug 2021 16:35:41 -0700 Subject: [PATCH 17/49] docs/DSP: Hyperlink opcode names --- .../GameCube_DSP_Users_Manual.tex | 307 ++++++++++-------- 1 file changed, 168 insertions(+), 139 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 0ead0fd656..95ad9ba75c 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -49,7 +49,7 @@ \date{\today\\v0.0.7} % Title formatting commands -\newcommand{\OpcodeTitle}[1]{\subsection{\textbf{\Large #1}}} +\newcommand{\OpcodeTitle}[1]{\subsection{#1}\label{instruction:#1}} % Formatting/self-documenting commands \newcommand{\Address}[1]{\texttt{#1}} @@ -58,7 +58,7 @@ \newcommand{\Flag}[1]{\texttt{#1}} \newcommand{\Function}[1]{\texttt{#1}} \newcommand{\InlineExpression}[1]{\texttt{#1}} -\newcommand{\Opcode}[1]{\texttt{#1}} +\newcommand{\Opcode}[1]{\texttt{\nameref{instruction:#1}}} \newcommand{\Register}[1]{\texttt{#1}} \newcommand{\RegisterField}[1]{\texttt{#1}} \newcommand{\Value}[1]{\texttt{#1}} @@ -1005,7 +1005,7 @@ Opcode decoding uses special naming for bits and their decimal representations t \section{Conditional opcodes} Conditional opcodes are executed only when the condition described by their encoded conditional field has been met. -The groups of conditional instructions are: \Opcode{CALL}, \Opcode{JMP}, \Opcode{IF}, and \Opcode{RET}. +The groups of conditional instructions are: \Opcode{CALLcc}, \Opcode{Jcc}, \Opcode{IFcc}, and \Opcode{RETcc}. \begin{table}[H] \centering @@ -3750,149 +3750,178 @@ allow extending (8 lower bits of opcode not used by opcode). Extended opcodes do \section{Instructions sorted by opcode} - -\newcolumntype{T}{>{\ttfamily}l} +\newcommand{\OpcodeRow}[2]{\Opcode{#2} & \texttt{#1} & \pageref{instruction:#2} \\*} +\newcommand{\OpcodeRowUnk}[1]{Unknown & \texttt{#1} \\*} +\newcommand{\OpcodeRowSkip}[0]{\\} \begin{center} -\begin{longtable}{TllT} -NOP & & * & 0000 0000 0000 0000 \\ -DAR & & * & 0000 0000 0000 01aa \\ -IAR & & * & 0000 0000 0000 10aa \\ -XXX & NOT USED & & 0000 0000 0000 11xx \\ -ADDARN & & * & 0000 0000 0001 bbaa \\ -HALT & & * & 0000 0000 0010 0001 \\ - & & & \\ -LOOP & & * & 0000 0000 010r rrrr \\ -BLOOP & & * & 0000 0000 011r rrrr aaaa aaaa aaaa aaaa \\ - & & & \\ -LRI & & * & 0000 0000 100r rrrr iiii iiii iiii iiii \\ -XXX & NOT USED & * & 0000 0000 101x xxxx \\ -LR & & * & 0000 0000 110r rrrr mmmm mmmm mmmm mmmm \\ -SR & & * & 0000 0000 111r rrrr mmmm mmmm mmmm mmmm \\ - & & & \\ -IF cc & & * & 0000 0010 0111 cccc \\ -JMP cc & & * & 0000 0010 1001 cccc aaaa aaaa aaaa aaaa \\ -CALL cc & & * & 0000 0010 1011 cccc aaaa aaaa aaaa aaaa \\ -RET cc & & * & 0000 0010 1101 cccc \\ -RTI & & * & 0000 0010 1111 1111 \\ - & & & \\ -ADDI & & * & 0000 001r 0000 0000 iiii iiii iiii iiii \\ -XORI & & * & 0000 001r 0010 0000 iiii iiii iiii iiii \\ -ANDI & & * & 0000 001r 0100 0000 iiii iiii iiii iiii \\ -ORI & & * & 0000 001r 0110 0000 iiii iiii iiii iiii \\ -CMPI & & * & 0000 001r 1000 0000 iiii iiii iiii iiii \\ -ANDF & & * & 0000 001r 1010 0000 iiii iiii iiii iiii \\ -ANDCF & & * & 0000 001r 1100 0000 iiii iiii iiii iiii \\ - & & & \\ -ILRR & & * & 0000 001r 0001 00aa \\ -ILRRD & & * & 0000 001r 0001 01aa \\ -ILRRI & & * & 0000 001r 0001 10aa \\ -ILRRN & & * & 0000 001r 0001 11aa \\ - & & & \\ -ADDIS & & * & 0000 010d iiii iiii \\ -CMPIS & & * & 0000 011d iiii iiii \\ -LRIS & & * & 0000 1rrr iiii iiii \\ - & & & \\ -LOOPI & & * & 0001 0000 iiii iiii \\ -BLOOPI & & * & 0001 0001 iiii iiii aaaa aaaa aaaa aaaa \\ -SBCLR & & * & 0001 0010 ???? ?iii \\ -SBSET & & * & 0001 0011 ???? ?iii \\ -LSL/LSR & & * & 0001 010r 0sss ssss \\ -ASL/ASR & & * & 0001 010r 1sss ssss \\ -SI & & * & 0001 0110 iiii iiii mmmm mmmm mmmm mmmm \\ -CALLR & & * & 0001 0111 rrr1 1111 \\ -JMPR & & * & 0001 0111 rrr0 1111 \\ -LRR(I|D|X) & & * & 0001 100x xaar rrrr \\ -SRR(I|D|X) & & * & 0001 101x xaar rrrr \\ -MRR & & * & 0001 11dd ddds ssss \\ - & & & \\ -LRS & & * & 0010 0rrr mmmm mmmm \\ -SRS & & * & 0010 1rrr mmmm mmmm \\ - & & & \\ -XORR & & * & 0011 00sr xxxx xxxx \\ -ANDR & & * & 0011 01sr xxxx xxxx \\ -ORR & & * & 0011 10sr xxxx xxxx \\ -ANDC & & * & 0011 110r xxxx xxxx \\ -ORC & & * & 0011 111r xxxx xxxx \\ - & & & \\ -ADDR & & * & 0100 0ssd xxxx xxxx \\ -ADDAX & & * & 0100 10sd xxxx xxxx \\ -ADD & & * & 0100 110d xxxx xxxx \\ -ADDP & & * & 0100 111d xxxx xxxx \\ - & & & \\ -SUBR & & * & 0101 0ssd xxxx xxxx \\ -SUBAX & & * & 0101 10sd xxxx xxxx \\ -SUB & & * & 0101 110d xxxx xxxx \\ -SUBP & & * & 0101 111d xxxx xxxx \\ - & & & \\ -MOVR & & * & 0110 0ssd xxxx xxxx \\ -MOVAX & & * & 0110 10sd xxxx xxxx \\ -MOV & & * & 0110 110d xxxx xxxx \\ -MOVP & & * & 0110 111d xxxx xxxx \\ - & & & \\ -ADDAXL & & * & 0111 00sr xxxx xxxx \\ -INCM & & * & 0111 010r xxxx xxxx \\ -INC & & * & 0111 011r xxxx xxxx \\ -DECM & & * & 0111 100r xxxx xxxx \\ -DEC & & * & 0111 101r xxxx xxxx \\ -NEG & & * & 0111 110r xxxx xxxx \\ -MOVNP & & * & 0111 111r xxxx xxxx \\ - & & & \\ -NX & & * & 1000 x000 xxxx xxxx \\ -CLR & & * & 1000 x001 xxxx xxxx \\ -CMP & & * & 1000 0010 xxxx xxxx \\ -??? & UNUSED & * & 1000 0011 xxxx xxxx \\ -CLRP & & * & 1000 0100 xxxx xxxx \\ -TSTAXH & & * & 1000 011x xxxx xxxx \\ -M0/M2 & & & 1000 101x xxxx xxxx \\ -CLR15/SET15 & & & 1000 110x xxxx xxxx \\ -SET40/16 & & & 1000 111x xxxx xxxx \\ - & & & \\ -MUL & & * & 1001 a000 xxxx xxxx \\ -ASR16 & & * & 1001 r001 xxxx xxxx \\ -MULMVZ & & * & 1001 a01r xxxx xxxx \\ -MULAC & & * & 1001 a10r xxxx xxxx \\ -MULMV & & * & 1001 a11r xxxx xxxx \\ - & & & \\ -MULX & & * & 101b a000 xxxx xxxx \\ -??? & & & 1010 r001 xxxx xxxx \\ -TST & & & 1011 r001 xxxx xxxx \\ -MULXMVZ & & * & 101b a01r xxxx xxxx \\ -MULXAC & & * & 101b a10r xxxx xxxx \\ -MULXMV & & * & 101b a11r xxxx xxxx \\ - & & & \\ -MULC & & * & 110s a000 xxxx xxxx \\ -CMP & & * & 110x r001 xxxx xxxx \\ -MULCMVZ & & * & 110s a01r xxxx xxxx \\ -MULCAC & & * & 110s a10r xxxx xxxx \\ -MULCMV & & * & 110s a11r xxxx xxxx \\ - & & & \\ -MADDX & & ** & 1110 00st xxxx xxxx \\ -MSUBX & & ** & 1110 01st xxxx xxxx \\ -MADDC & & ** & 1110 10st xxxx xxxx \\ -MSUBC & & ** & 1110 11st xxxx xxxx \\ - & & & \\ -LSL16 & & * & 1111 000r xxxx xxxx \\ -MADD & & * & 1111 001s xxxx xxxx \\ -LSR16 & & * & 1111 010r xxxx xxxx \\ -MSUB & & * & 1111 011s xxxx xxxx \\ -ADDPAXZ & & * & 1111 10ar xxxx xxxx \\ -CLRL & & * & 1111 110r xxxx xxxx \\ -MOVPZ & & * & 1111 111r xxxx xxxx +\begin{longtable}{llr} +Instruction & Opcode & Page \\ \hline +\endhead +\OpcodeRow{0000 0000 0000 0000}{NOP} +\OpcodeRow{0000 0000 0000 01aa}{DAR} +\OpcodeRow{0000 0000 0000 10aa}{IAR} +\OpcodeRowUnk{0000 0000 0000 11xx} +\OpcodeRow{0000 0000 0001 bbaa}{ADDARN} +\OpcodeRow{0000 0000 0010 0001}{HALT} +\OpcodeRowSkip +\OpcodeRow{0000 0000 010r rrrr}{LOOP} +\OpcodeRow{0000 0000 011r rrrr aaaa aaaa aaaa aaaa}{BLOOP} +\OpcodeRowSkip +\OpcodeRow{0000 0000 100r rrrr iiii iiii iiii iiii}{LRI} +\OpcodeRowUnk{0000 0000 101x xxxx} +\OpcodeRow{0000 0000 110r rrrr mmmm mmmm mmmm mmmm}{LR} +\OpcodeRow{0000 0000 111r rrrr mmmm mmmm mmmm mmmm}{SR} +\OpcodeRowSkip +\OpcodeRow{0000 0010 0111 cccc}{IFcc} +\OpcodeRow{0000 0010 1001 cccc aaaa aaaa aaaa aaaa}{Jcc} +\OpcodeRow{0000 0010 1011 cccc aaaa aaaa aaaa aaaa}{CALLcc} +\OpcodeRow{0000 0010 1101 cccc}{RETcc} +\OpcodeRow{0000 0010 1111 1111}{RTI} +\OpcodeRowSkip +\OpcodeRow{0000 001r 0000 0000 iiii iiii iiii iiii}{ADDI} +\OpcodeRow{0000 001r 0010 0000 iiii iiii iiii iiii}{XORI} +\OpcodeRow{0000 001r 0100 0000 iiii iiii iiii iiii}{ANDI} +\OpcodeRow{0000 001r 0110 0000 iiii iiii iiii iiii}{ORI} +\OpcodeRow{0000 001r 1000 0000 iiii iiii iiii iiii}{CMPI} +\OpcodeRow{0000 001r 1010 0000 iiii iiii iiii iiii}{ANDF} +\OpcodeRow{0000 001r 1100 0000 iiii iiii iiii iiii}{ANDCF} +\OpcodeRowSkip +\OpcodeRow{0000 001r 0001 00aa}{ILRR} +\OpcodeRow{0000 001r 0001 01aa}{ILRRD} +\OpcodeRow{0000 001r 0001 10aa}{ILRRI} +\OpcodeRow{0000 001r 0001 11aa}{ILRRN} +\OpcodeRowSkip +\OpcodeRow{0000 010d iiii iiii}{ADDIS} +\OpcodeRow{0000 011d iiii iiii}{CMPIS} +\OpcodeRow{0000 1rrr iiii iiii}{LRIS} +\OpcodeRowSkip +\OpcodeRow{0001 0000 iiii iiii}{LOOPI} +\OpcodeRow{0001 0001 iiii iiii aaaa aaaa aaaa aaaa}{BLOOPI} +\OpcodeRow{0001 0010 xxxx xiii}{SBCLR} +\OpcodeRow{0001 0011 xxxx xiii}{SBSET} +\OpcodeRowSkip +\OpcodeRow{0001 010r 00ss ssss}{LSL} +\OpcodeRow{0001 010r 01ss ssss}{LSR} +\OpcodeRow{0001 010r 10ss ssss}{ASL} +\OpcodeRow{0001 010r 11ss ssss}{ASR} +\OpcodeRow{0001 0110 iiii iiii mmmm mmmm mmmm mmmm}{SI} +\OpcodeRow{0001 0111 rrr1 1111}{CALLR} +\OpcodeRow{0001 0111 rrr0 1111}{JMPR} +\OpcodeRowSkip +\OpcodeRow{0001 1000 0aar rrrr}{LRR} +\OpcodeRow{0001 1000 1aar rrrr}{LRRD} +\OpcodeRow{0001 1001 1aar rrrr}{LRRI} +\OpcodeRow{0001 1001 1aar rrrr}{LRRN} +\OpcodeRow{0001 1010 0aar rrrr}{SRR} +\OpcodeRow{0001 1010 1aar rrrr}{SRRD} +\OpcodeRow{0001 1011 0aar rrrr}{SRRI} +\OpcodeRow{0001 1011 1aar rrrr}{SRRN} +\OpcodeRow{0001 11dd ddds ssss}{MRR} +\OpcodeRowSkip +\OpcodeRow{0010 0rrr mmmm mmmm}{LRS} +\OpcodeRow{0010 1rrr mmmm mmmm}{SRS} +\OpcodeRowSkip +\OpcodeRow{0011 00sr xxxx xxxx}{XORR} +\OpcodeRow{0011 01sr xxxx xxxx}{ANDR} +\OpcodeRow{0011 10sr xxxx xxxx}{ORR} +\OpcodeRow{0011 110r xxxx xxxx}{ANDC} +\OpcodeRow{0011 111r xxxx xxxx}{ORC} +\OpcodeRowSkip +\OpcodeRow{0100 0ssd xxxx xxxx}{ADDR} +\OpcodeRow{0100 10sd xxxx xxxx}{ADDAX} +\OpcodeRow{0100 110d xxxx xxxx}{ADD} +\OpcodeRow{0100 111d xxxx xxxx}{ADDP} +\OpcodeRowSkip +\OpcodeRow{0101 0ssd xxxx xxxx}{SUBR} +\OpcodeRow{0101 10sd xxxx xxxx}{SUBAX} +\OpcodeRow{0101 110d xxxx xxxx}{SUB} +\OpcodeRow{0101 111d xxxx xxxx}{SUBP} +\OpcodeRowSkip +\OpcodeRow{0110 0ssd xxxx xxxx}{MOVR} +\OpcodeRow{0110 10sd xxxx xxxx}{MOVAX} +\OpcodeRow{0110 110d xxxx xxxx}{MOV} +\OpcodeRow{0110 111d xxxx xxxx}{MOVP} +\OpcodeRowSkip +\OpcodeRow{0111 00sr xxxx xxxx}{ADDAXL} +\OpcodeRow{0111 010r xxxx xxxx}{INCM} +\OpcodeRow{0111 011r xxxx xxxx}{INC} +\OpcodeRow{0111 100r xxxx xxxx}{DECM} +\OpcodeRow{0111 101r xxxx xxxx}{DEC} +\OpcodeRow{0111 110r xxxx xxxx}{NEG} +\OpcodeRow{0111 111r xxxx xxxx}{MOVNP} +\OpcodeRowSkip +\OpcodeRow{1000 x000 xxxx xxxx}{NX} +\OpcodeRow{1000 x001 xxxx xxxx}{CLR} +\OpcodeRow{1000 0010 xxxx xxxx}{CMP} +\OpcodeRowUnk{1000 0011 xxxx xxxx} +\OpcodeRow{1000 0100 xxxx xxxx}{CLRP} +\OpcodeRow{1000 011x xxxx xxxx}{TSTAXH} +\OpcodeRowSkip +\OpcodeRow{1000 1010 xxxx xxxx}{M2} +\OpcodeRow{1000 1011 xxxx xxxx}{M0} +\OpcodeRow{1000 1100 xxxx xxxx}{CLR15} +\OpcodeRow{1000 1101 xxxx xxxx}{SET15} +\OpcodeRow{1000 1110 xxxx xxxx}{SET16} +\OpcodeRow{1000 1111 xxxx xxxx}{SET40} +\OpcodeRowSkip +\OpcodeRow{1001 a000 xxxx xxxx}{MUL} +\OpcodeRow{1001 r001 xxxx xxxx}{ASR16} +\OpcodeRow{1001 a01r xxxx xxxx}{MULMVZ} +\OpcodeRow{1001 a10r xxxx xxxx}{MULAC} +\OpcodeRow{1001 a11r xxxx xxxx}{MULMV} +\OpcodeRowSkip +\OpcodeRow{101b a000 xxxx xxxx}{MULX} +\OpcodeRowUnk{1010 r001 xxxx xxxx} +\OpcodeRow{1011 r001 xxxx xxxx}{TST} +\OpcodeRow{101b a01r xxxx xxxx}{MULXMVZ} +\OpcodeRow{101b a10r xxxx xxxx}{MULXAC} +\OpcodeRow{101b a11r xxxx xxxx}{MULXMV} +\OpcodeRowSkip +\OpcodeRow{110s a000 xxxx xxxx}{MULC} +\OpcodeRow{110x r001 xxxx xxxx}{CMP} +\OpcodeRow{110s a01r xxxx xxxx}{MULCMVZ} +\OpcodeRow{110s a10r xxxx xxxx}{MULCAC} +\OpcodeRow{110s a11r xxxx xxxx}{MULCMV} +\OpcodeRowSkip +\OpcodeRow{1110 00st xxxx xxxx}{MADDX} +\OpcodeRow{1110 01st xxxx xxxx}{MSUBX} +\OpcodeRow{1110 10st xxxx xxxx}{MADDC} +\OpcodeRow{1110 11st xxxx xxxx}{MSUBC} +\OpcodeRowSkip +\OpcodeRow{1111 000r xxxx xxxx}{LSL16} +\OpcodeRow{1111 001s xxxx xxxx}{MADD} +\OpcodeRow{1111 010r xxxx xxxx}{LSR16} +\OpcodeRow{1111 011s xxxx xxxx}{MSUB} +\OpcodeRow{1111 10ar xxxx xxxx}{ADDPAXZ} +\OpcodeRow{1111 110r xxxx xxxx}{CLRL} +\OpcodeRow{1111 111r xxxx xxxx}{MOVPZ} \end{longtable} \end{center} \begin{center} Extension Opcodes -\begin{longtable}{TllT} -[D|I|N]R & & * & xxxx xxxx 0000 nnaa \\ -MV & & * & xxxx xxxx 0001 ddss \\ -S[N] & & * & xxxx xxxx 001r rnaa \\ -L[N] & & * & xxxx xxxx 01dd diss \\ -LS[NM|M|N] & & * & xxxx xxxx 10dd ba0r \\ -SL[NM|M|N] & & * & xxxx xxxx 10dd ba1r \\ -LD[NM|M|N] & & & xxxx xxxx 11mn barr \\ -LD2[NM|M|N] & & & xxxx xxxx 11rm ba11 +\begin{longtable}{llr} +Instruction & Opcode & Page \\ \hline +\OpcodeRow{xxxx xxxx 0000 01aa}{'DR} +\OpcodeRow{xxxx xxxx 0000 10aa}{'IR} +\OpcodeRow{xxxx xxxx 0000 11aa}{'NR} +\OpcodeRow{xxxx xxxx 0001 ddss}{'MV} +\OpcodeRow{xxxx xxxx 001r r0aa}{'S} +\OpcodeRow{xxxx xxxx 001r r1aa}{'SN} +\OpcodeRow{xxxx xxxx 01dd d0ss}{'L} +\OpcodeRow{xxxx xxxx 01dd d1ss}{'LN} +\OpcodeRowSkip +\OpcodeRow{xxxx xxxx 10dd 000r}{'LS} +\OpcodeRow{xxxx xxxx 10dd 001r}{'SL} +\OpcodeRow{xxxx xxxx 10dd 010r}{'LSN} +\OpcodeRow{xxxx xxxx 10dd 011r}{'SLN} +\OpcodeRow{xxxx xxxx 10dd 100r}{'LSM} +\OpcodeRow{xxxx xxxx 10dd 101r}{'SLM} +\OpcodeRow{xxxx xxxx 10dd 110r}{'LSNM} +\OpcodeRow{xxxx xxxx 10dd 111r}{'SLNM} +\OpcodeRow{xxxx xxxx 11mn barr}{'LD[NM|M|N]} +\OpcodeRow{xxxx xxxx 11rm ba11}{'LD2[NM|M|N]} \end{longtable} \end{center} From 446b1d2f13d98b32db8e0aef59ec29ae06bc2794 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 13 Jul 2021 15:13:18 -0700 Subject: [PATCH 18/49] docs/DSP: Adjust bit names in opcode table The old names did not match the ones used by the instructions themselves, and were generally fairly inconsistent. --- .../GameCube_DSP_Users_Manual.tex | 124 +++++++++--------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 95ad9ba75c..9784cfe725 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -3759,19 +3759,19 @@ allow extending (8 lower bits of opcode not used by opcode). Extended opcodes do Instruction & Opcode & Page \\ \hline \endhead \OpcodeRow{0000 0000 0000 0000}{NOP} -\OpcodeRow{0000 0000 0000 01aa}{DAR} -\OpcodeRow{0000 0000 0000 10aa}{IAR} +\OpcodeRow{0000 0000 0000 01dd}{DAR} +\OpcodeRow{0000 0000 0000 10dd}{IAR} \OpcodeRowUnk{0000 0000 0000 11xx} -\OpcodeRow{0000 0000 0001 bbaa}{ADDARN} +\OpcodeRow{0000 0000 0001 ssdd}{ADDARN} \OpcodeRow{0000 0000 0010 0001}{HALT} \OpcodeRowSkip \OpcodeRow{0000 0000 010r rrrr}{LOOP} \OpcodeRow{0000 0000 011r rrrr aaaa aaaa aaaa aaaa}{BLOOP} \OpcodeRowSkip -\OpcodeRow{0000 0000 100r rrrr iiii iiii iiii iiii}{LRI} +\OpcodeRow{0000 0000 100d dddd iiii iiii iiii iiii}{LRI} \OpcodeRowUnk{0000 0000 101x xxxx} -\OpcodeRow{0000 0000 110r rrrr mmmm mmmm mmmm mmmm}{LR} -\OpcodeRow{0000 0000 111r rrrr mmmm mmmm mmmm mmmm}{SR} +\OpcodeRow{0000 0000 110d dddd mmmm mmmm mmmm mmmm}{LR} +\OpcodeRow{0000 0000 111s ssss mmmm mmmm mmmm mmmm}{SR} \OpcodeRowSkip \OpcodeRow{0000 0010 0111 cccc}{IFcc} \OpcodeRow{0000 0010 1001 cccc aaaa aaaa aaaa aaaa}{Jcc} @@ -3787,40 +3787,40 @@ Instruction & Opcode & Page \\ \hline \OpcodeRow{0000 001r 1010 0000 iiii iiii iiii iiii}{ANDF} \OpcodeRow{0000 001r 1100 0000 iiii iiii iiii iiii}{ANDCF} \OpcodeRowSkip -\OpcodeRow{0000 001r 0001 00aa}{ILRR} -\OpcodeRow{0000 001r 0001 01aa}{ILRRD} -\OpcodeRow{0000 001r 0001 10aa}{ILRRI} -\OpcodeRow{0000 001r 0001 11aa}{ILRRN} +\OpcodeRow{0000 001d 0001 00ss}{ILRR} +\OpcodeRow{0000 001d 0001 01ss}{ILRRD} +\OpcodeRow{0000 001d 0001 10ss}{ILRRI} +\OpcodeRow{0000 001d 0001 11ss}{ILRRN} \OpcodeRowSkip \OpcodeRow{0000 010d iiii iiii}{ADDIS} \OpcodeRow{0000 011d iiii iiii}{CMPIS} -\OpcodeRow{0000 1rrr iiii iiii}{LRIS} +\OpcodeRow{0000 1ddd iiii iiii}{LRIS} \OpcodeRowSkip \OpcodeRow{0001 0000 iiii iiii}{LOOPI} \OpcodeRow{0001 0001 iiii iiii aaaa aaaa aaaa aaaa}{BLOOPI} \OpcodeRow{0001 0010 xxxx xiii}{SBCLR} \OpcodeRow{0001 0011 xxxx xiii}{SBSET} \OpcodeRowSkip -\OpcodeRow{0001 010r 00ss ssss}{LSL} -\OpcodeRow{0001 010r 01ss ssss}{LSR} -\OpcodeRow{0001 010r 10ss ssss}{ASL} -\OpcodeRow{0001 010r 11ss ssss}{ASR} -\OpcodeRow{0001 0110 iiii iiii mmmm mmmm mmmm mmmm}{SI} +\OpcodeRow{0001 010r 00ii iiii}{LSL} +\OpcodeRow{0001 010r 01ii iiii}{LSR} +\OpcodeRow{0001 010r 10ii iiii}{ASL} +\OpcodeRow{0001 010r 11ii iiii}{ASR} +\OpcodeRow{0001 0110 mmmm mmmm iiii iiii iiii iiii}{SI} \OpcodeRow{0001 0111 rrr1 1111}{CALLR} \OpcodeRow{0001 0111 rrr0 1111}{JMPR} \OpcodeRowSkip -\OpcodeRow{0001 1000 0aar rrrr}{LRR} -\OpcodeRow{0001 1000 1aar rrrr}{LRRD} -\OpcodeRow{0001 1001 1aar rrrr}{LRRI} -\OpcodeRow{0001 1001 1aar rrrr}{LRRN} -\OpcodeRow{0001 1010 0aar rrrr}{SRR} -\OpcodeRow{0001 1010 1aar rrrr}{SRRD} -\OpcodeRow{0001 1011 0aar rrrr}{SRRI} -\OpcodeRow{0001 1011 1aar rrrr}{SRRN} +\OpcodeRow{0001 1000 0ssd dddd}{LRR} +\OpcodeRow{0001 1000 1ssd dddd}{LRRD} +\OpcodeRow{0001 1001 0ssd dddd}{LRRI} +\OpcodeRow{0001 1001 1ssd dddd}{LRRN} +\OpcodeRow{0001 1010 0dds ssss}{SRR} +\OpcodeRow{0001 1010 1dds ssss}{SRRD} +\OpcodeRow{0001 1011 0dds ssss}{SRRI} +\OpcodeRow{0001 1011 1dds ssss}{SRRN} \OpcodeRow{0001 11dd ddds ssss}{MRR} \OpcodeRowSkip -\OpcodeRow{0010 0rrr mmmm mmmm}{LRS} -\OpcodeRow{0010 1rrr mmmm mmmm}{SRS} +\OpcodeRow{0010 0ddd mmmm mmmm}{LRS} +\OpcodeRow{0010 1sss mmmm mmmm}{SRS} \OpcodeRowSkip \OpcodeRow{0011 00sr xxxx xxxx}{XORR} \OpcodeRow{0011 01sr xxxx xxxx}{ANDR} @@ -3843,20 +3843,20 @@ Instruction & Opcode & Page \\ \hline \OpcodeRow{0110 110d xxxx xxxx}{MOV} \OpcodeRow{0110 111d xxxx xxxx}{MOVP} \OpcodeRowSkip -\OpcodeRow{0111 00sr xxxx xxxx}{ADDAXL} -\OpcodeRow{0111 010r xxxx xxxx}{INCM} -\OpcodeRow{0111 011r xxxx xxxx}{INC} -\OpcodeRow{0111 100r xxxx xxxx}{DECM} -\OpcodeRow{0111 101r xxxx xxxx}{DEC} -\OpcodeRow{0111 110r xxxx xxxx}{NEG} -\OpcodeRow{0111 111r xxxx xxxx}{MOVNP} +\OpcodeRow{0111 00sd xxxx xxxx}{ADDAXL} +\OpcodeRow{0111 010d xxxx xxxx}{INCM} +\OpcodeRow{0111 011d xxxx xxxx}{INC} +\OpcodeRow{0111 100d xxxx xxxx}{DECM} +\OpcodeRow{0111 101d xxxx xxxx}{DEC} +\OpcodeRow{0111 110d xxxx xxxx}{NEG} +\OpcodeRow{0111 111d xxxx xxxx}{MOVNP} \OpcodeRowSkip \OpcodeRow{1000 x000 xxxx xxxx}{NX} -\OpcodeRow{1000 x001 xxxx xxxx}{CLR} +\OpcodeRow{1000 r001 xxxx xxxx}{CLR} \OpcodeRow{1000 0010 xxxx xxxx}{CMP} \OpcodeRowUnk{1000 0011 xxxx xxxx} \OpcodeRow{1000 0100 xxxx xxxx}{CLRP} -\OpcodeRow{1000 011x xxxx xxxx}{TSTAXH} +\OpcodeRow{1000 011r xxxx xxxx}{TSTAXH} \OpcodeRowSkip \OpcodeRow{1000 1010 xxxx xxxx}{M2} \OpcodeRow{1000 1011 xxxx xxxx}{M0} @@ -3865,24 +3865,24 @@ Instruction & Opcode & Page \\ \hline \OpcodeRow{1000 1110 xxxx xxxx}{SET16} \OpcodeRow{1000 1111 xxxx xxxx}{SET40} \OpcodeRowSkip -\OpcodeRow{1001 a000 xxxx xxxx}{MUL} +\OpcodeRow{1001 s000 xxxx xxxx}{MUL} \OpcodeRow{1001 r001 xxxx xxxx}{ASR16} -\OpcodeRow{1001 a01r xxxx xxxx}{MULMVZ} -\OpcodeRow{1001 a10r xxxx xxxx}{MULAC} -\OpcodeRow{1001 a11r xxxx xxxx}{MULMV} +\OpcodeRow{1001 s01r xxxx xxxx}{MULMVZ} +\OpcodeRow{1001 s10r xxxx xxxx}{MULAC} +\OpcodeRow{1001 s11r xxxx xxxx}{MULMV} \OpcodeRowSkip -\OpcodeRow{101b a000 xxxx xxxx}{MULX} +\OpcodeRow{101s t000 xxxx xxxx}{MULX} \OpcodeRowUnk{1010 r001 xxxx xxxx} \OpcodeRow{1011 r001 xxxx xxxx}{TST} -\OpcodeRow{101b a01r xxxx xxxx}{MULXMVZ} -\OpcodeRow{101b a10r xxxx xxxx}{MULXAC} -\OpcodeRow{101b a11r xxxx xxxx}{MULXMV} +\OpcodeRow{101s t01r xxxx xxxx}{MULXMVZ} +\OpcodeRow{101s t10r xxxx xxxx}{MULXAC} +\OpcodeRow{101s t11r xxxx xxxx}{MULXMV} \OpcodeRowSkip -\OpcodeRow{110s a000 xxxx xxxx}{MULC} +\OpcodeRow{110s t000 xxxx xxxx}{MULC} \OpcodeRow{110x r001 xxxx xxxx}{CMP} -\OpcodeRow{110s a01r xxxx xxxx}{MULCMVZ} -\OpcodeRow{110s a10r xxxx xxxx}{MULCAC} -\OpcodeRow{110s a11r xxxx xxxx}{MULCMV} +\OpcodeRow{110s t01r xxxx xxxx}{MULCMVZ} +\OpcodeRow{110s t10r xxxx xxxx}{MULCAC} +\OpcodeRow{110s t11r xxxx xxxx}{MULCMV} \OpcodeRowSkip \OpcodeRow{1110 00st xxxx xxxx}{MADDX} \OpcodeRow{1110 01st xxxx xxxx}{MSUBX} @@ -3893,9 +3893,9 @@ Instruction & Opcode & Page \\ \hline \OpcodeRow{1111 001s xxxx xxxx}{MADD} \OpcodeRow{1111 010r xxxx xxxx}{LSR16} \OpcodeRow{1111 011s xxxx xxxx}{MSUB} -\OpcodeRow{1111 10ar xxxx xxxx}{ADDPAXZ} +\OpcodeRow{1111 10sd xxxx xxxx}{ADDPAXZ} \OpcodeRow{1111 110r xxxx xxxx}{CLRL} -\OpcodeRow{1111 111r xxxx xxxx}{MOVPZ} +\OpcodeRow{1111 111d xxxx xxxx}{MOVPZ} \end{longtable} \end{center} @@ -3903,23 +3903,23 @@ Instruction & Opcode & Page \\ \hline Extension Opcodes \begin{longtable}{llr} Instruction & Opcode & Page \\ \hline -\OpcodeRow{xxxx xxxx 0000 01aa}{'DR} -\OpcodeRow{xxxx xxxx 0000 10aa}{'IR} -\OpcodeRow{xxxx xxxx 0000 11aa}{'NR} +\OpcodeRow{xxxx xxxx 0000 01rr}{'DR} +\OpcodeRow{xxxx xxxx 0000 10rr}{'IR} +\OpcodeRow{xxxx xxxx 0000 11rr}{'NR} \OpcodeRow{xxxx xxxx 0001 ddss}{'MV} -\OpcodeRow{xxxx xxxx 001r r0aa}{'S} -\OpcodeRow{xxxx xxxx 001r r1aa}{'SN} +\OpcodeRow{xxxx xxxx 001s s0dd}{'S} +\OpcodeRow{xxxx xxxx 001s s1dd}{'SN} \OpcodeRow{xxxx xxxx 01dd d0ss}{'L} \OpcodeRow{xxxx xxxx 01dd d1ss}{'LN} \OpcodeRowSkip -\OpcodeRow{xxxx xxxx 10dd 000r}{'LS} -\OpcodeRow{xxxx xxxx 10dd 001r}{'SL} -\OpcodeRow{xxxx xxxx 10dd 010r}{'LSN} -\OpcodeRow{xxxx xxxx 10dd 011r}{'SLN} -\OpcodeRow{xxxx xxxx 10dd 100r}{'LSM} -\OpcodeRow{xxxx xxxx 10dd 101r}{'SLM} -\OpcodeRow{xxxx xxxx 10dd 110r}{'LSNM} -\OpcodeRow{xxxx xxxx 10dd 111r}{'SLNM} +\OpcodeRow{xxxx xxxx 10dd 000s}{'LS} +\OpcodeRow{xxxx xxxx 10dd 001s}{'SL} +\OpcodeRow{xxxx xxxx 10dd 010s}{'LSN} +\OpcodeRow{xxxx xxxx 10dd 011s}{'SLN} +\OpcodeRow{xxxx xxxx 10dd 100s}{'LSM} +\OpcodeRow{xxxx xxxx 10dd 101s}{'SLM} +\OpcodeRow{xxxx xxxx 10dd 110s}{'LSNM} +\OpcodeRow{xxxx xxxx 10dd 111s}{'SLNM} \OpcodeRow{xxxx xxxx 11mn barr}{'LD[NM|M|N]} \OpcodeRow{xxxx xxxx 11rm ba11}{'LD2[NM|M|N]} \end{longtable} From 211c2b5d99e48966c816ff59554976d511cc09ea Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 13 Jul 2021 15:45:50 -0700 Subject: [PATCH 19/49] docs/DSP: Add most missing instructions These instructions were already implememented by Dolphin, but never added to the manual. Extension instructions will be handled in a later commit, as wlil instructions that were not previously implememented by Dolphin. --- .../Core/DSP/Interpreter/DSPIntArithmetic.cpp | 3 +- .../Core/DSP/Jit/x64/DSPJitArithmetic.cpp | 3 +- .../GameCube_DSP_Users_Manual.tex | 358 +++++++++++++++++- 3 files changed, 353 insertions(+), 11 deletions(-) diff --git a/Source/Core/Core/DSP/Interpreter/DSPIntArithmetic.cpp b/Source/Core/Core/DSP/Interpreter/DSPIntArithmetic.cpp index a0a8a2022f..18a48413b3 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPIntArithmetic.cpp +++ b/Source/Core/Core/DSP/Interpreter/DSPIntArithmetic.cpp @@ -126,8 +126,7 @@ void Interpreter::cmp(const UDSPInstruction) // CMPAR $acS axR.h // 110r s001 xxxx xxxx -// Compares accumulator $acS with accumulator axR.h. -// Not described by Duddie's doc - at least not as a separate instruction. +// Compares accumulator $acS with accumulator $axR.h. // // flags out: x-xx xxxx void Interpreter::cmpar(const UDSPInstruction opc) diff --git a/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp b/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp index 1acce79df6..7f2da96c37 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp @@ -185,8 +185,7 @@ void DSPEmitter::cmp(const UDSPInstruction opc) // CMPAR $acS axR.h // 110r s001 xxxx xxxx -// Compares accumulator $acS with accumulator axR.h. -// Not described by Duddie's doc - at least not as a separate instruction. +// Compares accumulator $acS with accumulator $axR.h. // // flags out: x-xx xxxx void DSPEmitter::cmpar(const UDSPInstruction opc) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 9784cfe725..77d8bd6415 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -1005,7 +1005,7 @@ Opcode decoding uses special naming for bits and their decimal representations t \section{Conditional opcodes} Conditional opcodes are executed only when the condition described by their encoded conditional field has been met. -The groups of conditional instructions are: \Opcode{CALLcc}, \Opcode{Jcc}, \Opcode{IFcc}, and \Opcode{RETcc}. +The groups of conditional instructions are: \Opcode{CALLcc}, \Opcode{Jcc}, \Opcode{IFcc}, \Opcode{RETcc}, \Opcode{JRcc}, and \Opcode{CALLRcc}. \begin{table}[H] \centering @@ -1042,6 +1042,28 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \pagebreak{} +\begin{DSPOpcode}{ABS} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{1010} & \monobitbox{4}{d001} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + ABS $acD + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Sets \Register{\$acD} to the absolute value of \Register{\$acD}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + IF $acD < 0 + $acD = -$acD + ENDIF + FLAGS($acD) + $pc++ + \end{DSPOpcodeOperation} +\end{DSPOpcode} + \begin{DSPOpcode}{ADD} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{0100} & \monobitbox{4}{110d} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} @@ -1377,6 +1399,32 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{ASRN} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{0000} & \monobitbox{4}{0010} & \monobitbox{4}{1101} & \monobitbox{4}{1011} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + ASRN + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Arithmetically shifts accumulator \Register{\$ac0} either left or right based on \Register{\$ac1.m}: if bit 6 is set, a right by the amount calculated by negating sign-extended bits 0--5 occurs, while if bit 6 is clear, a left shift occurs by bits 0--5. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + IF (ac1.m & 64) + IF (ac1.m & 63) != 0 + $ac0 >>= (64 - (ac1.m & 63)) + ENDIF + ELSE + $ac0 <<= ac1.m + ENDIF + FLAGS($ac0) + $pc++ + \end{DSPOpcodeOperation} +\end{DSPOpcode} + \begin{DSPOpcode}{ASR16} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{1001} & \monobitbox{4}{r001} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} @@ -1541,6 +1589,55 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{CALLRcc} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{0001} & \monobitbox{4}{0111} & \monobitbox{4}{rrr1} & \monobitbox{4}{cccc} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + CALLRcc $R + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Call function if condition \Flag{cc} has been met. Push program counter of the instruction following ``call'' to call stack \Register{\$st0}. + Set program counter to register \Register{\$R}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + IF (cc) + PUSH_STACK($st0) + $st0 = $pc + 1 + $pc = $R + ELSE + $pc++ + ENDIF + \end{DSPOpcodeOperation} +\end{DSPOpcode} + + +\begin{DSPOpcode}{CLR15} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{1000} & \monobitbox{4}{1100} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + CLR15 + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Sets \RegisterField{\$sr.SU} (bit 15) to 0, causing multiplication to treat its operands as signed. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $sr &= ~0x8000 + $pc++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeSeeAlso} + \item \Opcode{SET15} + \end{DSPOpcodeSeeAlso} +\end{DSPOpcode} + \begin{DSPOpcode}{CLR} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{1000} & \monobitbox{4}{r001} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} @@ -1629,6 +1726,25 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{CMPAR} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{110r} & \monobitbox{4}{s001} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + CMPAR $acS $axR.h + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Compares accumulator \Register{\$acS} with accumulator \Register{\$axR.h}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $sr = FLAGS($acS - ($axR.h << 16)) + $pc++ + \end{DSPOpcodeOperation} +\end{DSPOpcode} + \begin{DSPOpcode}{CMPI} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{0000} & \monobitbox{4}{001r} & \monobitbox{4}{1000} & \monobitbox{4}{0000} \\ @@ -1975,6 +2091,28 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{JRcc} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{0001} & \monobitbox{4}{0111} & \monobitbox{4}{rrr0} & \monobitbox{4}{cccc} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + JRcc $R + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Jump to address if condition \Flag{cc} has been met; set program counter to a value from register \Register{\$R}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + IF (cc) + $pc = $R + ELSE + $pc++ + ENDIF + \end{DSPOpcodeOperation} +\end{DSPOpcode} + \begin{DSPOpcode}{LOOP} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{0000} & \monobitbox{4}{0000} & \monobitbox{4}{010r} & \monobitbox{4}{rrrr} @@ -2251,6 +2389,32 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{LSRN} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{0000} & \monobitbox{4}{0010} & \monobitbox{4}{1100} & \monobitbox{4}{1010} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + LSRN + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Logically shifts accumulator \Register{\$ac0} either left or right based on \Register{\$ac1.m}: if bit 6 is set, a right by the amount calculated by negating sign-extended bits 0--5 occurs, while if bit 6 is clear, a left shift occurs by bits 0--5. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + IF (ac1.m & 64) + IF (ac1.m & 63) != 0 + $ac0 >>= (64 - (ac1.m & 63)) + ENDIF + ELSE + $ac0 <<= ac1.m + ENDIF + FLAGS($ac0) + $pc++ + \end{DSPOpcodeOperation} +\end{DSPOpcode} + \begin{DSPOpcode}{LSR16} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{1111} & \monobitbox{4}{010r} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} @@ -2271,6 +2435,52 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{M0} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{1000} & \monobitbox{4}{1011} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + M0 + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Sets \RegisterField{\$sr.AM} (bit 13) to 1, \textbf{disabling} the functionality that doubles the result of every multiply operation. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $sr |= 0x2000 + $pc++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeSeeAlso} + \item \Opcode{M2} + \end{DSPOpcodeSeeAlso} +\end{DSPOpcode} + +\begin{DSPOpcode}{M2} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{1000} & \monobitbox{4}{1010} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + M2 + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Sets \RegisterField{\$sr.AM} (bit 13) to 0, \textbf{enabling} the functionality that doubles the result of every multiply operation. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $sr &= ~0x2000 + $pc++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeSeeAlso} + \item \Opcode{M0} + \end{DSPOpcodeSeeAlso} +\end{DSPOpcode} + \begin{DSPOpcode}{MADD} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{1111} & \monobitbox{4}{001s} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} @@ -2608,6 +2818,29 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeSeeAlso} \end{DSPOpcode} +\begin{DSPOpcode}{MULAXH} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{1000} & \monobitbox{4}{0011} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + MULAXH + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Multiplies \Register{\$ax0.h} by itself. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $prod = $ax0.h * $ax0.h + $pc++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeSeeAlso} + \item \RegisterField{\$sr.AM} bit affects multiply result. + \end{DSPOpcodeSeeAlso} +\end{DSPOpcode} + \begin{DSPOpcode}{MULC} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{110s} & \monobitbox{4}{t000} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} @@ -3095,6 +3328,75 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{SET15} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{1000} & \monobitbox{4}{1101} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + SET15 + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Sets \RegisterField{\$sr.SU} (bit 15) to 1, causing multiplication to treat its operands as unsigned. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $sr |= 0x8000 + $pc++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeSeeAlso} + \item \Opcode{CLR15} + \end{DSPOpcodeSeeAlso} +\end{DSPOpcode} + +\begin{DSPOpcode}{SET16} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{1000} & \monobitbox{4}{1110} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + SET16 + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Sets \RegisterField{\$sr.SXM} (bit 14) to 0, resulting in 16-bit sign extension. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $sr &= ~0x4000 + $pc++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeSeeAlso} + \item \Opcode{SET40} + \end{DSPOpcodeSeeAlso} +\end{DSPOpcode} + +\begin{DSPOpcode}{SET40} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{1000} & \monobitbox{4}{1111} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + SET40 + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Sets \RegisterField{\$sr.SXM} (bit 14) to 1, resulting in 40-bit sign extension. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $sr |= 0x4000 + $pc++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeSeeAlso} + \item \Opcode{SET16} + \end{DSPOpcodeSeeAlso} +\end{DSPOpcode} + \begin{DSPOpcode}{SI} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{0001} & \monobitbox{4}{0110} & \monobitbox{4}{mmmm} & \monobitbox{4}{mmmm} \\ @@ -3260,6 +3562,25 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{SUBARN} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{0000} & \monobitbox{4}{0000} & \monobitbox{4}{0000} & \monobitbox{4}{11dd} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + SUBARN $arD + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Subtracts indexing register \Register{\$ixD} from addressing register \Register{\$arD}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $arD -= $ixD + $pc++ + \end{DSPOpcodeOperation} +\end{DSPOpcode} + \begin{DSPOpcode}{SUBAX} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{0101} & \monobitbox{4}{10sd} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} @@ -3358,6 +3679,25 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{TSTPROD} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{1000} & \monobitbox{4}{0101} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + TSTPROD + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Test the product register \Register{\$prod}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + FLAGS($prod) + $pc++ + \end{DSPOpcodeOperation} +\end{DSPOpcode} + \begin{DSPOpcode}{XORI} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{0000} & \monobitbox{4}{001r} & \monobitbox{4}{0010} & \monobitbox{4}{0000} \\ @@ -3761,7 +4101,7 @@ Instruction & Opcode & Page \\ \hline \OpcodeRow{0000 0000 0000 0000}{NOP} \OpcodeRow{0000 0000 0000 01dd}{DAR} \OpcodeRow{0000 0000 0000 10dd}{IAR} -\OpcodeRowUnk{0000 0000 0000 11xx} +\OpcodeRow{0000 0000 0000 11dd}{SUBARN} \OpcodeRow{0000 0000 0001 ssdd}{ADDARN} \OpcodeRow{0000 0000 0010 0001}{HALT} \OpcodeRowSkip @@ -3787,6 +4127,9 @@ Instruction & Opcode & Page \\ \hline \OpcodeRow{0000 001r 1010 0000 iiii iiii iiii iiii}{ANDF} \OpcodeRow{0000 001r 1100 0000 iiii iiii iiii iiii}{ANDCF} \OpcodeRowSkip +\OpcodeRow{0000 0010 1100 1010}{LSRN} +\OpcodeRow{0000 0010 1100 1011}{ASRN} +\OpcodeRowSkip \OpcodeRow{0000 001d 0001 00ss}{ILRR} \OpcodeRow{0000 001d 0001 01ss}{ILRRD} \OpcodeRow{0000 001d 0001 10ss}{ILRRI} @@ -3806,8 +4149,8 @@ Instruction & Opcode & Page \\ \hline \OpcodeRow{0001 010r 10ii iiii}{ASL} \OpcodeRow{0001 010r 11ii iiii}{ASR} \OpcodeRow{0001 0110 mmmm mmmm iiii iiii iiii iiii}{SI} -\OpcodeRow{0001 0111 rrr1 1111}{CALLR} -\OpcodeRow{0001 0111 rrr0 1111}{JMPR} +\OpcodeRow{0001 0111 rrr0 cccc}{JRcc} +\OpcodeRow{0001 0111 rrr1 cccc}{CALLRcc} \OpcodeRowSkip \OpcodeRow{0001 1000 0ssd dddd}{LRR} \OpcodeRow{0001 1000 1ssd dddd}{LRRD} @@ -3854,8 +4197,9 @@ Instruction & Opcode & Page \\ \hline \OpcodeRow{1000 x000 xxxx xxxx}{NX} \OpcodeRow{1000 r001 xxxx xxxx}{CLR} \OpcodeRow{1000 0010 xxxx xxxx}{CMP} -\OpcodeRowUnk{1000 0011 xxxx xxxx} +\OpcodeRow{1000 0011 xxxx xxxx}{MULAXH} \OpcodeRow{1000 0100 xxxx xxxx}{CLRP} +\OpcodeRow{1000 0101 xxxx xxxx}{TSTPROD} \OpcodeRow{1000 011r xxxx xxxx}{TSTAXH} \OpcodeRowSkip \OpcodeRow{1000 1010 xxxx xxxx}{M2} @@ -3872,14 +4216,14 @@ Instruction & Opcode & Page \\ \hline \OpcodeRow{1001 s11r xxxx xxxx}{MULMV} \OpcodeRowSkip \OpcodeRow{101s t000 xxxx xxxx}{MULX} -\OpcodeRowUnk{1010 r001 xxxx xxxx} +\OpcodeRow{1010 d001 xxxx xxxx}{ABS} \OpcodeRow{1011 r001 xxxx xxxx}{TST} \OpcodeRow{101s t01r xxxx xxxx}{MULXMVZ} \OpcodeRow{101s t10r xxxx xxxx}{MULXAC} \OpcodeRow{101s t11r xxxx xxxx}{MULXMV} \OpcodeRowSkip \OpcodeRow{110s t000 xxxx xxxx}{MULC} -\OpcodeRow{110x r001 xxxx xxxx}{CMP} +\OpcodeRow{110r s001 xxxx xxxx}{CMPAR} \OpcodeRow{110s t01r xxxx xxxx}{MULCMVZ} \OpcodeRow{110s t10r xxxx xxxx}{MULCAC} \OpcodeRow{110s t11r xxxx xxxx}{MULCMV} From 031621bf51e1624db5f3d1f036e677414c6868f4 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Thu, 12 Aug 2021 11:47:57 -0700 Subject: [PATCH 20/49] docs/DSP: Document behavior and instructions when the first nybble is 3 --- .../GameCube_DSP_Users_Manual.tex | 225 +++++++++++++++++- 1 file changed, 212 insertions(+), 13 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 77d8bd6415..4e8c55a1df 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -178,7 +178,7 @@ { } -% Environment for describing a not for a DSP opcode +% Environment for describing a note for a DSP opcode \newenvironment{DSPOpcodeNote} { \textbf{Note:} @@ -1248,7 +1248,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcode}{ANDC} \begin{DSPOpcodeBytefield}{16} - \monobitbox{4}{0011} & \monobitbox{4}{110d} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \monobitbox{4}{0011} & \monobitbox{4}{110d} & \monobitbox{4}{0xxx} & \monobitbox{4}{xxxx} \end{DSPOpcodeBytefield} \begin{DSPOpcodeFormat} @@ -1264,6 +1264,10 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). + \end{DSPOpcodeNote} \end{DSPOpcode} \begin{DSPOpcode}{ANDCF} @@ -1341,7 +1345,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcode}{ANDR} \begin{DSPOpcodeBytefield}{16} - \monobitbox{4}{0011} & \monobitbox{4}{01sd} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \monobitbox{4}{0011} & \monobitbox{4}{01sd} & \monobitbox{4}{0xxx} & \monobitbox{4}{xxxx} \end{DSPOpcodeBytefield} \begin{DSPOpcodeFormat} @@ -1357,6 +1361,10 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). + \end{DSPOpcodeNote} \end{DSPOpcode} \begin{DSPOpcode}{ASL} @@ -1425,6 +1433,66 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{ASRNR} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{0011} & \monobitbox{4}{111d} & \monobitbox{4}{1xxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + ASRNR $acD + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Arithmetically shifts accumulator \Register{\$acD} either left or right based on \Register{\$ac(1-D).m}: if bit 6 is set, a right by the amount calculated by negating sign-extended bits 0--5 occurs, while if bit 6 is clear, a left shift occurs by bits 0--5. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + IF (ac(1-D).m & 64) + IF (ac(1-D).m & 63) != 0 + $acD >>= (64 - (ac(1-D).m & 63)) + ENDIF + ELSE + $acD <<= ac(1-D).m + ENDIF + FLAGS($acD) + $pc++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). + \end{DSPOpcodeNote} +\end{DSPOpcode} + +\begin{DSPOpcode}{ASRNRX} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{0011} & \monobitbox{4}{10sd} & \monobitbox{4}{1xxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + ASRNRX $acD, $axS.h + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Arithmetically shifts accumulator \Register{\$acD} either left or right based on \Register{\$axS.h}: if bit 6 is set, a right by the amount calculated by negating sign-extended bits 0--5 occurs, while if bit 6 is clear, a left shift occurs by bits 0--5. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + IF (axS.h & 64) + IF (axS.h & 63) != 0 + $acD >>= (64 - (axS.h & 63)) + ENDIF + ELSE + $acD <<= axS.h + ENDIF + FLAGS($acD) + $pc++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). + \end{DSPOpcodeNote} +\end{DSPOpcode} + \begin{DSPOpcode}{ASR16} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{1001} & \monobitbox{4}{r001} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} @@ -2415,6 +2483,66 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{LSRNR} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{0011} & \monobitbox{4}{110d} & \monobitbox{4}{1xxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + LSRNR $acD + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Logically shifts accumulator \Register{\$acD} either left or right based on \Register{\$ac(1-D).m}: if bit 6 is set, a right by the amount calculated by negating sign-extended bits 0--5 occurs, while if bit 6 is clear, a left shift occurs by bits 0--5. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + IF (ac(1-D).m & 64) + IF (ac(1-D).m & 63) != 0 + $acD >>= (64 - (ac(1-D).m & 63)) + ENDIF + ELSE + $acD <<= ac(1-D).m + ENDIF + FLAGS($acD) + $pc++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). + \end{DSPOpcodeNote} +\end{DSPOpcode} + +\begin{DSPOpcode}{LSRNRX} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{0011} & \monobitbox{4}{01sd} & \monobitbox{4}{1xxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + LSRNRX $acD, $axS.h + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Logically shifts accumulator \Register{\$acD} either left or right based on \Register{\$axS.h}: if bit 6 is set, a right by the amount calculated by negating sign-extended bits 0--5 occurs, while if bit 6 is clear, a left shift occurs by bits 0--5. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + IF (axS.h & 64) + IF (axS.h & 63) != 0 + $acD >>= (64 - (axS.h & 63)) + ENDIF + ELSE + $acD <<= axS.h + ENDIF + FLAGS($acD) + $pc++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). + \end{DSPOpcodeNote} +\end{DSPOpcode} + \begin{DSPOpcode}{LSR16} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{1111} & \monobitbox{4}{010r} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} @@ -3129,6 +3257,30 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{NOT} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{0011} & \monobitbox{4}{001d} & \monobitbox{4}{1xxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + NOT $acD.m + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Invert all bits in the middle part of accumulator \Register{\$acD.m} (i.e. XOR with \Value{0xffff}). + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $acD.m = ~acD.m + FLAGS($acD) + $pc++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). + \end{DSPOpcodeNote} +\end{DSPOpcode} + \begin{DSPOpcode}{NOP} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{0000} & \monobitbox{4}{0000} & \monobitbox{4}{0000} & \monobitbox{4}{0000} @@ -3167,7 +3319,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcode}{ORC} \begin{DSPOpcodeBytefield}{16} - \monobitbox{4}{0011} & \monobitbox{4}{111d} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \monobitbox{4}{0011} & \monobitbox{4}{111d} & \monobitbox{4}{0xxx} & \monobitbox{4}{xxxx} \end{DSPOpcodeBytefield} \begin{DSPOpcodeFormat} @@ -3183,6 +3335,10 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). + \end{DSPOpcodeNote} \end{DSPOpcode} \begin{DSPOpcode}{ORI} @@ -3208,7 +3364,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcode}{ORR} \begin{DSPOpcodeBytefield}{16} - \monobitbox{4}{0011} & \monobitbox{4}{10sd} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \monobitbox{4}{0011} & \monobitbox{4}{10sd} & \monobitbox{4}{0xxx} & \monobitbox{4}{xxxx} \end{DSPOpcodeBytefield} \begin{DSPOpcodeFormat} @@ -3224,6 +3380,10 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). + \end{DSPOpcodeNote} \end{DSPOpcode} \begin{DSPOpcode}{RET} @@ -3698,6 +3858,30 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{XORC} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{0011} & \monobitbox{4}{000d} & \monobitbox{4}{1xxx} & \monobitbox{4}{xxxx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + XORC $acD.m, $ac(1-D).m + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Logical XOR (exclusive OR) middle part of accumulator \Register{\$acD.m} with middle part of accumulator \Register{\$ac(1-D).m}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $acD.m ^= $ac(1-D).m + FLAGS($acD) + $pc++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). + \end{DSPOpcodeNote} +\end{DSPOpcode} + \begin{DSPOpcode}{XORI} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{0000} & \monobitbox{4}{001r} & \monobitbox{4}{0010} & \monobitbox{4}{0000} \\ @@ -3721,7 +3905,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcode}{XORR} \begin{DSPOpcodeBytefield}{16} - \monobitbox{4}{0011} & \monobitbox{4}{00sd} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \monobitbox{4}{0011} & \monobitbox{4}{00sd} & \monobitbox{4}{0xxx} & \monobitbox{4}{xxxx} \end{DSPOpcodeBytefield} \begin{DSPOpcodeFormat} @@ -3737,12 +3921,20 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). + \end{DSPOpcodeNote} \end{DSPOpcode} \section{Extended opcodes} -Extended opcodes do not exist on their own. These opcodes can only be attached to opcodes that -allow extending (8 lower bits of opcode not used by opcode). Extended opcodes do not modify the program counter (\Register{\$pc} register). +Extended opcodes do not exist on their own. These opcodes can only be attached to opcodes that allow extending. +Specifically, opcodes where the first nybble is 0, 1, or 2 cannot be extended. +Opcodes where the first nybble is 4 or higher can be extended, using the 8 lower bits. +Opcodes where the first nybble is 3 can also be extended, but the main opcode is 9 bits and the extension opcode is 7 bits. For these instructions, the extension opcode is treated as if the first bit were 0 (i.e. \texttt{0xxxxxxx}). + +Extended opcodes do not modify the program counter (\Register{\$pc} register). \pagebreak{} @@ -4165,11 +4357,18 @@ Instruction & Opcode & Page \\ \hline \OpcodeRow{0010 0ddd mmmm mmmm}{LRS} \OpcodeRow{0010 1sss mmmm mmmm}{SRS} \OpcodeRowSkip -\OpcodeRow{0011 00sr xxxx xxxx}{XORR} -\OpcodeRow{0011 01sr xxxx xxxx}{ANDR} -\OpcodeRow{0011 10sr xxxx xxxx}{ORR} -\OpcodeRow{0011 110r xxxx xxxx}{ANDC} -\OpcodeRow{0011 111r xxxx xxxx}{ORC} +\OpcodeRow{0011 00sd 0xxx xxxx}{XORR} +\OpcodeRow{0011 01sd 0xxx xxxx}{ANDR} +\OpcodeRow{0011 10sd 0xxx xxxx}{ORR} +\OpcodeRow{0011 110d 0xxx xxxx}{ANDC} +\OpcodeRow{0011 111d 0xxx xxxx}{ORC} +\OpcodeRowSkip +\OpcodeRow{0011 000d 1xxx xxxx}{XORC} +\OpcodeRow{0011 001d 1xxx xxxx}{NOT} +\OpcodeRow{0011 01sd 1xxx xxxx}{LSRNRX} +\OpcodeRow{0011 10sd 1xxx xxxx}{ASRNRX} +\OpcodeRow{0011 110d 1xxx xxxx}{LSRNR} +\OpcodeRow{0011 111d 1xxx xxxx}{ASRNR} \OpcodeRowSkip \OpcodeRow{0100 0ssd xxxx xxxx}{ADDR} \OpcodeRow{0100 10sd xxxx xxxx}{ADDAX} From 29b61d463e62db44ce3888acd9f120e3083c8275 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Thu, 12 Aug 2021 15:34:15 -0700 Subject: [PATCH 21/49] docs/DSP: Document 'LD and 'LDAX --- .../GameCube_DSP_Users_Manual.tex | 231 +++++++++++++++++- 1 file changed, 229 insertions(+), 2 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 4e8c55a1df..7430f6bff2 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -4018,6 +4018,224 @@ Extended opcodes do not modify the program counter (\Register{\$pc} register). \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{'LD} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} & \monobitbox{4}{11dr} & \monobitbox{4}{00ss} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + 'LD $ax0.D, $ax1.R, @$arS + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Load register \Register{\$ax0.D} (either \Register{\$ax0.l} or \Register{\$ax0.h}, as \Register{\$(0x18+D*2)}) with value from memory pointed by register \Register{\$arS}. + Load register \Register{\$ax1.R} (either \Register{\$ax1.l} or \Register{\$ax1.h}, as \Register{\$(0x19+R*2)}) with value from memory pointed by register \Register{\$ar3}. + Increment both \Register{\$arS} and \Register{\$ar3}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $ax0.D = MEM[$arS] + $ax1.R = MEM[$ar3] + $arS++ + $ar3++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item \texttt{S} cannot be 3, as that instead encodes \Opcode{'LDAX}. Thus, \Register{\$arS} is guaranteed to be distinct from \Register{\$ar3}. + \end{DSPOpcodeNote} +\end{DSPOpcode} + +\begin{DSPOpcode}{'LDM} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} & \monobitbox{4}{11dr} & \monobitbox{4}{10ss} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + 'LDM $ax0.D, $ax1.R, @$arS + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Load register \Register{\$ax0.D} (either \Register{\$ax0.l} or \Register{\$ax0.h}, as \Register{\$(0x18+D*2)}) with value from memory pointed by register \Register{\$arS}. + Load register \Register{\$ax1.R} (either \Register{\$ax1.l} or \Register{\$ax1.h}, as \Register{\$(0x19+R*2)}) with value from memory pointed by register \Register{\$ar3}. + Add corresponding indexing register \Register{\$ix3} to addressing register \Register{\$ar3} and increment \Register{\$arS}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $ax0.D = MEM[$arS] + $ax1.R = MEM[$ar3] + $arS++ + $ar3 += $ix3 + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item \texttt{S} cannot be 3, as that instead encodes \Opcode{'LDAXM}. Thus, \Register{\$arS} is guaranteed to be distinct from \Register{\$ar3}. + \end{DSPOpcodeNote} +\end{DSPOpcode} + +\begin{DSPOpcode}{'LDNM} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} & \monobitbox{4}{11dr} & \monobitbox{4}{11ss} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + 'LDNM $ax0.D, $ax1.R, @$arS + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Load register \Register{\$ax0.D} (either \Register{\$ax0.l} or \Register{\$ax0.h}, as \Register{\$(0x18+D*2)}) with value from memory pointed by register \Register{\$arS}. + Load register \Register{\$ax1.R} (either \Register{\$ax1.l} or \Register{\$ax1.h}, as \Register{\$(0x19+R*2)}) with value from memory pointed by register \Register{\$ar3}. + Add corresponding indexing register \Register{\$ixS} to addressing register \Register{\$arS} and add corresponding + indexing register \Register{\$ix3} to addressing register \Register{\$ar3}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $ax0.D = MEM[$arS] + $ax1.R = MEM[$ar3] + $arS += $ixS + $ar3 += $ix3 + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item \texttt{S} cannot be 3, as that instead encodes \Opcode{'LDAXNM}. Thus, \Register{\$arS} is guaranteed to be distinct from \Register{\$ar3}. + \end{DSPOpcodeNote} +\end{DSPOpcode} + +\begin{DSPOpcode}{'LDN} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} & \monobitbox{4}{11dr} & \monobitbox{4}{01ss} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + 'LDN $ax0.D, $ax1.R, @$arS + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Load register \Register{\$ax0.D} (either \Register{\$ax0.l} or \Register{\$ax0.h}, as \Register{\$(0x18+D*2)}) with value from memory pointed by register \Register{\$arS}. + Load register \Register{\$ax1.R} (either \Register{\$ax1.l} or \Register{\$ax1.h}, as \Register{\$(0x19+R*2)}) with value from memory pointed by register \Register{\$ar3}. + Add corresponding indexing register \Register{\$ixS} to addressing register \Register{\$arS} and increment \Register{\$ar3}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $ax0.D = MEM[$arS] + $ax1.R = MEM[$ar3] + $arS += $ixS + $ar3++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item \texttt{S} cannot be 3, as that instead encodes \Opcode{'LDAXN}. Thus, \Register{\$arS} is guaranteed to be distinct from \Register{\$ar3}. + \end{DSPOpcodeNote} +\end{DSPOpcode} + +\begin{DSPOpcode}{'LDAX} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} & \monobitbox{4}{11sr} & \monobitbox{4}{0011} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + 'LDAX $axR, @$arS + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Load register \Register{\$axR.h} with value from memory pointed by register \Register{\$arS}. + Load register \Register{\$axR.l} with value from memory pointed by register \Register{\$ar3}. + Increment both \Register{\$arS} and \Register{\$ar3}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $axR.h = MEM[$arS] + $axR.l = MEM[$ar3] + $arS++ + $ar3++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item \texttt{S} can be either 0 or 1, corresponding to \Register{\$ar0} or \Register{\$ar1}. Thus, \Register{\$arS} is guaranteed to be distinct from \Register{\$ar3}. \Register{\$ar2} cannot be used with this instruction. + \end{DSPOpcodeNote} +\end{DSPOpcode} + +\begin{DSPOpcode}{'LDAXM} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} & \monobitbox{4}{11sr} & \monobitbox{4}{0011} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + 'LDAXM $axR, @$arS + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Load register \Register{\$axR.h} with value from memory pointed by register \Register{\$arS}. + Load register \Register{\$axR.l} with value from memory pointed by register \Register{\$ar3}. + Add corresponding indexing register \Register{\$ix3} to addressing register \Register{\$ar3} and increment \Register{\$arS}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $axR.h = MEM[$arS] + $axR.l = MEM[$ar3] + $arS++ + $ar3 += $ix3 + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item \texttt{S} can be either 0 or 1, corresponding to \Register{\$ar0} or \Register{\$ar1}. Thus, \Register{\$arS} is guaranteed to be distinct from \Register{\$ar3}. \Register{\$ar2} cannot be used with this instruction. + \end{DSPOpcodeNote} +\end{DSPOpcode} + +\begin{DSPOpcode}{'LDAXNM} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} & \monobitbox{4}{11sr} & \monobitbox{4}{0011} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + 'LDAXNM $axR, @$arS + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Load register \Register{\$axR.h} with value from memory pointed by register \Register{\$arS}. + Load register \Register{\$axR.l} with value from memory pointed by register \Register{\$ar3}. + Add corresponding indexing register \Register{\$ixS} to addressing register \Register{\$arS} and add corresponding + indexing register \Register{\$ix3} to addressing register \Register{\$ar3}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $axR.h = MEM[$arS] + $axR.l = MEM[$ar3] + $arS += $ixS + $ar3 += $ix3 + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item \texttt{S} can be either 0 or 1, corresponding to \Register{\$ar0} or \Register{\$ar1}. Thus, \Register{\$arS} is guaranteed to be distinct from \Register{\$ar3}. \Register{\$ar2} cannot be used with this instruction. + \end{DSPOpcodeNote} +\end{DSPOpcode} + +\begin{DSPOpcode}{'LDAXN} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} & \monobitbox{4}{11sr} & \monobitbox{4}{0011} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + 'LDAXN $axR, @$arS + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Load register \Register{\$axR.h} with value from memory pointed by register \Register{\$arS}. + Load register \Register{\$axR.l} with value from memory pointed by register \Register{\$ar3}. + Add corresponding indexing register \Register{\$ixS} to addressing register \Register{\$arS} and increment \Register{\$ar3}. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + $axR.h = MEM[$arS] + $axR.l = MEM[$ar3] + $arS += $ixS + $ar3++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item \texttt{S} can be either 0 or 1, corresponding to \Register{\$ar0} or \Register{\$ar1}. Thus, \Register{\$arS} is guaranteed to be distinct from \Register{\$ar3}. \Register{\$ar2} cannot be used with this instruction. + \end{DSPOpcodeNote} +\end{DSPOpcode} + \begin{DSPOpcode}{'LS} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} & \monobitbox{4}{01dd} & \monobitbox{4}{d1ss} @@ -4442,6 +4660,8 @@ Instruction & Opcode & Page \\ \hline \end{longtable} \end{center} +\pagebreak + \begin{center} Extension Opcodes \begin{longtable}{llr} @@ -4463,8 +4683,15 @@ Instruction & Opcode & Page \\ \hline \OpcodeRow{xxxx xxxx 10dd 101s}{'SLM} \OpcodeRow{xxxx xxxx 10dd 110s}{'LSNM} \OpcodeRow{xxxx xxxx 10dd 111s}{'SLNM} -\OpcodeRow{xxxx xxxx 11mn barr}{'LD[NM|M|N]} -\OpcodeRow{xxxx xxxx 11rm ba11}{'LD2[NM|M|N]} +\OpcodeRowSkip +\OpcodeRow{xxxx xxxx 11dr 00ss}{'LD} +\OpcodeRow{xxxx xxxx 11sr 0011}{'LDAX} +\OpcodeRow{xxxx xxxx 11dr 01ss}{'LDN} +\OpcodeRow{xxxx xxxx 11sr 0111}{'LDAXN} +\OpcodeRow{xxxx xxxx 11dr 10ss}{'LDM} +\OpcodeRow{xxxx xxxx 11sr 1011}{'LDAXM} +\OpcodeRow{xxxx xxxx 11dr 11ss}{'LDNM} +\OpcodeRow{xxxx xxxx 11dr 1111}{'LDAXNM} \end{longtable} \end{center} From 1bcea561e9a020b2a3642923b6a38d7b7fccd94b Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Fri, 13 Aug 2021 10:41:30 -0700 Subject: [PATCH 22/49] docs/DSP: Add 'NOP --- .../GameCube_DSP_Users_Manual.tex | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 7430f6bff2..23f04f8324 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -4347,6 +4347,24 @@ Extended opcodes do not modify the program counter (\Register{\$pc} register). \end{DSPOpcodeOperation} \end{DSPOpcode} +\begin{DSPOpcode}{'NOP} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} & \monobitbox{4}{0000} & \monobitbox{4}{00xx} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + 'NOP + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item No operation. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeNote} + \item Generally written as by not including any extension operation, such as writing \texttt{INC \$ac0} instead of writing \texttt{INC'NOP \$ac0}. + \end{DSPOpcodeNote} +\end{DSPOpcode} + \begin{DSPOpcode}{'NR} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} & \monobitbox{4}{0000} & \monobitbox{4}{11rr} @@ -4666,6 +4684,7 @@ Instruction & Opcode & Page \\ \hline Extension Opcodes \begin{longtable}{llr} Instruction & Opcode & Page \\ \hline +\OpcodeRow{xxxx xxxx 0000 00xx}{'NOP} \OpcodeRow{xxxx xxxx 0000 01rr}{'DR} \OpcodeRow{xxxx xxxx 0000 10rr}{'IR} \OpcodeRow{xxxx xxxx 0000 11rr}{'NR} From 79664d419cbf98be1cd0585ac5912f295ca43926 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Fri, 13 Aug 2021 11:44:52 -0700 Subject: [PATCH 23/49] docs/DSP: Document rounding behavior of CLRL --- .../GameCube_DSP_Users_Manual.tex | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 23f04f8324..74d3a30901 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -1736,14 +1736,22 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Clears \Register{\$acR.l} - low 16 bits of accumulator \Register{\$acR}. + \item Rounds \Register{\$acR} such that \Register{\$acR.l} is 0. This is a round-to-even operation. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - $acR.l = 0 + IF ($acR & 0x10000) != 0 + $acR = ($acR + 0x8000) & ~0xffff + ELSE + $acR = ($acR + 0x7fff) & ~0xffff + ENDIF FLAGS($acR) $pc++ \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item An alternative interpretation is that if \Register{\$acR.m} is odd, then increment \Register{\$acsR} if \Register{\$acR.l} is greater than or equal to \Value{0x8000}; if \Register{\$acR.m} is even, then increment \Register{\$acsR} if \Register{\$acR.l} is greater than or equal to \Value{0x7fff}. Afterwards set \Register{\$acR.l} to 0. + \end{DSPOpcodeNote} \end{DSPOpcode} \begin{DSPOpcode}{CLRP} From 8881ecef19b3e182c23f80b29dadeddd36851766 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Fri, 13 Aug 2021 12:17:09 -0700 Subject: [PATCH 24/49] docs/DSP: Adjust operation for CMPI and CMPIS This more clearly indicates what it is supposed to do. --- .../GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 74d3a30901..68ff49ff7f 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -1837,8 +1837,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - res = ($acD.hm - I) | $acD.l - FLAGS(res) + FLAGS($acD - (I << 16)) $pc += 2 \end{DSPOpcodeOperation} \end{DSPOpcode} @@ -1858,7 +1857,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - FLAGS($acD - #I) + FLAGS($acD - (I << 16)) $pc++ \end{DSPOpcodeOperation} \end{DSPOpcode} From 953670b0578410581ae455d288e55ec4c89bd78d Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Fri, 13 Aug 2021 13:07:25 -0700 Subject: [PATCH 25/49] docs/DSP: Fix operation of ADDR and SUBR --- .../GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 68ff49ff7f..2f7c4f2df9 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -1240,7 +1240,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - $acD += $(0x18+S) + $acD += ($(0x18+S) << 16) FLAGS($acD) $pc++ \end{DSPOpcodeOperation} @@ -3802,7 +3802,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - $acD -= $(0x18+S) + $acD -= ($(0x18+S) << 16) FLAGS($acD) $pc++ \end{DSPOpcodeOperation} From 2eb791d5e118f57a103898f466cfd13542894f03 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Fri, 13 Aug 2021 13:15:58 -0700 Subject: [PATCH 26/49] docs/DSP: Note that ADDAXL is unsigned --- docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 2f7c4f2df9..7358d2bf2a 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -1134,6 +1134,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcodeDescription} \item Adds secondary accumulator \Register{\$axS.l} to accumulator register \Register{\$acD}. + \Register{\$axS.l} is treated as an unsigned value. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} From 332bb6fd55c4551b643326f53a44d2517372c7e0 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Fri, 13 Aug 2021 14:00:27 -0700 Subject: [PATCH 27/49] docs/DSP: Fix operation for LSR/ASR --- .../GameCube_DSP_Users_Manual.tex | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 7358d2bf2a..ddf49380f7 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -1402,7 +1402,9 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - $acR >>= I + IF I != 0 + $acR >>= (64 - I) + ENDIF FLAGS($acD) $pc++ \end{DSPOpcodeOperation} @@ -2459,7 +2461,9 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - $acR >>= I + IF I != 0 + $acR >>= (64 - I) + ENDIF FLAGS($acD) $pc++ \end{DSPOpcodeOperation} From 8767df40e516e1487f10f4933955e2730018cf72 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Fri, 13 Aug 2021 14:04:31 -0700 Subject: [PATCH 28/49] docs/DSP: Fix acD/acR conflation in shift instructions --- .../GameCube_DSP_Users_Manual.tex | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index ddf49380f7..8a6790de42 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -1383,7 +1383,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcodeOperation} $acR <<= I - FLAGS($acD) + FLAGS($acR) $pc++ \end{DSPOpcodeOperation} \end{DSPOpcode} @@ -1405,7 +1405,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a IF I != 0 $acR >>= (64 - I) ENDIF - FLAGS($acD) + FLAGS($acR) $pc++ \end{DSPOpcodeOperation} \end{DSPOpcode} @@ -1511,7 +1511,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcodeOperation} $acR >>= 16 - FLAGS($acD) + FLAGS($acR) $pc++ \end{DSPOpcodeOperation} \end{DSPOpcode} @@ -2422,7 +2422,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcodeOperation} $acR <<= I - FLAGS($acD) + FLAGS($acR) $pc++ \end{DSPOpcodeOperation} \end{DSPOpcode} @@ -2442,7 +2442,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcodeOperation} $acR <<= 16 - FLAGS($acD) + FLAGS($acR) $pc++ \end{DSPOpcodeOperation} \end{DSPOpcode} @@ -2464,7 +2464,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a IF I != 0 $acR >>= (64 - I) ENDIF - FLAGS($acD) + FLAGS($acR) $pc++ \end{DSPOpcodeOperation} \end{DSPOpcode} @@ -2570,7 +2570,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcodeOperation} $acR >>= 16 - FLAGS($acD) + FLAGS($acR) $pc++ \end{DSPOpcodeOperation} \end{DSPOpcode} From 139e05800f3f04f769ba858051e3f911200247bd Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 13 Jul 2021 15:11:05 -0700 Subject: [PATCH 29/49] docs/DSP: Fix 'LS encoding The old encoding was a copy of 'LN. --- .../DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 8a6790de42..aa4cb5c09b 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -4250,7 +4250,7 @@ Extended opcodes do not modify the program counter (\Register{\$pc} register). \begin{DSPOpcode}{'LS} \begin{DSPOpcodeBytefield}{16} - \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} & \monobitbox{4}{01dd} & \monobitbox{4}{d1ss} + \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} & \monobitbox{4}{10dd} & \monobitbox{4}{000s} \end{DSPOpcodeBytefield} \begin{DSPOpcodeFormat} From 2db2683ea9c86d3cbd137f31c378f799d28d7403 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Fri, 13 Aug 2021 16:32:19 -0700 Subject: [PATCH 30/49] docs/DSP: Fix 'S format --- .../DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index aa4cb5c09b..f9e8bbf181 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -4401,7 +4401,7 @@ Extended opcodes do not modify the program counter (\Register{\$pc} register). \end{DSPOpcodeBytefield} \begin{DSPOpcodeFormat} - 'S @$D, $(0x1c+S) + 'S @$arD, $(0x1c+S) \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} From a8ec0ad27f69fe81b3a59255ab319f1666310e87 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Fri, 13 Aug 2021 21:01:34 -0700 Subject: [PATCH 31/49] docs/DSP: Fix MULXAC bytes The previous encoding was for MULXMVZ. --- .../DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index f9e8bbf181..7b875a0e79 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -3168,7 +3168,7 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \begin{DSPOpcode}{MULXAC} \begin{DSPOpcodeBytefield}{16} - \monobitbox{4}{101s} & \monobitbox{4}{t01r} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} + \monobitbox{4}{101s} & \monobitbox{4}{t10r} & \monobitbox{4}{xxxx} & \monobitbox{4}{xxxx} \end{DSPOpcodeBytefield} \begin{DSPOpcodeFormat} From 9249454f332f6706a8fdae8756248cf9af0f8ccd Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sat, 21 Aug 2021 17:05:53 -0700 Subject: [PATCH 32/49] docs/DSP: Document overflow and carry behavior --- .../GameCube_DSP_Users_Manual.tex | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 7b875a0e79..b8e536c389 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -1038,6 +1038,16 @@ There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} a \pagebreak{} +\section{Flags} + +Most opcodes update flags in the status register (\Register{\$sr}) based on their result. (Extended opcodes do not update flags.) + +Overflow (\texttt{O}) occurs when the result has wrapped around. The expression $C = A + B$ has overflown if $A > 0$ and $B > 0$ but $C \le 0$ or if $A < 0$ and $B < 0$ but $C \ge 0$. Any instruction that sets the \texttt{O} flag will also set the \texttt{OS} flag; when the \texttt{O} flag is set, \texttt{OS} is also set, but \texttt{OS} is not cleared when \texttt{O} is cleared. + +Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to the next most significant word. The expression $C = A + B$ generates a carry if $A > C$. The DSP uses different logic for subtraction: the expression $C = A - B$ generates a carry if $A \ge C$ (so if $B = 0$, a carry is generated for all $A$). This is because the DSP uses a carry flag, not a borrow flag. + +\pagebreak{} + \section{Alphabetical list of opcodes} \pagebreak{} From 0796fada17f11a62ab1a807de7044789716865d8 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Fri, 13 Aug 2021 21:45:32 -0700 Subject: [PATCH 33/49] docs/DSP: Add information about flags for every instruction --- .../GameCube_DSP_Users_Manual.tex | 285 +++++++++++++++++- 1 file changed, 283 insertions(+), 2 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index b8e536c389..ac83235e14 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -198,6 +198,23 @@ \end{description} } +% Command to show flags. +\newcommand{\DSPOpcodeFlags}[8] +{ + \textbf{Flags:} + \begin{description} + \item \begin{tabular}{|c|c|c|c|c|c|c|c|} + \hline + OS & LZ & TB & S32 & S & AZ & O & C \\ + \hline + #1 & #2 & #3 & #4 & #5 & #6 & #7 & #8 \\ + \hline + \end{tabular} + \end{description} +} + +\newcommand{\DSPOpcodeFlagsUnchanged}[0]{\DSPOpcodeFlags{-}{-}{-}{-}{-}{-}{-}{-}} + \makeatother \begin{document} \maketitle{} @@ -536,8 +553,8 @@ Furthermore, it also contains control bits to configure the flow of certain oper \texttt{9} & \texttt{IE} & Interrupt enable \\ \hline \texttt{8} & \texttt{0} & Hardwired to 0? \\ \hline \texttt{7} & \texttt{OS} & Overflow (sticky) \\ \hline -\texttt{6} & \texttt{LZ} & Logic zero \\ \hline -\texttt{5} & & Top two bits are equal \\ \hline +\texttt{6} & \texttt{LZ} & Logic zero (used by \Opcode{ANDCF} and \Opcode{ANDF}) \\ \hline +\texttt{5} & \texttt{TB} & Top two bits are equal \\ \hline \texttt{4} & \texttt{AS} & Above s32 \\ \hline \texttt{3} & \texttt{S} & Sign \\ \hline \texttt{2} & \texttt{Z} & Arithmetic zero \\ \hline @@ -1046,6 +1063,12 @@ Overflow (\texttt{O}) occurs when the result has wrapped around. The expression Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to the next most significant word. The expression $C = A + B$ generates a carry if $A > C$. The DSP uses different logic for subtraction: the expression $C = A - B$ generates a carry if $A \ge C$ (so if $B = 0$, a carry is generated for all $A$). This is because the DSP uses a carry flag, not a borrow flag. +Each instruction has a table showing what flags it updates, such as this: + +\DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} + +A ``-'' indicates that the flag retains its previous value, a ``0'' indicates that the flag is set to 0, and a ``X'' indicates that the value of the flag changes depending on what the instruction did. + \pagebreak{} \section{Alphabetical list of opcodes} @@ -1072,6 +1095,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{ADD} @@ -1092,6 +1117,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{ADDARN} @@ -1111,6 +1138,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $arD += $ixS $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{ADDAX} @@ -1131,6 +1160,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{ADDAXL} @@ -1152,6 +1183,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{ADDI} @@ -1173,6 +1206,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc += 2 \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{ADDIS} @@ -1193,6 +1228,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{ADDP} @@ -1213,6 +1250,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{ADDPAXZ} @@ -1235,6 +1274,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{ADDR} @@ -1255,6 +1296,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{ANDC} @@ -1279,6 +1322,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeNote} \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). \end{DSPOpcodeNote} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{ANDCF} @@ -1305,6 +1350,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to ENDIF $pc += 2 \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{X}{-}{-}{-}{-}{-}{-} \end{DSPOpcode} \begin{DSPOpcode}{ANDF} @@ -1331,6 +1378,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to ENDIF $pc += 2 \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{X}{-}{-}{-}{-}{-}{-} \end{DSPOpcode} \begin{DSPOpcode}{ANDI} @@ -1352,6 +1401,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc += 2 \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{ANDR} @@ -1376,6 +1427,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeNote} \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). \end{DSPOpcodeNote} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{ASL} @@ -1396,6 +1449,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acR) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{ASR} @@ -1418,6 +1473,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acR) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{ASRN} @@ -1444,6 +1501,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($ac0) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{ASRNR} @@ -1474,6 +1533,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeNote} \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). \end{DSPOpcodeNote} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{ASRNRX} @@ -1504,6 +1565,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeNote} \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). \end{DSPOpcodeNote} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{ASR16} @@ -1524,6 +1587,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acR) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{BLOOP} @@ -1560,6 +1625,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $pc = addrA + 1 // Remove values from stack \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{BLOOPI} @@ -1596,6 +1663,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $pc = addrA + 1 // Remove values from stack \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{CALL} @@ -1619,6 +1688,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $st0 = $pc + 2 $pc = addressA \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{CALLcc} @@ -1647,6 +1718,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $pc += 2 ENDIF \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{CALLR} @@ -1668,6 +1741,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $st0 = $pc + 1 $pc = $R \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{CALLRcc} @@ -1693,6 +1768,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $pc++ ENDIF \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} @@ -1717,6 +1794,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \Opcode{SET15} \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{CLR} @@ -1737,6 +1816,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acR) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{1}{0}{0}{1}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{CLRL} @@ -1765,6 +1846,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeNote} \item An alternative interpretation is that if \Register{\$acR.m} is odd, then increment \Register{\$acsR} if \Register{\$acR.l} is greater than or equal to \Value{0x8000}; if \Register{\$acR.m} is even, then increment \Register{\$acsR} if \Register{\$acR.l} is greater than or equal to \Value{0x7fff}. Afterwards set \Register{\$acR.l} to 0. \end{DSPOpcodeNote} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{CLRP} @@ -1794,6 +1877,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $prod.m2 = 0x0010 \end{lstlisting} \end{DSPOpcodeNote} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{CMP} @@ -1813,6 +1898,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $sr = FLAGS($ac0 - $ac1) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{CMPAR} @@ -1832,6 +1919,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $sr = FLAGS($acS - ($axR.h << 16)) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{CMPI} @@ -1853,6 +1942,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD - (I << 16)) $pc += 2 \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{CMPIS} @@ -1873,6 +1964,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD - (I << 16)) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{DAR} @@ -1892,6 +1985,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $arD-- $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{DEC} @@ -1912,6 +2007,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{DECM} @@ -1932,6 +2029,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{HALT} @@ -1950,6 +2049,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeOperation} DREG_CR |= DSP_CR_HALT; \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{IAR} @@ -1969,6 +2070,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $arD++ $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{IFcc} @@ -1991,6 +2094,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $pc += 2 ENDIF \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{ILRR} @@ -2011,6 +2116,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $acD.m = MEM[$arS] $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{ILRRD} @@ -2032,6 +2139,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $arS-- $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{ILRRI} @@ -2053,6 +2162,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $arS++ $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{ILRRN} @@ -2075,6 +2186,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $arS += $ixS $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{INC} @@ -2095,6 +2208,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{INCM} @@ -2115,6 +2230,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{JMP} @@ -2135,6 +2252,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeOperation} $pc = addressA \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{Jcc} @@ -2159,6 +2278,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $pc += 2 ENDIF \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{JMPR} @@ -2177,6 +2298,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeOperation} $pc = $R \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{JRcc} @@ -2199,6 +2322,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $pc++ ENDIF \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{LOOP} @@ -2223,6 +2348,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to END $pc += 2 \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{LOOPI} @@ -2247,6 +2374,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to END $pc += 2 \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{LR} @@ -2268,6 +2397,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $D = MEM[M] $pc += 2 \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{LRI} @@ -2289,6 +2420,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $D = I $pc += 2 \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{LRIS} @@ -2309,6 +2442,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $(0x18+D) = I $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{LRR} @@ -2329,6 +2464,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $D = MEM[$arS] $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{LRRD} @@ -2351,6 +2488,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $arS-- $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{LRRI} @@ -2373,6 +2512,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $arS++ $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{LRRN} @@ -2395,6 +2536,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $arS += $ixS $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{LRS} @@ -2415,6 +2558,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $(0x18+D) = MEM[M] $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{LSL} @@ -2435,6 +2580,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acR) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{LSL16} @@ -2455,6 +2602,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acR) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{LSR} @@ -2477,6 +2626,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acR) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{LSRN} @@ -2503,6 +2654,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($ac0) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{LSRNR} @@ -2533,6 +2686,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeNote} \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). \end{DSPOpcodeNote} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{LSRNRX} @@ -2563,6 +2718,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeNote} \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). \end{DSPOpcodeNote} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{LSR16} @@ -2583,6 +2740,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acR) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{M0} @@ -2606,6 +2765,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \Opcode{M2} \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{M2} @@ -2629,6 +2790,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \Opcode{M0} \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{MADD} @@ -2653,6 +2816,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{MADDC} @@ -2677,6 +2842,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{MADDX} @@ -2701,6 +2868,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{MOV} @@ -2721,6 +2890,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{0}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{MOVAX} @@ -2741,6 +2912,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{MOVNP} @@ -2761,6 +2934,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{MOVP} @@ -2781,6 +2956,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{MOVPZ} @@ -2802,6 +2979,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{MOVR} @@ -2823,6 +3002,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{MRR} @@ -2843,6 +3024,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $D = $S $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{MSUB} @@ -2868,6 +3051,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{MSUBC} @@ -2892,6 +3077,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{MSUBX} @@ -2916,6 +3103,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{MUL} @@ -2940,6 +3129,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{MULAC} @@ -2966,6 +3157,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{MULAXH} @@ -2989,6 +3182,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{MULC} @@ -3013,6 +3208,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{MULCAC} @@ -3040,6 +3237,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{MULCMV} @@ -3067,6 +3266,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{MULCMVZ} @@ -3096,6 +3297,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{MULMV} @@ -3122,6 +3325,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{MULMVZ} @@ -3150,6 +3355,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{MULX} @@ -3174,6 +3381,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{MULXAC} @@ -3201,6 +3410,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{MULXMV} @@ -3228,6 +3439,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{MULXMVZ} @@ -3257,6 +3470,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \RegisterField{\$sr.AM} bit affects multiply result. \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{NEG} @@ -3277,6 +3492,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{NOT} @@ -3301,6 +3518,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeNote} \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). \end{DSPOpcodeNote} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{NOP} @@ -3319,6 +3538,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeOperation} $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{NX} @@ -3337,6 +3558,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeOperation} $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{ORC} @@ -3361,6 +3584,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeNote} \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). \end{DSPOpcodeNote} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{ORI} @@ -3382,6 +3607,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc += 2 \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{ORR} @@ -3406,6 +3633,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeNote} \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). \end{DSPOpcodeNote} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{RET} @@ -3425,6 +3654,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $pc = $st0 POP_STACK($st0) \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{RETcc} @@ -3448,6 +3679,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $pc += 2 ENDIF \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{RTI} @@ -3470,6 +3703,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $pc = $st0 POP_STACK($st0) \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{SBCLR} @@ -3489,6 +3724,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $sr &= ~(1 << (I + 6)) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{SBSET} @@ -3508,6 +3745,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $sr |= 1 << (I + 6) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{SET15} @@ -3531,6 +3770,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \Opcode{CLR15} \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{SET16} @@ -3554,6 +3795,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \Opcode{SET40} \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{SET40} @@ -3577,6 +3820,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeSeeAlso} \item \Opcode{SET16} \end{DSPOpcodeSeeAlso} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{SI} @@ -3597,6 +3842,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to MEM[M] = I $pc += 2 \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{SR} @@ -3618,6 +3865,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to MEM[M] = $S $pc += 2 \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{SRR} @@ -3638,6 +3887,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to MEM[$arD] = $S $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{SRRD} @@ -3659,6 +3910,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $arD-- $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{SRRI} @@ -3680,6 +3933,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $arD++ $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{SRRN} @@ -3702,6 +3957,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $arD += $ixD $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{SRS} @@ -3722,6 +3979,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to MEM[M] = $(0x18+S) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{SUB} @@ -3742,6 +4001,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{SUBARN} @@ -3761,6 +4022,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to $arD -= $ixD $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} \begin{DSPOpcode}{SUBAX} @@ -3781,6 +4044,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{SUBP} @@ -3801,6 +4066,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{SUBR} @@ -3821,6 +4088,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{TST} @@ -3840,6 +4109,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acR) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{TSTAXH} @@ -3859,6 +4130,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($axR.h) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{0}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{TSTPROD} @@ -3878,6 +4151,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($prod) $pc++ \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{0}{X}{X}{0}{X} \end{DSPOpcode} \begin{DSPOpcode}{XORC} @@ -3902,6 +4177,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeNote} \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). \end{DSPOpcodeNote} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{XORI} @@ -3923,6 +4200,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to FLAGS($acD) $pc += 2 \end{DSPOpcodeOperation} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \begin{DSPOpcode}{XORR} @@ -3947,6 +4226,8 @@ Carry (\texttt{C}) occurs when an arithmetic carry occurs and should be added to \begin{DSPOpcodeNote} \item The main opcode is 9 bits and the extension opcode is 7 bits. The extension opcode is treated as if the 8th bit was 0 (i.e. it is \texttt{0xxxxxxx}). \end{DSPOpcodeNote} + + \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} \end{DSPOpcode} \section{Extended opcodes} From be753e5a4528ba7532f1405519578bded12f094d Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 13 Jul 2021 15:15:21 -0700 Subject: [PATCH 34/49] docs/DSP: MADDC operates on acS.m, not acS.l This matches the prose and Dolphin's implementation. --- .../GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index ac83235e14..67ff7bc72b 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -2826,7 +2826,7 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \end{DSPOpcodeBytefield} \begin{DSPOpcodeFormat} - MADDC $acS.l, $axT.h + MADDC $acS.m, $axT.h \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} @@ -2835,7 +2835,7 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - $prod += $acS.l * $axT.h + $prod += $acS.m * $axT.h $pc++ \end{DSPOpcodeOperation} From 7c645e1865ba65394c9b96450ef4c9d815e9fe6d Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 13 Jul 2021 15:15:57 -0700 Subject: [PATCH 35/49] docs/DSP: Fix registers used by MOVAX and MOV --- .../GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 67ff7bc72b..2e1401d6d7 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -2882,11 +2882,11 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Moves accumulator \Register{\$ax(1-D)} to accumulator \Register{\$axD}. + \item Moves accumulator \Register{\$ac(1-D)} to accumulator \Register{\$acD}. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - $acD = $ax(1-D) + $acD = $ac(1-D) FLAGS($acD) $pc++ \end{DSPOpcodeOperation} @@ -2904,7 +2904,7 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Moves secondary accumulator \Register{\$axS} to accumulator \Register{\$axD}. + \item Moves secondary accumulator \Register{\$axS} to accumulator \Register{\$acD}. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} From 8fa649e1d64baacc5dc0b474e6fc914c7e348fe9 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sat, 14 Aug 2021 17:34:24 -0700 Subject: [PATCH 36/49] docs/DSP: Document masking/sign extension behavior of registers --- .../GameCube_DSP_Users_Manual.tex | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 2e1401d6d7..6980489b8c 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -482,6 +482,10 @@ The DSP has 32 16-bit registers, although their individual purpose and their fun The DSP has two long 40-bit accumulators (\Register{\$acX}) and their short 24-bit forms (\Register{\$acsX}) that reflect the upper part of 40-bit accumulator. There are additional two 32-bit accumulators (\Register{\$axX}). +The high parts of the 40-bit accumulators (\Register{acX.h}) are sign-extended 8-bit registers. Writes to the upper 8 bits are ignored, +and the upper 8 bits read the same as the 7th bit. For instance, \Value{0x007F} reads back as \Value{0x007F}, but \Value{0x0080} reads +back as \Value{0xFF80}. + \textbf{Accumulators \Register{\$acX}:} 40-bit accumulator \Register{\$acX} (\Register{\$acX.hml}) consists of registers: @@ -532,6 +536,8 @@ If the value is not zero, then the PC is modified by the value from call stack \ Its purpose is unknown at this time. It is written with \Value{0x00FF} and \Value{0x0004} values. +This is an 8-bit register. Writes to the upper 8 bits are ignored and those bits always read back as 0. + \pagebreak{} \section{Status register} @@ -551,7 +557,7 @@ Furthermore, it also contains control bits to configure the flow of certain oper \texttt{11} & \texttt{EIE} & External interrupt enable \\ \hline \texttt{10} & & \\ \hline \texttt{9} & \texttt{IE} & Interrupt enable \\ \hline -\texttt{8} & \texttt{0} & Hardwired to 0? \\ \hline +\texttt{8} & & Unknown, always reads back as 0 \\ \hline \texttt{7} & \texttt{OS} & Overflow (sticky) \\ \hline \texttt{6} & \texttt{LZ} & Logic zero (used by \Opcode{ANDCF} and \Opcode{ANDF}) \\ \hline \texttt{5} & \texttt{TB} & Top two bits are equal \\ \hline @@ -580,6 +586,8 @@ It needs to be noted that \InlineExpression{\$prod.m1 + \$prod.m2} overflow bit Bit \RegisterField{\$sr.AM} affects the result of the multiply unit. If \RegisterField{\$sr.AM} is equal 0 then the result of every multiply operation will be multiplied by two. +\Register{prod.h} is 8 bits. The upper 8 bits always read back as 0. + \pagebreak{} \chapter{Exceptions} From 408623b6e92c0e3e00fb4ddb3bd18b3fe00b2e2d Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sat, 14 Aug 2021 17:36:55 -0700 Subject: [PATCH 37/49] docs/DSP: Document behavior of LRS/SRS/SI with CR --- Source/DSPSpy/tests/cr_test.ds | 81 +++++++++++++++++++ .../GameCube_DSP_Users_Manual.tex | 18 +++-- 2 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 Source/DSPSpy/tests/cr_test.ds diff --git a/Source/DSPSpy/tests/cr_test.ds b/Source/DSPSpy/tests/cr_test.ds new file mode 100644 index 0000000000..272e4b8c2a --- /dev/null +++ b/Source/DSPSpy/tests/cr_test.ds @@ -0,0 +1,81 @@ +incdir "tests" +include "dsp_base.inc" + +; Tests the behavior of SI, SRS, and LRS when CR is changed + +; Register that is writable but with contents that doesn't matter (COEF_A1_0) +TEST_REG: equ 0xFFA0 ; 0xFF00 (not writable) +; This is separate because SRS and SI currently require value 0..7f or ff80..ffff, +; though the actual behavior doesn't match that +TEST_ADDR: equ 0xFFA0 ; 0x0000 +; Memory addresses +TEST_MEM: equ 0x00A0 ; 0x0000 +TEST_MEM_2: equ 0x01A0 ; 0x0100 + + LRI $AC0.L, #0xf00f + SR @TEST_REG, $AC0.L + SR @TEST_MEM, $AC0.L + SR @TEST_MEM_2, $AC0.L + CALL send_regs + + ; Observed: writes to TEST_REG + SI @TEST_ADDR, #0xf11f + CALL send_regs + + LRI $AC0.L, #0xf22f + ; Observed: writes to TEST_REG + SRS @TEST_ADDR, $AC0.L + CALL send_regs + + LRI $CR, #0x0000 + ; Observed: still writes to TEST_REG + SI @TEST_ADDR, #0xf33f + CALL send_regs + + LRI $AC0.L, #0xf44f + ; Observed: writes to TEST_MEM + SRS @TEST_ADDR, $AC0.L + CALL send_regs + + LRI $CR, #0x0001 + ; Observed: still writes to TEST_REG + SI @TEST_ADDR, #0xf55f + CALL send_regs + + LRI $AC0.L, #0xf66f + ; Observed: writes to TEST_MEM_2 + SRS @TEST_ADDR, $AC0.L + CALL send_regs + + ; At this point, TEST_REG should be f55f, TEST_MEM should be f44f, + ; and TEST_MEM_2 should be f66f. Test the behavior of LRS. + ; Changes to prod.l are for display only. + LRI $CR, #0x00ff + LRI $prod.l, #0xf55f + LRS $AC0.L, @TEST_ADDR + CALL send_regs + + LRI $CR, #0x0000 + LRI $prod.l, #0xf44f + LRS $AC0.L, @TEST_ADDR + CALL send_regs + + LRI $CR, #0x0001 + LRI $prod.l, #0xf66f + LRS $AC0.L, @TEST_ADDR + CALL send_regs + +; We're done, DO NOT DELETE THIS LINE + JMP end_of_test + +send_regs: + ; For display purposes only + LRI $prod.m1, #TEST_REG + LRI $prod.h, #TEST_MEM + LRI $prod.m2, #TEST_MEM_2 + ; Actual registers + LR $AC1.L, @TEST_REG + LR $AC0.M, @TEST_MEM + LR $AC1.M, @TEST_MEM_2 + CALL send_back + RET diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 6980489b8c..615a834bc0 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -534,7 +534,7 @@ If the value is not zero, then the PC is modified by the value from call stack \ \section{Config register} -Its purpose is unknown at this time. It is written with \Value{0x00FF} and \Value{0x0004} values. +Serves as a base offset for \Opcode{SRS} and \Opcode{LRS}. Zelda uCode writes it with \Value{0x0004}, but otherwise it is usually \Value{0x00FF}. This is an 8-bit register. Writes to the upper 8 bits are ignored and those bits always read back as 0. @@ -2558,12 +2558,12 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Move value from data memory pointed by address \Address{M} (8-bit sign-extended) to register \Register{\$(0x18+D)}. + \item Move value from data memory pointed by address \Address{(\$cr << 8) | M} to register \Register{\$(0x18+D)}. Perform an additional operation depending on destination register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - $(0x18+D) = MEM[M] + $(0x18+D) = MEM[($cr << 8) | M] $pc++ \end{DSPOpcodeOperation} @@ -3843,14 +3843,18 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Store 16-bit immediate value \Value{I} to a memory location pointed by address \Address{M} (\Address{M} is an 8-bit sign-extended value). + \item Store 16-bit immediate value \Value{I} to a memory location pointed by address \Address{0xFF00 | M}. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - MEM[M] = I + MEM[0xFF00 | M] = I $pc += 2 \end{DSPOpcodeOperation} + \begin{DSPOpcodeNote} + \item Unlike \Opcode{LRS} and \Opcode{SRS}, \Opcode{SI} does not use \Register{\$cr} to decide the base address and instead always uses \Address{0xFF00}. + \end{DSPOpcodeNote} + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} @@ -3979,12 +3983,12 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Store value from register \Register{\$(0x18+S)} to a memory pointed by address \Address{M} (8-bit sign-extended). + \item Store value from register \Register{\$(0x18+S)} to a memory pointed by address \Address{(\$cr << 8) | M}. Perform an additional operation depending on destination register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - MEM[M] = $(0x18+S) + MEM[($cr << 8) | M] = $(0x18+S) $pc++ \end{DSPOpcodeOperation} From af10eab938e23dcaf1299e4368feaa9d08a639ba Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sat, 14 Aug 2021 22:37:21 -0700 Subject: [PATCH 38/49] docs/DSP: Split SRSH from SRS --- .../GameCube_DSP_Users_Manual.tex | 52 ++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 615a834bc0..f1da961ab6 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -534,7 +534,7 @@ If the value is not zero, then the PC is modified by the value from call stack \ \section{Config register} -Serves as a base offset for \Opcode{SRS} and \Opcode{LRS}. Zelda uCode writes it with \Value{0x0004}, but otherwise it is usually \Value{0x00FF}. +Serves as a base offset for \Opcode{SRS}, \Opcode{SRSH}, and \Opcode{LRS}. Zelda uCode writes it with \Value{0x0004}, but otherwise it is usually \Value{0x00FF}. This is an 8-bit register. Writes to the upper 8 bits are ignored and those bits always read back as 0. @@ -2567,6 +2567,10 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th $pc++ \end{DSPOpcodeOperation} + \begin{DSPOpcodeNote} + \item \Opcode{LRS} can use \Register{\$axD} and cannot use \Register{\$acS.h}, while \Opcode{SRS} and \Opcode{SRSH} only work on \Register{\$acS}. + \end{DSPOpcodeNote} + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} @@ -3852,7 +3856,7 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \end{DSPOpcodeOperation} \begin{DSPOpcodeNote} - \item Unlike \Opcode{LRS} and \Opcode{SRS}, \Opcode{SI} does not use \Register{\$cr} to decide the base address and instead always uses \Address{0xFF00}. + \item Unlike \Opcode{SRS}, \Opcode{SRSH}, and \Opcode{LRS}, \Opcode{SI} does not use \Register{\$cr} to decide the base address and instead always uses \Address{0xFF00}. \end{DSPOpcodeNote} \DSPOpcodeFlagsUnchanged @@ -3975,23 +3979,55 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \begin{DSPOpcode}{SRS} \begin{DSPOpcodeBytefield}{16} - \monobitbox{4}{0010} & \monobitbox{4}{1sss} & \monobitbox{4}{mmmm} & \monobitbox{4}{mmmm} + \monobitbox{4}{0010} & \monobitbox{4}{11ss} & \monobitbox{4}{mmmm} & \monobitbox{4}{mmmm} \end{DSPOpcodeBytefield} \begin{DSPOpcodeFormat} - SRS @M, $(0x18+S) + SRS @M, $(0x1C+S) \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Store value from register \Register{\$(0x18+S)} to a memory pointed by address \Address{(\$cr << 8) | M}. + \item Store value from register \Register{\$(0x1C+S)} to a memory pointed by address \Address{(\$cr << 8) | M}. Perform an additional operation depending on destination register. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - MEM[($cr << 8) | M] = $(0x18+S) + MEM[($cr << 8) | M] = $(0x1C+S) $pc++ \end{DSPOpcodeOperation} + \begin{DSPOpcodeNote} + \item Unlike \Opcode{LRS}, \Opcode{SRS} and \Opcode{SRSH} only work on \Register{\$acS}. + The pattern \Value{101s} is unused and does not perform any write. + \end{DSPOpcodeNote} + + \DSPOpcodeFlagsUnchanged +\end{DSPOpcode} + +\begin{DSPOpcode}{SRSH} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{0010} & \monobitbox{4}{100s} & \monobitbox{4}{mmmm} & \monobitbox{4}{mmmm} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + SRSH @M, $acS.h + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Store value from register \Register{\$acS.h} to a memory pointed by address \Address{(\$cr << 8) | M}. + Perform an additional operation depending on destination register. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + MEM[($cr << 8) | M] = $acS.h + $pc++ + \end{DSPOpcodeOperation} + + \begin{DSPOpcodeNote} + \item Unlike \Opcode{LRS}, \Opcode{SRS} and \Opcode{SRSH} only work on \Register{\$acS}. + The pattern \Value{101s} is unused and does not perform any write. + \end{DSPOpcodeNote} + \DSPOpcodeFlagsUnchanged \end{DSPOpcode} @@ -4906,7 +4942,9 @@ Instruction & Opcode & Page \\ \hline \OpcodeRow{0001 11dd ddds ssss}{MRR} \OpcodeRowSkip \OpcodeRow{0010 0ddd mmmm mmmm}{LRS} -\OpcodeRow{0010 1sss mmmm mmmm}{SRS} +\OpcodeRow{0010 100s mmmm mmmm}{SRSH} +\OpcodeRowUnk{0010 101x mmmm mmmm} +\OpcodeRow{0010 11ss mmmm mmmm}{SRS} \OpcodeRowSkip \OpcodeRow{0011 00sd 0xxx xxxx}{XORR} \OpcodeRow{0011 01sd 0xxx xxxx}{ANDR} From 5611bd8f23b4d851b5be30169dc32624391f7b8a Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sun, 15 Aug 2021 23:32:21 -0700 Subject: [PATCH 39/49] docs/DSP: Change conditional names to match Dolphin --- .../GameCube_DSP_Users_Manual.tex | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index f1da961ab6..19c73a0cf0 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -1037,29 +1037,30 @@ The groups of conditional instructions are: \Opcode{CALLcc}, \Opcode{Jcc}, \Opco \begin{tabular}{|l|l|l|l|} \hline \textbf{Bits} & \textbf{\texttt{cc}} & \textbf{Name} & \textbf{Evaluated expression} \\ \hline -\texttt{0b0000} & \texttt{GE} & Greater than or equal & \\ \hline -\texttt{0b0001} & \texttt{L} & Less than & \\ \hline -\texttt{0b0010} & \texttt{G} & Greater than & \\ \hline -\texttt{0b0011} & \texttt{LE} & Less than or equal & \\ \hline -\texttt{0b0100} & \texttt{NE} & Not equal & \texttt{(\$sr \& 0x4) == 0} \\ \hline -\texttt{0b0101} & \texttt{EQ} & Equal & \texttt{(\$sr \& 0x4) != 0} \\ \hline -\texttt{0b0110} & \texttt{NC} & Not carry & \texttt{(\$sr \& 0x1) == 0} \\ \hline -\texttt{0b0111} & \texttt{C} & Carry & \texttt{(\$sr \& 0x1) != 0} \\ \hline -\texttt{0b1000} & & Below s32 & \texttt{(\$sr \& 0x10) == 0} \\ \hline -\texttt{0b1001} & & Above s32 & \texttt{(\$sr \& 0x10) != 0} \\ \hline -\texttt{0b1010} & & & \\ \hline -\texttt{0b1011} & & & \\ \hline -\texttt{0b1100} & \texttt{NZ} & Not zero & \texttt{(\$sr \& 0x40) == 0} \\ \hline -\texttt{0b1101} & \texttt{ZR} & Zero & \texttt{(\$sr \& 0x40) != 0} \\ \hline -\texttt{0b1110} & \texttt{O} & Overflow & \texttt{(\$sr \& 0x2) != 0} \\ \hline -\texttt{0b1111} & & \textless always\textgreater & \\ \hline +\texttt{0b0000} & \texttt{GE} & Greater than or equal & \Code{\$sr.O == \$sr.S} \\ \hline +\texttt{0b0001} & \texttt{L} & Less than & \Code{\$sr.O != \$sr.S} \\ \hline +\texttt{0b0010} & \texttt{G} & Greater than & \Code{(\$sr.O == \$sr.S) \&\& (\$sr.Z == 0)} \\ \hline +\texttt{0b0011} & \texttt{LE} & Less than or equal & \Code{(\$sr.O != \$sr.S) || (\$sr.Z != 0)} \\ \hline +\texttt{0b0100} & \texttt{NZ} & Not zero & \Code{\$sr.Z == 0} \\ \hline +\texttt{0b0101} & \texttt{Z} & Zero & \Code{\$sr.Z != 0} \\ \hline +\texttt{0b0110} & \texttt{NC} & Not carry & \Code{\$sr.C == 0} \\ \hline +\texttt{0b0111} & \texttt{C} & Carry & \Code{\$sr.C != 0} \\ \hline +\texttt{0b1000} & \texttt{x8} & Below s32 & \Code{\$sr.AS == 0} \\ \hline +\texttt{0b1001} & \texttt{x9} & Above s32 & \Code{\$sr.AS != 0} \\ \hline +\texttt{0b1010} & \texttt{xA} & & \Code{((\$sr.AS != 0) || (\$sr.TB != 0)) \&\& (\$sr.Z == 0)} \\ \hline +\texttt{0b1011} & \texttt{xB} & & \Code{((\$sr.AS == 0) \&\& (\$sr.TB == 0)) || (\$sr.Z != 0)} \\ \hline +\texttt{0b1100} & \texttt{LNZ} & Not logic zero & \Code{\$sr.LZ == 0} \\ \hline +\texttt{0b1101} & \texttt{LZ} & Logic zero & \Code{\$sr.LZ != 0} \\ \hline +\texttt{0b1110} & \texttt{O} & Overflow & \Code{\$sr.O != 0} \\ \hline +\texttt{0b1111} & & \textless always\textgreater & \\ \hline \end{tabular} \end{table} \textbf{Note:} -There are two pairs of conditions that work similarly: \texttt{EQ}/\texttt{NE} and \texttt{ZR}/\texttt{NZ}. -\texttt{EQ}/\texttt{NE} pair operates on arithmetic zero flag (arithmetic 0) while \texttt{ZR}/\texttt{NZ} pair operates on logic zero flag (logic 0). +There are two pairs of conditions that work similarly: \texttt{Z}/\texttt{NZ} and \texttt{LZ}/\texttt{LNZ}. +\texttt{Z}/\texttt{NZ} pair operates on arithmetic zero flag (arithmetic 0) while \texttt{LZ}/\texttt{LNZ} pair operates on logic zero flag (logic 0). +The logic zero flag is only set by \Opcode{ANDCF} and \Opcode{ANDF}. \pagebreak{} From 1b84721b7f587b09a75eba4f2e75425c3ba4796d Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Mon, 16 Aug 2021 00:03:15 -0700 Subject: [PATCH 40/49] docs/DSP: Add RTIcc --- .../GameCube_DSP_Users_Manual.tex | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 19c73a0cf0..afe1a3e16c 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -1030,7 +1030,7 @@ Opcode decoding uses special naming for bits and their decimal representations t \section{Conditional opcodes} Conditional opcodes are executed only when the condition described by their encoded conditional field has been met. -The groups of conditional instructions are: \Opcode{CALLcc}, \Opcode{Jcc}, \Opcode{IFcc}, \Opcode{RETcc}, \Opcode{JRcc}, and \Opcode{CALLRcc}. +The groups of conditional instructions are: \Opcode{CALLcc}, \Opcode{Jcc}, \Opcode{IFcc}, \Opcode{RETcc}, \Opcode{RTIcc}, \Opcode{JRcc}, and \Opcode{CALLRcc}. \begin{table}[H] \centering @@ -3720,6 +3720,34 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \DSPOpcodeFlagsUnchanged \end{DSPOpcode} +\begin{DSPOpcode}{RTIcc} + \begin{DSPOpcodeBytefield}{16} + \monobitbox{4}{0000} & \monobitbox{4}{0010} & \monobitbox{4}{1111} & \monobitbox{4}{cccc} + \end{DSPOpcodeBytefield} + + \begin{DSPOpcodeFormat} + RTIcc + \end{DSPOpcodeFormat} + + \begin{DSPOpcodeDescription} + \item Return from exception if condition \Flag{cc} has been met. Pops stored status register \Register{\$sr} from data stack \Register{\$st1} and + program counter PC from call stack \Register{\$st0} and sets \Register{\$pc} to this location. + \end{DSPOpcodeDescription} + + \begin{DSPOpcodeOperation} + IF (cc) + $sr = $st1 + POP_STACK($st1) + $pc = $st0 + POP_STACK($st0) + ELSE + $pc++ + ENDIF + \end{DSPOpcodeOperation} + + \DSPOpcodeFlagsUnchanged +\end{DSPOpcode} + \begin{DSPOpcode}{SBCLR} \begin{DSPOpcodeBytefield}{16} \monobitbox{4}{0001} & \monobitbox{4}{0010} & \monobitbox{4}{0000} & \monobitbox{4}{0iii} @@ -4897,7 +4925,7 @@ Instruction & Opcode & Page \\ \hline \OpcodeRow{0000 0010 1001 cccc aaaa aaaa aaaa aaaa}{Jcc} \OpcodeRow{0000 0010 1011 cccc aaaa aaaa aaaa aaaa}{CALLcc} \OpcodeRow{0000 0010 1101 cccc}{RETcc} -\OpcodeRow{0000 0010 1111 1111}{RTI} +\OpcodeRow{0000 0010 1111 cccc}{RTIcc} \OpcodeRowSkip \OpcodeRow{0000 001r 0000 0000 iiii iiii iiii iiii}{ADDI} \OpcodeRow{0000 001r 0010 0000 iiii iiii iiii iiii}{XORI} From 5bf59f3ce44e2a20103c48f7c61a6aac1d9c62c6 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Mon, 16 Aug 2021 00:03:46 -0700 Subject: [PATCH 41/49] docs/DSP: A failed RETcc only inceases PC by 1, not 2 This is because RETcc is a single-word instruction. --- .../DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index afe1a3e16c..d8c1958a06 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -3689,7 +3689,7 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th IF (cc) POP_STACK($st0) ELSE - $pc += 2 + $pc++ ENDIF \end{DSPOpcodeOperation} From c51c3394246a9d25ed95e186ab80d8c5d16d0234 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Mon, 16 Aug 2021 12:14:56 -0700 Subject: [PATCH 42/49] docs/DSP: Document initialization process --- .../GameCube_DSP_Users_Manual.tex | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index d8c1958a06..28a05b9e27 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -396,8 +396,6 @@ Instruction Memory (IMEM) is divided into instruction RAM (IRAM) and instruction Exception vectors are located at the top of the RAM and occupy the first 16 words, with 2 words available for each exception (enough for a \Opcode{JMP} instruction for each exception). -DSP IRAM is mapped through as first 8KB of ARAM (Accelerator RAM), therefore the CPU can DMA DSP code to DSP IRAM. This usually occurs during boot time, as the DSP ROM is not enabled at cold reset and needs to be reenabled by a small stub executed in IRAM. - There are no DSP instructions that write to IMEM; however, the \texttt{ILLR} family of instructions can read from it. This is sometimes used for jump tables or indexing into a list of pointers (which may point into either IMEM or DMEM). \begin{table}[htb] @@ -431,6 +429,23 @@ It is possible to both read and write to DMEM, but coefficient data cannot be wr \pagebreak{} +\section{Initialization} + +The DSP is initialized before it is used. This is done by copying a small program to physical address \Address{0x01000000} (virtual \Address{0x81000000}) in GameCube/Wii main memory, and then writing to \Register{DSP\_CONTROL\_STATUS} at \texttt{0xCC00500A} with the 11th and 0th bits set (SDK titles write \Value{0x08ad}). The 11th bit being set appears to cause data from \Address{0x01000000} to be DMAd to the start of IMEM; at least 128 bytes of data (64 DSP words) are transferred. (None of this has been extensively hardware tested, and is instead based on libogc's \Code{\_\_dsp\_bootstrap}.) + +The program that SDK titles send does the following: +\begin{enumerate} +\item Reads all \Value{0x1000} words of IROM from \Address{0x8000} through \Address{0x8FFF} (using \Opcode{ILRRI}) +\item Writes zero to all \Value{0x1000} words of DRAM from \Address{0x0000} through \Address{0x0FFF} (using \Opcode{SRRI}) +\item Reads all \Value{0x0800} words of COEF data from \Address{0x1000} through \Address{0x17FF} (using \Opcode{LRRI}) +\item Waits for the top bit of \Register{DMBH} to be clear (indicating the CPU is ready to receive mail) +\item Writes \Value{0x0054} to \Register{DMBH} and \Value{0x4348} to \Register{DMBL}, sending \Value{0x00543448} (``TCH''?) to the CPU. The CPU does not check for this value, but it does wait for mail to be sent. +\end{enumerate} + +It is not clear why this is done, as the values read from IROM and COEF are not used; perhaps it works around a hardware bug where incorrect values are read from ROM initially. + +\pagebreak{} + \chapter{Registers} \section{Register names} From 602163b623cdbba28f6a5dadfc4ff656fc820428 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 17 Aug 2021 20:56:03 -0700 Subject: [PATCH 43/49] docs/DSP: Fix typo with MULCMVZ and MULCMV --- .../Core/Core/DSP/Interpreter/DSPIntMultiplier.cpp | 2 -- Source/Core/Core/DSP/Jit/x64/DSPJitMultiplier.cpp | 2 -- .../GameCube_DSP_Users_Manual.tex | 12 ++++++------ 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/Source/Core/Core/DSP/Interpreter/DSPIntMultiplier.cpp b/Source/Core/Core/DSP/Interpreter/DSPIntMultiplier.cpp index e12cf07ab1..5d0e0a369c 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPIntMultiplier.cpp +++ b/Source/Core/Core/DSP/Interpreter/DSPIntMultiplier.cpp @@ -372,7 +372,6 @@ void Interpreter::mulcac(const UDSPInstruction opc) // Multiply mid part of accumulator register $acS.m by high part $axT.h of // secondary accumulator $axT (treat them both as signed). Move product // register before multiplication to accumulator $acR. -// possible mistake in duddie's doc axT.h rather than axS.h // // flags out: --xx xx0x void Interpreter::mulcmv(const UDSPInstruction opc) @@ -395,7 +394,6 @@ void Interpreter::mulcmv(const UDSPInstruction opc) // MULCMVZ $acS.m, $axT.h, $acR // 110s t01r xxxx xxxx -// (fixed possible bug in duddie's description, s->t) // Multiply mid part of accumulator register $acS.m by high part $axT.h of // secondary accumulator $axT (treat them both as signed). Move product // register before multiplication to accumulator $acR, set (round) low part of diff --git a/Source/Core/Core/DSP/Jit/x64/DSPJitMultiplier.cpp b/Source/Core/Core/DSP/Jit/x64/DSPJitMultiplier.cpp index 4b7db14823..41e0548146 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPJitMultiplier.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPJitMultiplier.cpp @@ -586,7 +586,6 @@ void DSPEmitter::mulcac(const UDSPInstruction opc) // Multiply mid part of accumulator register $acS.m by high part $axT.h of // secondary accumulator $axT (treat them both as signed). Move product // register before multiplication to accumulator $acR. -// possible mistake in duddie's doc axT.h rather than axS.h // flags out: --xx xx0x void DSPEmitter::mulcmv(const UDSPInstruction opc) @@ -618,7 +617,6 @@ void DSPEmitter::mulcmv(const UDSPInstruction opc) // MULCMVZ $acS.m, $axT.h, $acR // 110s t01r xxxx xxxx -// (fixed possible bug in duddie's description, s->t) // Multiply mid part of accumulator register $acS.m by high part $axT.h of // secondary accumulator $axT (treat them both as signed). Move product // register before multiplication to accumulator $acR, set (round) low part of diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 28a05b9e27..85530f543b 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -3279,14 +3279,14 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Multiply mid part of accumulator register \Register{\$acS.m} by high part \Register{\$axS.h} of - secondary accumulator \Register{\$axS} (treat them both as signed). + \item Multiply mid part of accumulator register \Register{\$acS.m} by high part \Register{\$axT.h} of + secondary accumulator \Register{\$axT} (treat them both as signed). Move product register before multiplication to accumulator \Register{\$acR}. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} temp = $prod - $prod = $acS.m * $axS.h + $prod = $acS.m * $axT.h $acR = temp $pc++ \end{DSPOpcodeOperation} @@ -3308,15 +3308,15 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \end{DSPOpcodeFormat} \begin{DSPOpcodeDescription} - \item Multiply mid part of accumulator register \Register{\$acS.m} by high part \Register{\$axS.h} of - secondary accumulator \Register{\$axS} (treat them both as signed). + \item Multiply mid part of accumulator register \Register{\$acS.m} by high part \Register{\$aTS.h} of + secondary accumulator \Register{\$axT} (treat them both as signed). Move product register before multiplication to accumulator \Register{\$acR}. Set low part of accumulator \Register{\$acR.l} to zero. \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} temp = $prod - $prod = $acS.m * $axS.h + $prod = $acS.m * $axT.h $acR.hm = temp.hm $acR.l = 0 $pc++ From 9ef388f1c3635db413a1049ffef7ce156d7e9477 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Wed, 18 Aug 2021 16:33:19 -0700 Subject: [PATCH 44/49] docs/DSP: NEG can set overflow and carry --- .../GameCube_DSP_Users_Manual.tex | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 85530f543b..18706a8b45 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -3516,12 +3516,19 @@ A ``-'' indicates that the flag retains its previous value, a ``0'' indicates th \end{DSPOpcodeDescription} \begin{DSPOpcodeOperation} - $acD = -$acD + $acD = 0 - $acD FLAGS($acD) $pc++ \end{DSPOpcodeOperation} - \DSPOpcodeFlags{-}{-}{X}{X}{X}{X}{0}{0} + \begin{DSPOpcodeNote} + \item The carry flag is set only if \Register{\$acD} was zero. + The overflow flag is set only if \Register{\$acD} was \Value{0x8000000000} (the minimum value), + as \Code{-INT\_MIN} is \Code{INT\_MIN} in two's complement. + In both of these cases, the value of \Register{\$acD} after the operation is the same as it was before. + \end{DSPOpcodeNote} + + \DSPOpcodeFlags{X}{-}{X}{X}{X}{X}{X}{X} \end{DSPOpcode} \begin{DSPOpcode}{NOT} From 4fa9517ba39dde7e6e3eab87b8fba3c2e95da1ff Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sat, 21 Aug 2021 11:39:42 -0700 Subject: [PATCH 45/49] docs/DSP: Update version and history The GFDL requires the history section to be updated. --- .../GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex index 18706a8b45..582f1e96fa 100644 --- a/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex +++ b/docs/DSP/GameCube_DSP_Users_Manual/GameCube_DSP_Users_Manual.tex @@ -46,7 +46,7 @@ % Document front page material \title{\textbf{\Huge GameCube DSP User's Manual}} \author{Reverse-engineered and documented by Duddie \\ \href{mailto:duddie@walla.com}{duddie@walla.com}} -\date{\today\\v0.0.7} +\date{\today\\v0.1.0} % Title formatting commands \newcommand{\OpcodeTitle}[1]{\subsection{#1}\label{instruction:#1}} @@ -247,7 +247,7 @@ The purpose of this documentation is purely academic and it aims at understandin \begin{table}[htb] \centering -\begin{tabular}{|l|l|l|l|} +\begin{tabular}{|p{.5in}|p{.75in}|p{.75in}|p{3.5in}|} \hline \textbf{Version} & \textbf{Date} & \textbf{Author} & \textbf{Change} \\ \hline 0.0.1 & 2005.05.08 & Duddie & Initial release \\ \hline @@ -257,6 +257,7 @@ The purpose of this documentation is purely academic and it aims at understandin 0.0.5 & 2018.04.09 & Lioncache & Converted document over to LaTeX. \\ \hline 0.0.6 & 2018.04.13 & BhaaL & Updated register tables, fixed opcode operations \\ \hline 0.0.7 & Mid 2020 & Tilka & Fixed typos and register names, and improved readability. \\ \hline +0.1.0 & 2021.08.21 & Pokechu22 & Added missing instructions, improved documentation of hardware registers, documented additional behaviors, and improved formatting. \\ \hline \end{tabular} \end{table} From 3eaf06d2e05544866df43f253a76042e1a928ec0 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sat, 14 Aug 2021 14:16:05 -0700 Subject: [PATCH 46/49] DSPSpy: Create .gitignore --- Source/DSPSpy/.gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Source/DSPSpy/.gitignore diff --git a/Source/DSPSpy/.gitignore b/Source/DSPSpy/.gitignore new file mode 100644 index 0000000000..33ae368ffb --- /dev/null +++ b/Source/DSPSpy/.gitignore @@ -0,0 +1,4 @@ +dsp_code.h +build/ +*.dol +*.elf \ No newline at end of file From 1ad8dd7634608a7645a5f1869d344a337c16240e Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sat, 14 Aug 2021 14:17:52 -0700 Subject: [PATCH 47/49] DSPSpy: Remove build.sh and sbuild.sh This also removes the emu folder from the Makefile, and the Config.h file. I'm not entirely sure what build.sh was for, but my best guess is that it was some kind of tool to run emulated DSP code at the same time as the actual DSP code and compare the results. I don't know if it ever worked, but it certainly doesn't work now. --- Source/DSPSpy/Config.h | 4 ---- Source/DSPSpy/Makefile | 2 +- Source/DSPSpy/build.sh | 6 ------ Source/DSPSpy/sbuild.sh | 4 ---- 4 files changed, 1 insertion(+), 15 deletions(-) delete mode 100644 Source/DSPSpy/Config.h delete mode 100644 Source/DSPSpy/build.sh delete mode 100644 Source/DSPSpy/sbuild.sh diff --git a/Source/DSPSpy/Config.h b/Source/DSPSpy/Config.h deleted file mode 100644 index 9790da1b56..0000000000 --- a/Source/DSPSpy/Config.h +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright 2003 Dolphin Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -// Dummy file for common to compile diff --git a/Source/DSPSpy/Makefile b/Source/DSPSpy/Makefile index 6ab9c54535..df6a27aa55 100644 --- a/Source/DSPSpy/Makefile +++ b/Source/DSPSpy/Makefile @@ -23,7 +23,7 @@ include $(DEVKITPPC)/$(HW_TYPE)_rules #--------------------------------------------------------------------------------- TARGET := $(notdir $(CURDIR))_$(HW_TYPE) BUILD := build -SOURCES := . emu +SOURCES := . DATA := data INCLUDES := include ../Core/Common . diff --git a/Source/DSPSpy/build.sh b/Source/DSPSpy/build.sh deleted file mode 100644 index a6fbaf9015..0000000000 --- a/Source/DSPSpy/build.sh +++ /dev/null @@ -1,6 +0,0 @@ -../../Binary/x64/DSPTool.exe -h dsp_code tests/mul_test.ds -mkdir emu -cp ../Core/Core/DSP/*.cpp emu -cp ../Core/Core/DSP/*.h emu -make - diff --git a/Source/DSPSpy/sbuild.sh b/Source/DSPSpy/sbuild.sh deleted file mode 100644 index 80038bf9f5..0000000000 --- a/Source/DSPSpy/sbuild.sh +++ /dev/null @@ -1,4 +0,0 @@ -../../Binary/x64/DSPTool.exe -h dsp_code tests/mul_test.ds -rm -rf emu -make - From ddc2dd91d2068a3ab4a466fc8c4fcbef30ca3dd4 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sat, 14 Aug 2021 16:55:31 -0700 Subject: [PATCH 48/49] DSPSpy: Create README.md --- Source/DSPSpy/README.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Source/DSPSpy/README.md diff --git a/Source/DSPSpy/README.md b/Source/DSPSpy/README.md new file mode 100644 index 0000000000..4c57915a79 --- /dev/null +++ b/Source/DSPSpy/README.md @@ -0,0 +1,39 @@ +# DSPSpy + +DSPSpy is a homebrew tool for experimenting with the GameCube/Wii DSP. It can also be used to dump the DSP ROMs. + +## Building + +DSPSpy is built using [devkitPPC](https://wiibrew.org/wiki/DevkitPPC); see the [devkitPro getting started page](https://devkitpro.org/wiki/Getting_Started) for more information. DSPSpy also requires DSPTool to be built. + +First, run DSPTool to generate `dsp_code.h`, for instance from `tests/dsp_test.ds`. The following commands assume an x64 Windows setup running in the DSPSpy directory: + +``` +../../Binary/x64/DSPTool.exe -h dsp_code tests/dsp_test.ds +``` + +To use the ROM-dumping code, run this: + +``` +../../Binary/x64/DSPTool.exe -h dsp_code util/dump_roms.ds +``` + +DSPTool can also generate a header for multiple DSP programs at the same time. First, create a file (in this example, it was named `file_list.txt`) with the following contents: + +``` +tests/dsp_test.ds +tests/mul_test.ds +tests/neg_test.ds +``` + +Then run: + +``` +../../Binary/x64/DSPTool.exe -h dsp_code -m file_list.txt +``` + +After `dsp_code.h` has been generated, simply run `make` to generate `dspspy_wii.dol`, which can be loaded by normal means. + +## Dumping DSP ROMs + +Build DSPSpy with `util/dump_roms.ds`. When launched, DSPSpy will automatically create files `dsp_rom.bin` and `dsp_coef.bin` on the SD card (only SD cards are supported); DSPSpy can be exited immediately afterwards. \ No newline at end of file From 88d2a7260d386e7bebf0bbcad89f3853aed1bbc2 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Fri, 13 Aug 2021 11:52:17 -0700 Subject: [PATCH 49/49] DSPLLE: Improve various instruction comments * DSP*Arithmetic: Fix grammar for ANDCF and ANDF * DSP*Arithmetic: Fix registers used by MOVAX and MOV * DSP*Branch: Fix documentation for JMPR * DSP*Branch: Fix HALT encoding ("I think I saw a two") * DSP*ExtOps: Fix 'LN encoding (The listed encoding was for 'L) * DSP*ExtOps: Improve documentation for 'LD and 'LDAX * DSPJitExtOps: Correct typo * DSP*LoadStore: Remove obsolete comment about pc in SRS (This was fixed in 1419e7e5b2d8aad63ef9c2bf3ef9f5b7db759b49) * DSP*LoadStore: Fix comments for LRR/SRR * DSP*Misc: Improve documentation for SBCLR and SBSET * DSP*Multiplier: Fix MULXAC encoding (The previous encoding was for MULXMVZ) * DSP*Multiplier: Fix tabs in MULCAC and MULCMVZ (There are some other tabs in comments in the JIT, but these are the only ones that are in instruction comments instead of indicating the corresponding interpreter code. Those other comments can be corrected in a different PR, as they're not documentation related.) * DSPJitMultiplier: Fix MULXMVZ typo --- .../Core/DSP/Interpreter/DSPIntArithmetic.cpp | 8 ++-- .../Core/DSP/Interpreter/DSPIntBranch.cpp | 7 ++-- .../Core/DSP/Interpreter/DSPIntExtOps.cpp | 29 +++++++------- .../Core/DSP/Interpreter/DSPIntLoadStore.cpp | 39 +++++++++---------- .../Core/Core/DSP/Interpreter/DSPIntMisc.cpp | 8 ++-- .../Core/DSP/Interpreter/DSPIntMultiplier.cpp | 6 +-- .../Core/DSP/Jit/x64/DSPJitArithmetic.cpp | 8 ++-- Source/Core/Core/DSP/Jit/x64/DSPJitBranch.cpp | 7 ++-- Source/Core/Core/DSP/Jit/x64/DSPJitExtOps.cpp | 33 +++++++++------- .../Core/Core/DSP/Jit/x64/DSPJitLoadStore.cpp | 39 +++++++++---------- Source/Core/Core/DSP/Jit/x64/DSPJitMisc.cpp | 8 ++-- .../Core/DSP/Jit/x64/DSPJitMultiplier.cpp | 8 ++-- 12 files changed, 104 insertions(+), 96 deletions(-) diff --git a/Source/Core/Core/DSP/Interpreter/DSPIntArithmetic.cpp b/Source/Core/Core/DSP/Interpreter/DSPIntArithmetic.cpp index 18a48413b3..41ff79cc67 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPIntArithmetic.cpp +++ b/Source/Core/Core/DSP/Interpreter/DSPIntArithmetic.cpp @@ -47,7 +47,7 @@ void Interpreter::clrl(const UDSPInstruction opc) // 0000 001r 1100 0000 // iiii iiii iiii iiii // Set logic zero (LZ) flag in status register $sr if result of logic AND of -// accumulator mid part $acD.m with immediate value I is equal I. +// accumulator mid part $acD.m with immediate value I is equal to I. // // flags out: -x-- ---- void Interpreter::andcf(const UDSPInstruction opc) @@ -64,7 +64,7 @@ void Interpreter::andcf(const UDSPInstruction opc) // iiii iiii iiii iiii // Set logic zero (LZ) flag in status register $sr if result of logical AND // operation of accumulator mid part $acD.m with immediate value I is equal -// immediate value 0. +// to immediate value 0. // // flags out: -x-- ---- void Interpreter::andf(const UDSPInstruction opc) @@ -793,7 +793,7 @@ void Interpreter::movr(const UDSPInstruction opc) // MOVAX $acD, $axS // 0110 10sd xxxx xxxx -// Moves secondary accumulator $axS to accumulator $axD. +// Moves secondary accumulator $axS to accumulator $acD. // // flags out: --xx xx00 void Interpreter::movax(const UDSPInstruction opc) @@ -811,7 +811,7 @@ void Interpreter::movax(const UDSPInstruction opc) // MOV $acD, $ac(1-D) // 0110 110d xxxx xxxx -// Moves accumulator $ax(1-D) to accumulator $axD. +// Moves accumulator $ac(1-D) to accumulator $acD. // // flags out: --x0 xx00 void Interpreter::mov(const UDSPInstruction opc) diff --git a/Source/Core/Core/DSP/Interpreter/DSPIntBranch.cpp b/Source/Core/Core/DSP/Interpreter/DSPIntBranch.cpp index eb556330a9..7dafeaf3d8 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPIntBranch.cpp +++ b/Source/Core/Core/DSP/Interpreter/DSPIntBranch.cpp @@ -76,9 +76,10 @@ void Interpreter::jcc(const UDSPInstruction opc) } // Generic jmpr implementation -// JMPcc $R +// JRcc $R // 0001 0111 rrr0 cccc -// Jump to address; set program counter to a value from register $R. +// Jump to address if condition cc has been met. Set program counter to +// a value from register $R. void Interpreter::jmprcc(const UDSPInstruction opc) { if (!CheckCondition(opc & 0xf)) @@ -116,7 +117,7 @@ void Interpreter::rti(const UDSPInstruction) } // HALT -// 0000 0000 0020 0001 +// 0000 0000 0010 0001 // Stops execution of DSP code. Sets bit DSP_CR_HALT in register DREG_CR. void Interpreter::halt(const UDSPInstruction) { diff --git a/Source/Core/Core/DSP/Interpreter/DSPIntExtOps.cpp b/Source/Core/Core/DSP/Interpreter/DSPIntExtOps.cpp index 87bc51e06a..c271c28f33 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPIntExtOps.cpp +++ b/Source/Core/Core/DSP/Interpreter/DSPIntExtOps.cpp @@ -144,7 +144,7 @@ void Interpreter::l(const UDSPInstruction opc) } // LN $axD.D, @$arS -// xxxx xxxx 01dd d0ss +// xxxx xxxx 01dd d1ss // Load $axD.D/$acD.D with value from memory pointed by register $arS. // Add indexing register $ixS to register $arS. void Interpreter::ln(const UDSPInstruction opc) @@ -327,17 +327,17 @@ void Interpreter::slnm(const UDSPInstruction opc) IncreaseAddressRegister(DSP_REG_AR0, static_cast(state.r.ix[0]))); } -// LD $ax0.d, $ax1.r, @$arS +// LD $ax0.D, $ax1.R, @$arS // xxxx xxxx 11dr 00ss -// example for "nx'ld $AX0.L, $AX1.L, @$AR3" -// Loads the word pointed by AR0 to AX0.H, then loads the word pointed by AR3 to AX0.L. -// Increments AR0 and AR3. -// If AR0 and AR3 point into the same memory page (upper 6 bits of addr are the same -> games are -// not doing that!) -// then the value pointed by AR0 is loaded to BOTH AX0.H and AX0.L. -// If AR0 points into an invalid memory page (ie 0x2000), then AX0.H keeps its old value. (not +// Load register $ax0.D (either $ax0.l or $ax0.h) with value from memory pointed by register $arS. +// Load register $ax1.R (either $ax1.l or $ax1.h) with value from memory pointed by register $ar3. +// Increment both $arS and $ar3. +// S cannot be 3, as that encodes LDAX. Thus $arS and $ar3 are known to be distinct. +// If $ar0 and $ar3 point into the same memory page (upper 6 bits of addr are the same -> games are +// not doing that!) then the value pointed by $ar0 is loaded to BOTH $ax0.D and $ax1.R. +// If $ar0 points into an invalid memory page (ie 0x2000), then $ax0.D keeps its old value. (not // implemented yet) -// If AR3 points into an invalid memory page, then AX0.L gets the same value as AX0.H. (not +// If $ar3 points into an invalid memory page, then $ax1.R gets the same value as $ax0.D. (not // implemented yet) void Interpreter::ld(const UDSPInstruction opc) { @@ -360,6 +360,9 @@ void Interpreter::ld(const UDSPInstruction opc) // LDAX $axR, @$arS // xxxx xxxx 11sr 0011 +// Load register $axR.h with value from memory pointed by register $arS. +// Load register $axR.l with value from memory pointed by register $ar3. +// Increment both $arS and $ar3. void Interpreter::ldax(const UDSPInstruction opc) { const u8 sreg = (opc >> 5) & 0x1; @@ -378,7 +381,7 @@ void Interpreter::ldax(const UDSPInstruction opc) WriteToBackLog(3, DSP_REG_AR3, IncrementAddressRegister(DSP_REG_AR3)); } -// LDN $ax0.d, $ax1.r, @$arS +// LDN $ax0.D, $ax1.R, @$arS // xxxx xxxx 11dr 01ss void Interpreter::ldn(const UDSPInstruction opc) { @@ -419,7 +422,7 @@ void Interpreter::ldaxn(const UDSPInstruction opc) WriteToBackLog(3, DSP_REG_AR3, IncrementAddressRegister(DSP_REG_AR3)); } -// LDM $ax0.d, $ax1.r, @$arS +// LDM $ax0.D, $ax1.R, @$arS // xxxx xxxx 11dr 10ss void Interpreter::ldm(const UDSPInstruction opc) { @@ -462,7 +465,7 @@ void Interpreter::ldaxm(const UDSPInstruction opc) IncreaseAddressRegister(DSP_REG_AR3, static_cast(state.r.ix[3]))); } -// LDNM $ax0.d, $ax1.r, @$arS +// LDNM $ax0.D, $ax1.R, @$arS // xxxx xxxx 11dr 11ss void Interpreter::ldnm(const UDSPInstruction opc) { diff --git a/Source/Core/Core/DSP/Interpreter/DSPIntLoadStore.cpp b/Source/Core/Core/DSP/Interpreter/DSPIntLoadStore.cpp index 30729fd956..744dffb70b 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPIntLoadStore.cpp +++ b/Source/Core/Core/DSP/Interpreter/DSPIntLoadStore.cpp @@ -13,7 +13,6 @@ namespace DSP::Interpreter // Move value from register $(0x18+S) to data memory pointed by address // CR[0-7] | M. That is, the upper 8 bits of the address are the // bottom 8 bits from CR, and the lower 8 bits are from the 8-bit immediate. -// Note: pc+=2 in duddie's doc seems wrong void Interpreter::srs(const UDSPInstruction opc) { auto& state = m_dsp_core.DSPState(); @@ -86,9 +85,9 @@ void Interpreter::si(const UDSPInstruction opc) state.WriteDMEM(addr, imm); } -// LRR $D, @$S +// LRR $D, @$arS // 0001 1000 0ssd dddd -// Move value from data memory pointed by addressing register $S to register $D. +// Move value from data memory pointed by addressing register $arS to register $D. void Interpreter::lrr(const UDSPInstruction opc) { const u8 sreg = (opc >> 5) & 0x3; @@ -100,10 +99,10 @@ void Interpreter::lrr(const UDSPInstruction opc) ConditionalExtendAccum(dreg); } -// LRRD $D, @$S +// LRRD $D, @$arS // 0001 1000 1ssd dddd -// Move value from data memory pointed by addressing register $S to register $D. -// Decrement register $S. +// Move value from data memory pointed by addressing register $arS to register $D. +// Decrement register $arS. void Interpreter::lrrd(const UDSPInstruction opc) { const u8 sreg = (opc >> 5) & 0x3; @@ -116,10 +115,10 @@ void Interpreter::lrrd(const UDSPInstruction opc) state.r.ar[sreg] = DecrementAddressRegister(sreg); } -// LRRI $D, @$S +// LRRI $D, @$arS // 0001 1001 0ssd dddd -// Move value from data memory pointed by addressing register $S to register $D. -// Increment register $S. +// Move value from data memory pointed by addressing register $arS to register $D. +// Increment register $arS. void Interpreter::lrri(const UDSPInstruction opc) { const u8 sreg = (opc >> 5) & 0x3; @@ -132,10 +131,10 @@ void Interpreter::lrri(const UDSPInstruction opc) state.r.ar[sreg] = IncrementAddressRegister(sreg); } -// LRRN $D, @$S +// LRRN $D, @$arS // 0001 1001 1ssd dddd -// Move value from data memory pointed by addressing register $S to register $D. -// Add indexing register $(0x4+S) to register $S. +// Move value from data memory pointed by addressing register $arS to register $D. +// Add corresponding indexing register $ixS to register $arS. void Interpreter::lrrn(const UDSPInstruction opc) { const u8 sreg = (opc >> 5) & 0x3; @@ -148,10 +147,10 @@ void Interpreter::lrrn(const UDSPInstruction opc) state.r.ar[sreg] = IncreaseAddressRegister(sreg, static_cast(state.r.ix[sreg])); } -// SRR @$D, $S +// SRR @$arD, $S // 0001 1010 0dds ssss // Store value from source register $S to a memory location pointed by -// addressing register $D. +// addressing register $arD. void Interpreter::srr(const UDSPInstruction opc) { const u8 dreg = (opc >> 5) & 0x3; @@ -164,10 +163,10 @@ void Interpreter::srr(const UDSPInstruction opc) state.WriteDMEM(state.r.ar[dreg], OpReadRegister(sreg)); } -// SRRD @$D, $S +// SRRD @$arD, $S // 0001 1010 1dds ssss // Store value from source register $S to a memory location pointed by -// addressing register $D. Decrement register $D. +// addressing register $arD. Decrement register $arD. void Interpreter::srrd(const UDSPInstruction opc) { const u8 dreg = (opc >> 5) & 0x3; @@ -182,10 +181,10 @@ void Interpreter::srrd(const UDSPInstruction opc) state.r.ar[dreg] = DecrementAddressRegister(dreg); } -// SRRI @$D, $S +// SRRI @$arD, $S // 0001 1011 0dds ssss // Store value from source register $S to a memory location pointed by -// addressing register $D. Increment register $D. +// addressing register $arD. Increment register $arD. void Interpreter::srri(const UDSPInstruction opc) { const u8 dreg = (opc >> 5) & 0x3; @@ -200,10 +199,10 @@ void Interpreter::srri(const UDSPInstruction opc) state.r.ar[dreg] = IncrementAddressRegister(dreg); } -// SRRN @$D, $S +// SRRN @$arD, $S // 0001 1011 1dds ssss // Store value from source register $S to a memory location pointed by -// addressing register $D. Add DSP_REG_IX0 register to register $D. +// addressing register $arD. Add corresponding indexing register $ixD to register $arD. void Interpreter::srrn(const UDSPInstruction opc) { const u8 dreg = (opc >> 5) & 0x3; diff --git a/Source/Core/Core/DSP/Interpreter/DSPIntMisc.cpp b/Source/Core/Core/DSP/Interpreter/DSPIntMisc.cpp index a686bba2b5..4335bb2f69 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPIntMisc.cpp +++ b/Source/Core/Core/DSP/Interpreter/DSPIntMisc.cpp @@ -122,8 +122,8 @@ void Interpreter::addarn(const UDSPInstruction opc) // SBCLR #I // 0001 0010 aaaa aiii -// bit of status register $sr. Bit number is calculated by adding 6 to -// immediate value I. +// Clear bit of status register $sr. Bit number is calculated by adding 6 to immediate value I; +// thus, bits 6 through 13 (LZ through AM) can be cleared with this instruction. void Interpreter::sbclr(const UDSPInstruction opc) { auto& state = m_dsp_core.DSPState(); @@ -134,8 +134,8 @@ void Interpreter::sbclr(const UDSPInstruction opc) // SBSET #I // 0001 0011 aaaa aiii -// Set bit of status register $sr. Bit number is calculated by adding 6 to -// immediate value I. +// Set bit of status register $sr. Bit number is calculated by adding 6 to immediate value I; +// thus, bits 6 through 13 (LZ through AM) can be set with this instruction. void Interpreter::sbset(const UDSPInstruction opc) { auto& state = m_dsp_core.DSPState(); diff --git a/Source/Core/Core/DSP/Interpreter/DSPIntMultiplier.cpp b/Source/Core/Core/DSP/Interpreter/DSPIntMultiplier.cpp index 5d0e0a369c..a334f99d3e 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPIntMultiplier.cpp +++ b/Source/Core/Core/DSP/Interpreter/DSPIntMultiplier.cpp @@ -247,7 +247,7 @@ void Interpreter::mulx(const UDSPInstruction opc) } // MULXAC $ax0.S, $ax1.T, $acR -// 101s t01r xxxx xxxx +// 101s t10r xxxx xxxx // Add product register to accumulator register $acR. Multiply one part // $ax0 by one part $ax1. Part is selected by S and // T bits. Zero selects low part, one selects high part. @@ -343,7 +343,7 @@ void Interpreter::mulc(const UDSPInstruction opc) } // MULCAC $acS.m, $axT.h, $acR -// 110s t10r xxxx xxxx +// 110s t10r xxxx xxxx // Multiply mid part of accumulator register $acS.m by high part $axS.h of // secondary accumulator $axS (treat them both as signed). Add product // register before multiplication to accumulator $acR. @@ -393,7 +393,7 @@ void Interpreter::mulcmv(const UDSPInstruction opc) } // MULCMVZ $acS.m, $axT.h, $acR -// 110s t01r xxxx xxxx +// 110s t01r xxxx xxxx // Multiply mid part of accumulator register $acS.m by high part $axT.h of // secondary accumulator $axT (treat them both as signed). Move product // register before multiplication to accumulator $acR, set (round) low part of diff --git a/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp b/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp index 7f2da96c37..633b714124 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPJitArithmetic.cpp @@ -56,7 +56,7 @@ void DSPEmitter::clrl(const UDSPInstruction opc) // 0000 001r 1100 0000 // iiii iiii iiii iiii // Set logic zero (LZ) flag in status register $sr if result of logic AND of -// accumulator mid part $acD.m with immediate value I is equal I. +// accumulator mid part $acD.m with immediate value I is equal to I. // // flags out: -x-- ---- void DSPEmitter::andcf(const UDSPInstruction opc) @@ -91,7 +91,7 @@ void DSPEmitter::andcf(const UDSPInstruction opc) // iiii iiii iiii iiii // Set logic zero (LZ) flag in status register $sr if result of logical AND // operation of accumulator mid part $acD.m with immediate value I is equal -// immediate value 0. +// to immediate value 0. // // flags out: -x-- ---- void DSPEmitter::andf(const UDSPInstruction opc) @@ -1089,7 +1089,7 @@ void DSPEmitter::movr(const UDSPInstruction opc) // MOVAX $acD, $axS // 0110 10sd xxxx xxxx -// Moves secondary accumulator $axS to accumulator $axD. +// Moves secondary accumulator $axS to accumulator $acD. // // flags out: --xx xx00 void DSPEmitter::movax(const UDSPInstruction opc) @@ -1110,7 +1110,7 @@ void DSPEmitter::movax(const UDSPInstruction opc) // MOV $acD, $ac(1-D) // 0110 110d xxxx xxxx -// Moves accumulator $ax(1-D) to accumulator $axD. +// Moves accumulator $ac(1-D) to accumulator $acD. // // flags out: --x0 xx00 void DSPEmitter::mov(const UDSPInstruction opc) diff --git a/Source/Core/Core/DSP/Jit/x64/DSPJitBranch.cpp b/Source/Core/Core/DSP/Jit/x64/DSPJitBranch.cpp index 05dc6e672a..ea4df2a6fd 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPJitBranch.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPJitBranch.cpp @@ -156,9 +156,10 @@ void DSPEmitter::r_jmprcc(const UDSPInstruction opc) WriteBranchExit(); } // Generic jmpr implementation -// JMPcc $R +// JRcc $R // 0001 0111 rrr0 cccc -// Jump to address; set program counter to a value from register $R. +// Jump to address if condition cc has been met. Set program counter to +// a value from register $R. // NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit void DSPEmitter::jmprcc(const UDSPInstruction opc) { @@ -270,7 +271,7 @@ void DSPEmitter::rti(const UDSPInstruction opc) } // HALT -// 0000 0000 0020 0001 +// 0000 0000 0010 0001 // Stops execution of DSP code. Sets bit DSP_CR_HALT in register DREG_CR. void DSPEmitter::halt(const UDSPInstruction) { diff --git a/Source/Core/Core/DSP/Jit/x64/DSPJitExtOps.cpp b/Source/Core/Core/DSP/Jit/x64/DSPJitExtOps.cpp index 0df0a4037a..96147237c0 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPJitExtOps.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPJitExtOps.cpp @@ -9,7 +9,7 @@ using namespace Gen; /* It is safe to directly write to the address registers as they are - neither read not written by any extendable opcode. The same is true + neither read nor written by any extendable opcode. The same is true for memory accesses. It probably even is safe to write to all registers except for SR, ACx.x, AXx.x and PROD, which may be modified by the main op. @@ -131,7 +131,7 @@ void DSPEmitter::l(const UDSPInstruction opc) } // LN $axD.D, @$arS -// xxxx xxxx 01dd d0ss +// xxxx xxxx 01dd d1ss // Load $axD.D/$acD.D with value from memory pointed by register $arS. // Add indexing register $ixS to register $arS. void DSPEmitter::ln(const UDSPInstruction opc) @@ -354,16 +354,18 @@ void DSPEmitter::slnm(const UDSPInstruction opc) increase_addr_reg(DSP_REG_AR0, DSP_REG_AR0); } -// LD $ax0.d, $ax1.r, @$arS +// LD $ax0.D, $ax1.R, @$arS // xxxx xxxx 11dr 00ss -// example for "nx'ld $AX0.L, $AX1.L, @$AR3" -// Loads the word pointed by AR0 to AX0.H, then loads the word pointed by AR3 -// to AX0.L. Increments AR0 and AR3. If AR0 and AR3 point into the same -// memory page (upper 6 bits of addr are the same -> games are not doing that!) -// then the value pointed by AR0 is loaded to BOTH AX0.H and AX0.L. If AR0 -// points into an invalid memory page (ie 0x2000), then AX0.H keeps its old -// value. (not implemented yet) If AR3 points into an invalid memory page, then -// AX0.L gets the same value as AX0.H. (not implemented yet) +// Load register $ax0.D (either $ax0.l or $ax0.h) with value from memory pointed by register $arS. +// Load register $ax1.R (either $ax1.l or $ax1.h) with value from memory pointed by register $ar3. +// Increment both $arS and $ar3. +// S cannot be 3, as that encodes LDAX. Thus $arS and $ar3 are known to be distinct. +// If $ar0 and $ar3 point into the same memory page (upper 6 bits of addr are the same -> games are +// not doing that!) then the value pointed by $ar0 is loaded to BOTH $ax0.D and $ax1.R. +// If $ar0 points into an invalid memory page (ie 0x2000), then $ax0.D keeps its old value. (not +// implemented yet) +// If $ar3 points into an invalid memory page, then $ax1.R gets the same value as $ax0.D. (not +// implemented yet) void DSPEmitter::ld(const UDSPInstruction opc) { u8 dreg = (opc >> 5) & 0x1; @@ -396,6 +398,9 @@ void DSPEmitter::ld(const UDSPInstruction opc) // LDAX $axR, @$arS // xxxx xxxx 11sr 0011 +// Load register $axR.h with value from memory pointed by register $arS. +// Load register $axR.l with value from memory pointed by register $ar3. +// Increment both $arS and $ar3. void DSPEmitter::ldax(const UDSPInstruction opc) { u8 sreg = (opc >> 5) & 0x1; @@ -425,7 +430,7 @@ void DSPEmitter::ldax(const UDSPInstruction opc) increment_addr_reg(DSP_REG_AR3); } -// LDN $ax0.d, $ax1.r, @$arS +// LDN $ax0.D, $ax1.R, @$arS // xxxx xxxx 11dr 01ss void DSPEmitter::ldn(const UDSPInstruction opc) { @@ -488,7 +493,7 @@ void DSPEmitter::ldaxn(const UDSPInstruction opc) increment_addr_reg(DSP_REG_AR3); } -// LDM $ax0.d, $ax1.r, @$arS +// LDM $ax0.D, $ax1.R, @$arS // xxxx xxxx 11dr 10ss void DSPEmitter::ldm(const UDSPInstruction opc) { @@ -551,7 +556,7 @@ void DSPEmitter::ldaxm(const UDSPInstruction opc) increase_addr_reg(DSP_REG_AR3, DSP_REG_AR3); } -// LDNM $ax0.d, $ax1.r, @$arS +// LDNM $ax0.D, $ax1.R, @$arS // xxxx xxxx 11dr 11ss void DSPEmitter::ldnm(const UDSPInstruction opc) { diff --git a/Source/Core/Core/DSP/Jit/x64/DSPJitLoadStore.cpp b/Source/Core/Core/DSP/Jit/x64/DSPJitLoadStore.cpp index 11b4888735..7c60d6d1d2 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPJitLoadStore.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPJitLoadStore.cpp @@ -17,7 +17,6 @@ namespace DSP::JIT::x64 // Move value from register $(0x18+S) to data memory pointed by address // CR[0-7] | M. That is, the upper 8 bits of the address are the // bottom 8 bits from CR, and the lower 8 bits are from the 8-bit immediate. -// Note: pc+=2 in duddie's doc seems wrong void DSPEmitter::srs(const UDSPInstruction opc) { u8 reg = ((opc >> 8) & 0x7) + 0x18; @@ -105,9 +104,9 @@ void DSPEmitter::si(const UDSPInstruction opc) m_gpr.PutXReg(tmp1); } -// LRR $D, @$S +// LRR $D, @$arS // 0001 1000 0ssd dddd -// Move value from data memory pointed by addressing register $S to register $D. +// Move value from data memory pointed by addressing register $arS to register $D. void DSPEmitter::lrr(const UDSPInstruction opc) { u8 sreg = (opc >> 5) & 0x3; @@ -124,10 +123,10 @@ void DSPEmitter::lrr(const UDSPInstruction opc) dsp_conditional_extend_accum(dreg); } -// LRRD $D, @$S +// LRRD $D, @$arS // 0001 1000 1ssd dddd -// Move value from data memory pointed by addressing register $S to register $D. -// Decrement register $S. +// Move value from data memory pointed by addressing register $arS to register $D. +// Decrement register $arS. void DSPEmitter::lrrd(const UDSPInstruction opc) { u8 sreg = (opc >> 5) & 0x3; @@ -145,10 +144,10 @@ void DSPEmitter::lrrd(const UDSPInstruction opc) decrement_addr_reg(sreg); } -// LRRI $D, @$S +// LRRI $D, @$arS // 0001 1001 0ssd dddd -// Move value from data memory pointed by addressing register $S to register $D. -// Increment register $S. +// Move value from data memory pointed by addressing register $arS to register $D. +// Increment register $arS. void DSPEmitter::lrri(const UDSPInstruction opc) { u8 sreg = (opc >> 5) & 0x3; @@ -166,10 +165,10 @@ void DSPEmitter::lrri(const UDSPInstruction opc) increment_addr_reg(sreg); } -// LRRN $D, @$S +// LRRN $D, @$arS // 0001 1001 1ssd dddd -// Move value from data memory pointed by addressing register $S to register $D. -// Add indexing register $(0x4+S) to register $S. +// Move value from data memory pointed by addressing register $arS to register $D. +// Add indexing register $ixS to register $arS. void DSPEmitter::lrrn(const UDSPInstruction opc) { u8 sreg = (opc >> 5) & 0x3; @@ -187,10 +186,10 @@ void DSPEmitter::lrrn(const UDSPInstruction opc) increase_addr_reg(sreg, sreg); } -// SRR @$D, $S +// SRR @$arD, $S // 0001 1010 0dds ssss // Store value from source register $S to a memory location pointed by -// addressing register $D. +// addressing register $arD. void DSPEmitter::srr(const UDSPInstruction opc) { u8 dreg = (opc >> 5) & 0x3; @@ -205,10 +204,10 @@ void DSPEmitter::srr(const UDSPInstruction opc) m_gpr.PutXReg(tmp1); } -// SRRD @$D, $S +// SRRD @$arD, $S // 0001 1010 1dds ssss // Store value from source register $S to a memory location pointed by -// addressing register $D. Decrement register $D. +// addressing register $arD. Decrement register $arD. void DSPEmitter::srrd(const UDSPInstruction opc) { u8 dreg = (opc >> 5) & 0x3; @@ -225,10 +224,10 @@ void DSPEmitter::srrd(const UDSPInstruction opc) decrement_addr_reg(dreg); } -// SRRI @$D, $S +// SRRI @$arD, $S // 0001 1011 0dds ssss // Store value from source register $S to a memory location pointed by -// addressing register $D. Increment register $D. +// addressing register $arD. Increment register $arD. void DSPEmitter::srri(const UDSPInstruction opc) { u8 dreg = (opc >> 5) & 0x3; @@ -245,10 +244,10 @@ void DSPEmitter::srri(const UDSPInstruction opc) increment_addr_reg(dreg); } -// SRRN @$D, $S +// SRRN @$arD, $S // 0001 1011 1dds ssss // Store value from source register $S to a memory location pointed by -// addressing register $D. Add DSP_REG_IX0 register to register $D. +// addressing register $arD. Add corresponding indexing register $ixD to register $arD. void DSPEmitter::srrn(const UDSPInstruction opc) { u8 dreg = (opc >> 5) & 0x3; diff --git a/Source/Core/Core/DSP/Jit/x64/DSPJitMisc.cpp b/Source/Core/Core/DSP/Jit/x64/DSPJitMisc.cpp index 8115804b56..0e0dd087b4 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPJitMisc.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPJitMisc.cpp @@ -130,8 +130,8 @@ void DSPEmitter::clrCompileSR(u16 bit) } // SBCLR #I // 0001 0011 aaaa aiii -// bit of status register $sr. Bit number is calculated by adding 6 to -// immediate value I. +// Clear bit of status register $sr. Bit number is calculated by adding 6 to immediate value I; +// thus, bits 6 through 13 (LZ through AM) can be cleared with this instruction. void DSPEmitter::sbclr(const UDSPInstruction opc) { u8 bit = (opc & 0x7) + 6; @@ -141,8 +141,8 @@ void DSPEmitter::sbclr(const UDSPInstruction opc) // SBSET #I // 0001 0010 aaaa aiii -// Set bit of status register $sr. Bit number is calculated by adding 6 to -// immediate value I. +// Set bit of status register $sr. Bit number is calculated by adding 6 to immediate value I; +// thus, bits 6 through 13 (LZ through AM) can be set with this instruction. void DSPEmitter::sbset(const UDSPInstruction opc) { u8 bit = (opc & 0x7) + 6; diff --git a/Source/Core/Core/DSP/Jit/x64/DSPJitMultiplier.cpp b/Source/Core/Core/DSP/Jit/x64/DSPJitMultiplier.cpp index 41e0548146..efbd59d164 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPJitMultiplier.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPJitMultiplier.cpp @@ -416,7 +416,7 @@ void DSPEmitter::mulx(const UDSPInstruction opc) } // MULXAC $ax0.S, $ax1.T, $acR -// 101s t01r xxxx xxxx +// 101s t10r xxxx xxxx // Add product register to accumulator register $acR. Multiply one part // $ax0 by one part $ax1. Part is selected by S and // T bits. Zero selects low part, one selects high part. @@ -487,7 +487,7 @@ void DSPEmitter::mulxmv(const UDSPInstruction opc) m_gpr.PutXReg(tmp1); } -// MULXMV $ax0.S, $ax1.T, $acR +// MULXMVZ $ax0.S, $ax1.T, $acR // 101s t01r xxxx xxxx // Move product register to accumulator register $acR and clear (round) low part // of accumulator register $acR.l. Multiply one part $ax0 by one part $ax1 @@ -545,7 +545,7 @@ void DSPEmitter::mulc(const UDSPInstruction opc) } // MULCAC $acS.m, $axT.h, $acR -// 110s t10r xxxx xxxx +// 110s t10r xxxx xxxx // Multiply mid part of accumulator register $acS.m by high part $axS.h of // secondary accumulator $axS (treat them both as signed). Add product // register before multiplication to accumulator $acR. @@ -616,7 +616,7 @@ void DSPEmitter::mulcmv(const UDSPInstruction opc) } // MULCMVZ $acS.m, $axT.h, $acR -// 110s t01r xxxx xxxx +// 110s t01r xxxx xxxx // Multiply mid part of accumulator register $acS.m by high part $axT.h of // secondary accumulator $axT (treat them both as signed). Move product // register before multiplication to accumulator $acR, set (round) low part of