\chapter{Instruction Set Architecture}

\newcommand{\OpcodeTable}[5] {
	\noindent
	\begin{minipage}{\textwidth}
		\begin{tabularx}{\textwidth}{ | X | X | X | X | }
			\hline
			Opcode Hex & Instruction & Operand 1 & Operand 2 \\
			\hline
			#1 & #2 & #3 & #4 \\
			\hline
		\end{tabularx}
		\paragraph{Description} #5
	\end{minipage}
}

\def\minY{-1.5em} \def\maxY{1.5em}
\def\minX{-7} \def\maxX{7}

\section{Encoding Scheme}
All instructions are a fixed width of 32-bits. There are two basic encoding schemes that the object code will take. The most basic layout is shown in Figure \ref{fig:OpShortEncodingFigure} that is used by instructions that take one or zero arguments, where the 16 most significant bits are used to encode the instruction itself. Followed by the 16 least significant bits being used to encode a numeric constant that may be interpreted as a relative address. For instructions that require two arguments the encoding scheme shown in Figure \ref{fig:OpArgEncodingFigure} is used.
% Placement info here: https://en.wikibooks.org/wiki/LaTeX/Floats,_Figures_and_Captions#Figures
% Paths: https://tikz.dev/tikz-paths
\begin{figure}
	\begin{tikzpicture}
		\draw (-8, 0) -- (-4, 0) node[midway, below=1em] {Opcode};
		\draw (-8, -0.25) -- (-8, 0.25) node[above] {7};
		\draw (-4, -0.25) -- (-4, 0.25) node[above] {0};
		\draw [dashed] (-3.75, 0) -- (0, 0) node[midway, above=1em] {Mode Setting};
		\draw (-3.75, -0.25) node[below] {7} -- (-3.75, 0.25);
		\draw (0, -0.25) node[below] {0} -- (0, 0.25);
	\end{tikzpicture}
	\caption{Encoding}
	\label{fig:opencoding} % https://www.overleaf.com/learn/latex/Referencing_Figures
	\paragraph{Note} The dotted line showing the \textit{Mode Setting} byte can be optional in some instructions.
\end{figure}


\begin{figure}
	\begin{tikzpicture}
		\draw (\minX, 0) -- (\maxX, 0);
		\draw (\minX, \minY / 2) -- (\minX, \maxY / 2); %{$y$}; Note the $'s, those make something math stylized.
		\draw (0, \minY / 2) -- (0, \maxY / 2); % Halfway mark
		\draw (\maxX, \minY / 2) -- (\maxX, \maxY / 2);
		\draw (\minX, -\maxY) node[below=1em] {31} [decorate, decoration={brace, amplitude=1em, mirror}] -- (0, -\maxY) node[below=1em] {16} node[midway, below=1em] {Op Code (16-bits)};
		\draw (0, \maxY) node[above=1em] {15} [decorate, decoration={brace, amplitude=1em}] -- (\maxX, \maxY) node[above=1em] {0} node[midway, above=1em] {Near Address (16-bits)};
	\end{tikzpicture}
	\caption{Short Valued Opcodes}
	\label{fig:OpShortEncodingFigure} % https://www.overleaf.com/learn/latex/Referencing_Figures
\end{figure}
\begin{figure}
	\begin{tikzpicture}
		\draw (\minX, 0) -- (\maxX, 0);
		\draw (\minX, \minY / 2) -- (\minX, \maxY / 2); %{$y$}; Note the $'s, those make something math stylized.
		\draw (0, \minY / 2) -- (0, \maxY / 2); % Halfway mark
		\draw (\maxX, \minY / 2) -- (\maxX, \maxY / 2);
		\draw (\maxX / 2, \minY / 2) -- (\maxX / 2, \maxY / 2); % Halfway mark for the lower 16 bits
		\draw (\minX, -\maxY) node[below=1em] {31} [decorate, decoration={brace, amplitude=1em, mirror}] -- (0, -\maxY) node[below=1em] {16} node[midway, below=1em] {Op Code (16-bits)};
		\draw (0, \maxY) node[above=1em] {15} [decorate, decoration={brace, amplitude=1em}] -- (\maxX / 2, \maxY) node[above=1em] {8} node[midway, above=1em] {Destination};
		\draw (\maxX / 2, -\maxY) node[below=1em] {7} [decorate, decoration={brace, amplitude=1em, mirror}] -- (\maxX, -\maxY) node[below=1em] {0} node[midway, below=1em] {Source};
	\end{tikzpicture}
	\caption{Register Based Opcodes}
	\label{fig:OpArgEncodingFigure} % https://www.overleaf.com/learn/latex/Referencing_Figures
	\paragraph{Note} How the \textit{Destination} and \textit{Source} are interpreted is dependent on the opcode and operand mode bits as shown in Figure \ref{fig:AddressingModeBitPattern}.
\end{figure}
\begin{figure}
	\begin{tabularx}{\textwidth}{ | X | X | X | }
		\hline
		Bit Pattern & Destination & Source \\
		\hline
		0000 & Register & Register \\
		0001 & Register & 8 Bit Immediate \\
		0010 & Register & 32 Bit Immediate \\
		0011 & 8 Bit Immediate & Register \\
		0100 & 32 Bit Immediate & Register \\
		\hline
	\end{tabularx}
	\caption{Addressing Mode}
	\label{fig:AddressingModeBitPattern}
	\paragraph{Note} The \textit{Immediate} values could represent an address (if 8-bit, relative otherwise 32-bit values will represent absolute addresses) or a numeric constant. 
\end{figure}

\clearpage
\section{Instructions}
The /r represents a byte that specifies a register. /iX is for the immediate data type, where \textit{X} defines the width, which are 8, 16, or 32 bits.
\subsection{Add}
\OpcodeTable{01 /r /r}{add /r, /r}{Register}{Register}{Sums \textit{Operand 1} and \textit{Operand 2} placing the result into \textit{Operand 1}.}
\subsection{Sub}
\OpcodeTable{01 /r /r}{sub /r, /r}{Register}{Register}{Subtracts \textit{Operand 1} and \textit{Operand 2} placing the result into \textit{Operand 1}.}
\subsection{Mul}
\OpcodeTable{01 /r /r}{mul /r, /r}{Register}{Register}{Multiplies \textit{Operand 1} and \textit{Operand 2} placing the result into \textit{Operand 1}.}
\subsection{Div}
\OpcodeTable{01 /r /r}{div /r, /r}{Register}{Register}{Divides \textit{Operand 1} and \textit{Operand 2} placing the result into \textit{Operand 1}.}
\subsection{Mov}
\OpcodeTable{04 /mod /r /r}{mov /mod /r, /r}{Register}{Register}{Copies the 32-bit value from \textit{Operand 2} to \textit{Operand 1}.}
\subsection{AND}
\OpcodeTable{01 /r /r}{and /r, /r}{Register}{Register}{Bit-wise ANDs \textit{Operand 1} and \textit{Operand 2} placing the result into \textit{Operand 1}.}
\subsection{OR}
\OpcodeTable{01 /r /r}{or /r, /r}{Register}{Register}{Bit-wise ORs \textit{Operand 1} and \textit{Operand 2} placing the result into \textit{Operand 1}.}
\subsection{XOR}
\OpcodeTable{01 /r /r}{xor /r, /r}{Register}{Register}{Bit-wise exclusive ORs \textit{Operand 1} and \textit{Operand 2} placing the result into \textit{Operand 1}.}
\subsection{NOT}
\OpcodeTable{01 /r}{not /r}{Register}{None}{Bit-wise negates \textit{Operand 1} placing the result into \textit{Operand 1}.}
\subsection{SHL}
\OpcodeTable{01 /r /i8}{shl /r, /i8}{Register}{Immediate}{Shifts the bits of \textit{Operand 1} left \textit{Operand 2} times.}
\subsection{SHR}
\OpcodeTable{01 /r /i8}{shr /r, /i8}{Register}{Immediate}{Shifts the bits of \textit{Operand 1} right \textit{Operand 2} times.}

\subsection{NOP}
\OpcodeTable{01}{nop}{None}{None}{No operation, increments the Program Counter by one.}
%Oh this control flow will be interesting, juggling flags is not something I'm used to.
\subsection{CMP}
\OpcodeTable{01 /mod /r /r}{cmp /r, /r}{Register}{Register}{Subtracts \textit{Operand 2} from \textit{Operand 1} setting the Zero Flag if the result is zero. If \textit{Operand 2} is larger then the Sign Flag is set, otherwise the Sign Flag will be cleared.}
\subsection{JMP}
\OpcodeTable{01 /mod /i32}{jmp /i32}{Immediate}{None}{Unconditionally jumps to address \textit{Operand 1}.}
\subsection{JZ}
\OpcodeTable{01 /i32}{jz /i32}{Immediate}{None}{Jumps to address \textit{Operand 1} if the Zero Flag is set.}
\subsection{JG}
\OpcodeTable{01 /mod /i32}{jg /i32}{Immediate}{None}{Jumps to address \textit{Operand 1} if the Sign Flag is set.}
\subsection{JL}
\OpcodeTable{01 /mod /i32}{jl /i32}{Immediate}{None}{Jumps to address \textit{Operand 1} if the Sign Flag is not set.}

%Maybe these in/out instructions could have a mode setting for choosing the width of the data written to the port.
\subsection{Outb}
\OpcodeTable{01 /r /r}{add /r, /r}{8-Bit}{Register}{Writes an 8-bit value from \textit{Operand 2} into port number \textit{Operand 1}.}
\subsection{Inb}
\OpcodeTable{01 /r /r}{inb /r, /r}{Register}{8-Bit}{Reads an 8-bit byte from the port number \textit{Operand 2}, writing it into \textit{Operand 1}.}

\subsection{HLT}
\OpcodeTable{01}{hlt}{None}{None}{Halts the processor until a new interrupt is received.}
\subsection{CLI}
\OpcodeTable{01}{cli}{None}{None}{Clears the interrupt flag preventing the processor from receiving interrupts.}
\subsection{ENI}
\OpcodeTable{01}{eni}{None}{None}{Sets the interrupt flag allowing the processor to receive interrupts.}
\subsection{INT}
\OpcodeTable{01 /i8}{int /i8}{Immediate}{None}{Triggers software interrupt number \textit{Operand 1}.}