\documentclass[a4paper,12pt]{book}
\usepackage{tikz}
\usepackage{hyperref}
\hypersetup{
	linktoc=all
}

\title{Unnamed Machine}
\author{A Very Terrible 16-bit Machine}

\newcommand{\OpcodeTable}[4] {
	\begin{tabular}{ c c c c }
		\hline
		Opcode & Mnemonic & Operand 1 & Operand 2 \\
		\hline\hline
		#1 & #2 & #3 & #4 \\
		\hline
	\end{tabular}
}

\begin{document}
	\maketitle
	\tableofcontents
	\chapter{Overview}
	\section{Introduction}
	This is a very poorly thought out 16-bit machine, but you've got to start somewhere. Currently debating between a CPU status register, 80x86 style, or just placing arithmetic results into a predetermined register. This is more of a load–store architecture to try and keep the instruction set simple. The machine will be big-endian.
	\section{Registers}
	The following are the general purpose registers that can be used.
	\begin{itemize}
		\item[] R1
		\item[] ...
		\item[] R8
	\end{itemize}
	Additionally, there will be a special status register that will be a signed 16 bit register that the compare and jump instructions will read or write to when determining what action, if any, they'll take.
	\section{Memory Model}
	Memory will be implicitly mapped I/O. The bottom 3201 bytes of memory will be reserved for the keyboard input and graphics.
	A single byte is reserved for the keyboard's input. The current key will be stored in byte 0xF37E, with the most significant bit being a flag indicating that the keyboard 
	is ready to be read from. This means that the character encoding is actually 7 bits.
	Video memory starts at 0xF37F (62335 decimal), and every byte represents an ASCII character in monochrome.
	\begin{figure}[!htb]
		\centering
		\begin{tikzpicture}
			\fill[gray!5] (0,0)rectangle(5,10);
			%\draw (0,10) .. controls (-2,6) and (-2,4) .. (0,1);
			%\draw (0,10) arc (0:180:3cm);
			\draw (0,10) -- (5,10);
			\draw (0,1) --  node[above] {Video 0xF37F} (5,1);
			\draw (0,0) -- (5,0);
			\node[label=right:Top 0x0000] at (5,10) {};
			\node[label=right:Bottom 0xFFFF] at (5,0) {};
		\end{tikzpicture}
		\caption{Memory Layout}
	\end{figure}
	\chapter{Instruction Set Architecture}
	\section{Instruction Encoding}
	The instruction encoding is fixed width to exactly 8 bites wide.
	The encoding for the instructions will differ depending on if the opcode requires a register as its first operand.
	For instructions that require, as their first argument, a register the encoding format will be as shown in Figure \ref{fig:WithRegister}.
	The lower 3 bits may be any bit pattern as long as at least one bit is set in the upper 5 bits.
	%https://tex.stackexchange.com/questions/32598/force-latex-image-to-appear-in-the-section-in-which-its-declared	
	\begin{figure}[!htb]
		\centering
		\begin{tabular}{ c c }
			Instruction & Register \\
			\hline
			XXXX X & 000 \\
			\hline
		\end{tabular}
		\caption{Encoding Layout, Register Required}
		\label{fig:WithRegister}
	\end{figure}

	Figure \ref{fig:NoRegisterEncoding} shows how encoding will look for instructions that lack arguments or do not require a register.
	In contrast with the previous encoding scheme the upper 5 bits MUST be zero, allowing 7 possible instructions to use this format.
	All zeroes is not considered a legal instruction.

	\begin{figure}[!htb]
	\centering
	\begin{tabular}{ c c }
		Must Be Zero & Instruction \\
		\hline
		0000 0 & XXX \\
		\hline
	\end{tabular}
	\caption{Encoding Layout, Register Required}
	\label{fig:NoRegisterEncoding}
\end{figure}
	
	\section{Notes}
	For the opcodes that load or store data at the assembly language level we could have the mnemonics
	"store" and "load" and have the assembler pick the opcode based on the inclusion of the word "byte" 
	or "word" for two bytes. That would make the assembly easier to read but put a bit more work on the
	assembler. The Stack Pointer will start 2 bytes above the video memory start.
	\section{STOB (Store Byte)}
		\OpcodeTable{0x20}{stob}{Register}{Register}\\[6pt]
		Stores a single byte (the lower nibble) from a register to a memory address store in a register.
	\section{STOW (Store Machine Word)}
		\OpcodeTable{0x20}{stow}{Register}{Register}\\[6pt]
		Stores a machine word from a register to a memory address stored in a register.
	\section{LAA (Load Absolute Address)}
		\OpcodeTable{0x00}{laa}{Register}{Address}\\[6pt]
		Loads an address (2 bytes) into the register.
	\section{LODB (Load Byte)}
		\OpcodeTable{0x20}{lodb}{Register}{Register}\\[6pt]
		Loads a single byte into a register from a memory address in the second operand register, zeroing out the high nibble.
	\section{LODW (Load Machine Word)}
		\OpcodeTable{0x20}{lodw}{Register}{Register}\\[6pt]
		Loads a word into a register from a memory address in the second operand register.
	\section{LODWI (Load Immediate Word)}
		\OpcodeTable{0x00}{lodwi}{Register}{Constant}\\[6pt]
		Loads an immediate machine word into the register clearing the high nibble if the value is less then 256.
	\section{CMP (Compare)}
		\OpcodeTable{0x20}{cmp}{Register}{Register}\\[6pt]
		Compares two registers and somewhere sets a result in the status register.
	\section{CMPI (Compare Immediate)}
		\OpcodeTable{0x00}{cmpi}{Register}{Constant}\\[6pt]
		Compares an immediate 2 byte value to the contents of a register setting the status register accordingly.
	\section{ADD (Add)}
		\OpcodeTable{0x20}{add}{Register}{Register}\\[6pt]
		Performs addition on a register with a value from another (or the same) register.
	\section{SUB (Subtract)}
		\OpcodeTable{0x20}{sub}{Register}{Register}\\[6pt]
		Performs subtraction on a register with a value from another (or the same) register.
	\section{JMP (Jump)}
		\OpcodeTable{0x20}{jmp}{Register}{None}\\[6pt]
		Jumps unconditionally to a memory address. Sets the Program Counter to Address.
	\section{JZ (Jump if Zero)}
		\OpcodeTable{0x20}{jz}{Register}{None}\\[6pt]
		Jumps to a memory address if the status flag is zero.
	\section{JG (Jump if Greater Than)}
		\OpcodeTable{0x70}{jg}{Register}{None}\\[6pt]
		Jump to the Address if the status flag is greater than zero.
	\section{JL (Jump if Less Than)}
		\OpcodeTable{0x00}{jl}{Register}{None}\\[6pt]
		Jumps to the address if the status flag is less than zero.
	\section{JMPA (Jump to Address)}
		\OpcodeTable{0x20}{jmpa}{Address}{None}\\[6pt]
		Jumps unconditionally to a memory address. Sets the Program Counter to Address.
	\section{JZA (Jump to Address if Zero)}
		\OpcodeTable{0x20}{jza}{Address}{None}\\[6pt]
		Jumps to a memory address if the status flag is zero.
	\section{JGA (Jump to Address if Greater Than)}
		\OpcodeTable{0x70}{jga}{Address}{None}\\[6pt]
		Jump to the Address if the status flag is greater than zero.
	\section{JLA (Jump to Address if Less Than)}
		\OpcodeTable{0x00}{jla}{Address}{None}\\[6pt]
		Jumps to the address if the status flag is less than zero.
	\section{AND (Logical AND)}
		\OpcodeTable{0x00}{and}{Register}{Register}\\[6pt]
		Logical ANDs the two registers together storing the result in operand 1.
	\section{XOR (Logical Exclusive OR)}
		\OpcodeTable{0x00}{xor}{Register}{Register}\\[6pt]
		Logical XORs the two registers together storing the result in operand 1.
	\section{OR (Logical OR)}
		\OpcodeTable{0x00}{or}{Register}{Register}\\[6pt]
		Logical ORs the two registers together storing the result in operand 1.
	\section{NOT (Logical Negation)}
		\OpcodeTable{0x00}{not}{Register}{None}\\[6pt]
		Inverts the bits of the target register.
	\section{SHR (Shift Right)}
		\OpcodeTable{0x00}{shr}{Register}{Constant}\\[6pt]
		Bit-wise shifts the contents of the register right Constant number of times.
	\section{SHL (Shift Left)}
		\OpcodeTable{0x00}{shl}{Register}{Constant}\\[6pt]
		Bit-wise shifts the contents of the register left Constant number of times.
	\section{INC (Increment)}
		\OpcodeTable{0x00}{inc}{Register}{None}\\[6pt]
		Increments the contents of the register by one. Over-flows will not be reported.
	\section{DEC (Decrement)}
		\OpcodeTable{0x00}{dec}{Register}{None}\\[6pt]
		Decrements the contents of the register by one. Under-flows will not be reported.
	\section{NOP (No Operation)}
		\OpcodeTable{0x00}{nop}{None}{None}\\[6pt]
		Skips a clock cycle, incrementing the program counter.
	\section{Push}
		\OpcodeTable{0x00}{push}{Register}{None}
		Pushes the value of Register onto the stack, decrementing the Stack Pointer by 2.
	\section{Pop}
		\OpcodeTable{0x00}{pop}{Register}{None}
		Pops the top of the stack into Register, incrementing the Stack Pointer by 2.
\end{document}
