\chapter{Introduction} This is an attempt to distill what I know about how computers work into some kind of emulator / simulator. I'm curious to see if what I know at the moment is enough to allow me too emulate a general purpose computer. It turns out that it take quite a different skill set compared to writing web or desktop applications. But I realize that, while I understand the concepts that underpin what I do day to day, I don't have an intuitive understanding of the hardware. This has become painfully evident pretty much immediately after I started this project. An ISA should be simple, add, subtract, copy, etc., but then you have to consider the state that the processor will be in after each instruction. \section{Conventions \& Data Types} This machine is \quotes{little endian} meaning bytes are numbered starting from the least significant byte or the right most byte. Figure \ref{fig:bytelayout} shows how a structure is layed out in memory byte by byte. \begin{figure}[h] \begin{tikzpicture} % Row 0 \node [draw, fit={( 0.0, 0.0) ( 2.0, 0.5)}, inner sep=0, label=center:byte 0] (row0b0) {}; \node [draw, fit={( 0.0, 0.0) (-2.0, 0.5)}, inner sep=0, label=center:byte 1] (row0b1) {}; \node [draw, fit={(-2.0, 0.0) (-4.0, 0.5)}, inner sep=0, label=center:byte 2] (row0b2) {}; \node [draw, fit={(-4.0, 0.0) (-6.0, 0.5)}, inner sep=0, label=center:byte 3] (row0b3) {}; % Row 1 \node [draw, fit={( 0.0, 0.5) (2.0, 1.0)}, inner sep=0] (row1b0) {}; \node [draw, fit={( 0.0, 0.5) (-2.0, 1.0)}, inner sep=0] (row1b1) {}; \node [draw, fit={(-2.0, 0.5) (-4.0, 1.0)}, inner sep=0] (row1b2) {}; \node [draw, fit={(-4.0, 0.5) (-6.0, 1.0)}, inner sep=0] (row1b3) {}; % Row 2 \node [draw, fit={( 0.0, 1.0) ( 2.0, 1.5)}, inner sep=0] (row2b0) {}; \node [draw, fit={( 0.0, 1.0) (-2.0, 1.5)}, inner sep=0] (row2b1) {}; \node [draw, fit={(-2.0, 1.0) (-4.0, 1.5)}, inner sep=0] (row2b2) {}; \node [draw, fit={(-4.0, 1.0) (-6.0, 1.5)}, inner sep=0] (row2b3) {}; % Draw Row 0 Byte Offset \node at (row0b0.east)[right] (offset) {0}; \node at (offset.south)[below] {Byte Offset}; %Draw Row 1 byte offset \node at (row1b0.east)[right] {4}; %Draw Row 2 bit offset label and bit positions \node at (row2b0.east)[right] {8}; % Byte offset \node at (row2b0.north east)[above] {0}; \node at (row2b0.north west)[above] {8 7}; % \node at (row2b1.north west)[above] {16 15}; % \node at (row2b2.north west)[above] {24 23}; % \node at (row2b3.north west)[above] (mostbit) {31}; \node at (mostbit.west)[left] {Bit Offset}; \end{tikzpicture} \caption{Layout of a Structure in Memory} \label{fig:bytelayout} \end{figure} There are three data types that are understood by this machine: byte, short and word. \begin{description} \item[Byte] An octet or a structure that is exactly 8-bits wide. \item[Short] To loosely borrow from C, a short is exactly two bytes or 16-bits wide. \item[Word] Exactly four bytes wide, or 32-bits. \end{description} \section{Registers} Thirty-two general purpose registers are available for program code to use however it wishes. The base name for the general purpose registers is \quotes{r} follows by an unpadded number, such as \quotes{r8}. These numbers do not follow a zero-based index scheme, \quotes{r29} is the twenty-ninth register. Using the base name implies full width, a \quotes{word}, when reading or writing from or to the register respectively. In addition to the general purpose registers there is also a base pointer (bp), stack pointer (sp) and an instruction pointer (ip). The base pointer and the stack pointer may be set directly using the \hyperref[sec:mov]{mov} instruction, which allows the programmer to set up a stack frame. The instruction pointer can only be set with a branching operation like \hyperref[sec:jmp]{jmp} or a call to a subroutine with the \hyperref[sec:call]{call} instruction. One final register that can only be indirectly set is the \quotes{flags} register. This register, like the others, is one word wide meaning it can store thirty-two flags. Currently only three flags are present, the Zero, Underflow and Overflow flags. These flags are only affected by arithmetic operations and generally read by branching instructions like \hyperref[sec:jmp]{jmp}. \begin{figure}[h] \begin{tikzpicture} %\draw[help lines] (-8,-3) grid (8,3); \node [draw, fit={(-6, 0) (-1, -0.5)}, label=center:r1] (r1) {}; \node [draw=none, fit={(-6, -1) (-1, -1.5)}, label=center:...] (ellipsis) {}; \node [draw, fit={(-6, -2) (-1, -2.5)}, label=center:r32] (r32) {}; \node [draw, fit={(-3.0, 1.5) (2.0, 1.0)}, label=center:Flags Register] (flags) {}; \node [draw, fit={(0, 0) (5, -0.5)}, label=center:Instruction Pointer (ip)] (ip) {}; \node [draw, fit={(0, -1.0) (5, -1.5)}, label=center:Base Pointer (ip)] (bp) {}; \node [draw, fit={(0, -2.0) (5, -2.5)}, label=center:Stack Pointer (ip)] (sp) {}; \draw (r1); \node at (r1.north) [above] {General Purpose}; \node at (r1.north west) [above] {31}; \node at (r1.north east) [above] {0}; \draw (ellipsis); \draw (r32); \draw (flags); \node at (flags.north) [above] {Status Register}; \node at (flags.north west) [above] {31}; \node at (flags.north east) [above] {0}; \draw (ip); \node at (ip.north) [above] {Program Status}; \node at (ip.north west) [above] {31}; \node at (ip.north east) [above] {0}; \draw (bp); \draw (sp); \end{tikzpicture} \caption{Bit Ordering} \label{fig:registerbitlayout} % https://www.overleaf.com/learn/latex/Referencing_Figures \end{figure} \begin{description} \item In summary, the available registers are as follows: \item[General Purpose] Thirty-two general purpose registers that are the width of a \textit{word} and numbered \quotes{r1} through \quotes{r32} \item[Base Pointer (bp)] Points to the call location when a function call is made \item[Stack Pointer (sp)] points to the end of the last argument after a function call is executed, which may be the return address of the stack \item[Instruction Pointer (ip)] Points to the next instruction to execute and advanced by the width of an instruction. Set by jump or call instructions to the location specified by the instruction. \end{description} \section{Memory} The memory layout is quite simple, much like many modern machines it is a linear memory map. The address bus is thirty-two bits wide, the same width of the data bus, meaning at most there is 2\textsuperscript{32} of addressable memory. Like contemporary machines the top of memory starts at address 0x00000000 and grows downward toward 0xFFFFFFFF. By default the memory is mapped as shown in Figure \ref{fig:memorylayout}. % How memory mapped I/O works: https://superuser.com/questions/595672/how-is-memory-mapped-to-certain-hardware-how-is-mmio-accomplished-exactly \begin{figure} \begin{tikzpicture} \node [draw, fit={(0,0) (3, 6)}] (memory) {}; \draw (memory); \node (top) at (memory.north east)[right] {0x00000000}; \node at (memory.south east)[right] {0xFFFFFFFF}; \draw[->] ($(memory.west)-(0.5,-0.25)$)[left] -- ($(memory.north west)-(0.5,0.0)$)[left] node[midway, left] {Stack}; \draw[->] ($(memory.west)-(0.5, 0.25)$)[left] -- ($(memory.south west)-(0.5,0.0)$)[above] node[midway, left] {Heap}; %\draw[dashed] ($(memory.north west)-(0.0,0.5)$) node[left] {0x000800} -- ($(memory.north east)-(0.0,0.5)$) node[midway, above] {IVT - 2kb}; %\draw[dashed] ($(memory.north west)-(0.0,1.0)$) -- ($(memory.north east)-(0.0,1.0)$) node[right] {0x200800} node[midway, above] {Firmware - 2MiB}; %\draw[dashed] ($(memory.north west)-(0.0,1.5)$) node[left] {0x276100} -- ($(memory.north east)-(0.0,1.5)$) node[midway, above] {VRAM - 3.75MiB}; \end{tikzpicture} \caption{Memory Map \& Layout} \label{fig:memorylayout} % https://www.overleaf.com/learn/latex/Referencing_Figures \end{figure}