118 lines
4.8 KiB
TeX
118 lines
4.8 KiB
TeX
\documentclass[a4paper,12pt]{book}
|
||
\usepackage{tikz}
|
||
|
||
\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}
|
||
\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}
|
||
\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}
|
||
Instructions are fixed to exactly one byte (8 bits).
|
||
Instructions that work with two operands the register for operand one will be encoded in the three least significant bits. So an instruction with format XXXX X000 will use Register 1 and so forth all the way to XXXX X111, which will be Register 8.
|
||
\begin{figure}
|
||
\centering
|
||
\begin{tabular}{ c c }
|
||
\hline
|
||
Instruction & Register \\
|
||
\hline\hline
|
||
0000 0 & 000 \\
|
||
\hline
|
||
\end{tabular}
|
||
\caption{Encoding Layout}
|
||
\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.
|
||
\section{STOB (Store Byte)}
|
||
\OpcodeTable{0x20}{stob}{Register}{Address}\\[6pt]
|
||
Stores a single byte (the lower nibble) from a register to a memory address.
|
||
\section{STOW (Store Machine Word)}
|
||
\OpcodeTable{0x20}{stow}{Register}{Address}\\[6pt]
|
||
Stores a machine word from a register to a memory address.
|
||
\section{LODB (Load Byte)}
|
||
\OpcodeTable{0x20}{lodb}{Register}{Address}\\[6pt]
|
||
Loads a single byte into a register from a memory address, zeroing out the high nibble.
|
||
\section{LODW (Load Machine Word)}
|
||
\OpcodeTable{0x20}{lodw}{Register}{Address}\\[6pt]
|
||
Loads a word into a register from a memory address.
|
||
\section{LODBI (Load Immediate Byte)}
|
||
\OpcodeTable{0x00}{lodbi}{Register}{Constant}\\[6pt]
|
||
Loads an immediate byte into the register, zeroing the high nibble.
|
||
\section{LODWI (Load Immediate Word)}
|
||
\OpcodeTable{0x00}{lodwi}{Register}{Constant}\\[6pt]
|
||
Loads an immediate machine word into the register.
|
||
\section{CMP (Compare)}
|
||
\OpcodeTable{0x20}{cmp}{Register}{Register}\\[6pt]
|
||
Compares two registers and somewhere sets a result, maybe in register 1?
|
||
\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}{Address}{None}\\[6pt]
|
||
Jumps unconditionally to a memory address.
|
||
\section{JZ (Jump if Zero)}
|
||
\OpcodeTable{0x20}{jz}{Register}{None}\\[6pt]
|
||
Jumps to a memory address if some register is zero.
|
||
\section{JG (Jump if Greater Than)}
|
||
\OpcodeTable{0x70}{jg}{Address}{None}\\[6pt]
|
||
Jump to the Address if some register is greater than zero.
|
||
\section{JL (Jump if Less Than)}
|
||
\section{AND (Logical AND)}
|
||
\section{XOR (Logical Exclusive OR)}
|
||
\section{OR (Logical OR)}
|
||
\section{NOT (Logical Negation)}
|
||
\section{SHR (Shift Right)}
|
||
\section{SHL (Shift Left)}
|
||
\section{INC (Increment)}
|
||
\OpcodeTable{0x00}{inc}{Register}{None}
|
||
\section{DEC (Decrement)}
|
||
\OpcodeTable{0x00}{dec}{Register}{None}
|
||
|
||
\end{document}
|