Files
lang/chapter 1.tex
T

134 lines
9.0 KiB
TeX

\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. This \quotes{little} project will be a specification for a sort of System-on-Chip (SoC) where the CPU, GPU and memory are all inter-connected.
\section{Conventions \& Data Types}
\label{sec:conventions}
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]
\label{fig:bytelayout} % https://www.overleaf.com/learn/latex/Referencing_Figures
\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}
\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.
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]
\label{fig:registerbitlayout} % https://www.overleaf.com/learn/latex/Referencing_Figures
\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) {};
\node at (r1.north) [above] {General Purpose};
\node at (r1.north west) [above] {31};
\node at (r1.north east) [above] {0};
\node at (flags.north) [above] {Status Register};
\node at (flags.north west) [above] {31};
\node at (flags.north east) [above] {0};
\node at (ip.north) [above] {Program Status};
\node at (ip.north west) [above] {31};
\node at (ip.north east) [above] {0};
\end{tikzpicture}
\caption{Bit Ordering}
\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}
Memory is laid out as a contiguous linear block for a total of 2\textsuperscript{32} bytes of addressable memory. Addressing starts at 0x00000000 and grows downward toward 0xFFFFFFFF as shown in Figure \ref{fig:memoryhighlow}. The figure also shows the direction the stack grows along with the heap, which grows in the opposite direction. For a quick reference to the initial mapped memory see Figure \ref{fig:memorymap}.
% 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}[h]
\label{fig:memoryhighlow} % https://www.overleaf.com/learn/latex/Referencing_Figures
\begin{tikzpicture}
\node [draw, fit={(0,0) (3, 6)}] (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 Layout}
\end{figure}
\section{Device Initialization \& Firmware}
On initialization the CPU will load firmware from read-only memory, or \quotes{ROM}, starting at address 0xFFDFFFFF and ending at 0xFFFFFFFF. From there the firmware will perform basic setup routines like creating the interrupt table, mapping HID and constructing the \quotes{Devicetree}. The Devicetree that is built adheres to the \quotes{Devicetree} specification (\url{https://www.devicetree.org/specifications}) allowing for an agnostic way of providing information about the machine be it to a bootloader or an operating system. Figure \ref{fig:memorymap} shows how the memory is setup after the firmware has completed initialization and proceeds to look for bootable media.
\begin{figure}[h]
\label{fig:memorymap} % https://www.overleaf.com/learn/latex/Referencing_Figures
\begin{tabularx}{\textwidth}{ | c | c | X | X | }
\hline
Start & End & Used For & Remark \\
\hline
0x00000000 & 0x000003FC & Interrupt Table & 255 Word Entries \\
\hline
0x00000400 & 0x002003FC & Devicetree & 2MiB - One Word\\
\hline
0x00200400 & 0x002004FF & Keyboard Buffer & 255 Chars \\
\hline
0x00200500 & 0x002024C0 & Video Buffer & 127 x 64 Col x Row \\
\hline
0xFFDFFFFF & 0xFFFFFFFF & Firmware & 2MiB \\
\hline
\end{tabularx}
\caption{Initial Memory Map}
\end{figure}