241 lines
7.8 KiB
TeX
241 lines
7.8 KiB
TeX
\documentclass{report}
|
|
\usepackage{hyperref}
|
|
%\usepackage{dirtytalk}
|
|
\usepackage{scrextend}
|
|
\usepackage{graphicx}
|
|
%\usepackage{wrapfig}
|
|
\usepackage{minted}
|
|
\usepackage[svgnames]{xcolor}
|
|
\usepackage[T1]{fontenc}
|
|
\usepackage{inconsolata}
|
|
|
|
\title{Dreamcast from scratch the hard way}
|
|
\hypersetup{colorlinks=true,urlcolor=blue}
|
|
|
|
\begin{document}
|
|
\maketitle
|
|
\tableofcontents
|
|
|
|
\chapter{Motivation}
|
|
\begin{listing}[H]
|
|
\begin{minted}[bgcolor=Beige, bgcolorpadding=0.5em]{C}
|
|
int main() {
|
|
printf("hello, world");
|
|
return 0;
|
|
}
|
|
\end{minted}
|
|
\caption{Example of a listing.}
|
|
\label{lst:example}
|
|
\end{listing}
|
|
|
|
\chapter{Toolchain}
|
|
This section shows how to build and install a toolchain for compiling C and C++
|
|
source code to SH4 (Dreamcast) binaries.
|
|
|
|
\section{Toolchain download}
|
|
|
|
Download and extract source archives for Binutils and GCC; this could be done for example like this:
|
|
|
|
\begin{listing}[H]
|
|
\begin{minted}[bgcolor=Beige, bgcolorpadding=0.5em]{shell}
|
|
cd ~
|
|
|
|
curl -LO https://ftp.gnu.org/gnu/binutils/binutils-2.45.tar.xz
|
|
curl -LO https://ftp.gnu.org/gnu/gcc/gcc-15.1.0/gcc-15.1.0.tar.xz
|
|
|
|
tar xJf binutils-2.45.tar.xz
|
|
tar xJf gcc-15.1.0.tar.xz
|
|
\end{minted}
|
|
\caption{Toolchain download and extract}
|
|
\label{lst:toolchain-download-extract}
|
|
\end{listing}
|
|
|
|
\section{Binutils configuration}
|
|
|
|
The binutils configuration script is easy to invoke. The only option needed is:
|
|
|
|
\begin{minted}[bgcolor=Beige, bgcolorpadding=0.5em]{shell}
|
|
--target=sh4-none-elf
|
|
\end{minted}
|
|
|
|
The \texttt{target} option causes the binutils build system to create a
|
|
cross-assembler\footnote{assuming you aren't running binutils on a computer that
|
|
also contains an SH4 CPU} that is capable of generating code for the SH4
|
|
(Dreamcast) CPU. This also causes all installed commands to be prefixed with
|
|
\texttt{sh4-none-elf-}, for example: \texttt{sh4-none-elf-ld} for the binutils
|
|
linker.
|
|
|
|
These ``target triples'' are underdocumented.
|
|
|
|
While nearly any \texttt{sh*-*-*} triplet would have worked, a secondary goal of
|
|
choosing this specific triplet is to not conflict with the name chosen for the
|
|
KallistiOS toolchain, \texttt{sh-elf}.
|
|
|
|
The complete configure command is:
|
|
|
|
\begin{listing}[H]
|
|
\begin{minted}[bgcolor=Beige, bgcolorpadding=0.5em]{shell}
|
|
mkdir ~/binutils-2.45/build
|
|
cd ~/binutils-2.45/build
|
|
../configure --target=sh4-none-elf
|
|
\end{minted}
|
|
\caption{Binutils configure}
|
|
\label{lst:binutils-configure}
|
|
\end{listing}
|
|
|
|
\section{Binutils build and install}
|
|
|
|
Build and install binutils with:
|
|
|
|
\begin{listing}[H]
|
|
\begin{minted}[bgcolor=Beige, bgcolorpadding=0.5em]{shell}
|
|
cd ~/binutils-2.45/build
|
|
|
|
make -j$(nproc)
|
|
|
|
make install
|
|
\end{minted}
|
|
\caption{Binutils build and install}
|
|
\label{lst:binutils-build-install}
|
|
\end{listing}
|
|
|
|
You may need to prefix the \texttt{make install} command with \texttt{sudo} or
|
|
\texttt{su} depending on your system.
|
|
|
|
Note that binutils must be installed correctly prior to proceeding. You can test
|
|
this by running the command \texttt{sh4-none-elf-ld -v}. If
|
|
\texttt{sh4-none-elf} binutils is properly installed, you will get output
|
|
identical to:
|
|
|
|
\begin{minted}[bgcolor=Beige, bgcolorpadding=0.5em]{shell}
|
|
GNU ld (GNU Binutils) 2.45
|
|
\end{minted}
|
|
|
|
\section{GCC configuration}
|
|
The GCC we will build in particular will have no support for linking with
|
|
a C standard library. In Dreamcast game development, the C standard library
|
|
isn't particularly useful (e.g: string manipulation functions are hardly used).
|
|
|
|
Anything we do need that we could have used from the C standard library we will
|
|
reimplement ourselves.
|
|
|
|
While it is obvious that the GCC developers don't support this use-case as well
|
|
as they could, the only problem occurs when GCC automatically emits a call to
|
|
\texttt{memcpy} or \texttt{memzero} in code that did not explicitly call either.
|
|
Most of the time, such calls can be removed by changing optimization levels or
|
|
refactoring code. In other cases, it may be situationally convenient to
|
|
implement either as trivial one-line loops.
|
|
|
|
To compile gcc, invoke the \texttt{./configure} script with the appropriate
|
|
options. Here are explanations for a few of the more interesting options:
|
|
|
|
\begin{minted}[bgcolor=Beige, bgcolorpadding=0.5em]{shell}
|
|
--with-endian=little
|
|
\end{minted}
|
|
|
|
The SH4 CPU in the Dreamcast is jumpered to little endian mode, and CPU
|
|
endianness is not reconfigurable without physical modification.
|
|
|
|
\begin{minted}[bgcolor=Beige, bgcolorpadding=0.5em]{shell}
|
|
--with-cpu=m4-single
|
|
\end{minted}
|
|
|
|
\texttt{m4-single} is a floating point calling convention where functions assume
|
|
the SH4 CPU is in ``single precision'' mode on function entry. In this ABI,
|
|
functions that use double precision operations require extra instructions (and
|
|
CPU cycles) to switch to double precision mode on function entry, and switch
|
|
back to single precision mode prior to function return.
|
|
|
|
\begin{minted}[bgcolor=Beige, bgcolorpadding=0.5em]{shell}
|
|
--disable-hosted-libstdcxx
|
|
\end{minted}
|
|
|
|
This disables all libstdcxx features that depend on exceptions and heap
|
|
allocation. For example, \texttt{<list>} and \texttt{<vector>} are not
|
|
available, but \texttt{<bit>} and \texttt{<type\_traits>} are available.
|
|
|
|
The cppreference.com article on
|
|
\href{https://en.cppreference.com/w/cpp/freestanding.html}{freestanding} has
|
|
more information on which features are (not) available with a freestanding
|
|
libstdc++ build.
|
|
|
|
The complete configure command is:
|
|
|
|
\begin{listing}[H]
|
|
\begin{minted}[bgcolor=Beige, bgcolorpadding=0.5em]{shell}
|
|
mkdir ~/gcc-15.1.0/build
|
|
cd ~/gcc-15.1.0/build
|
|
../configure \
|
|
--target=sh4-none-elf \
|
|
--with-endian=little \
|
|
--with-cpu=m4-single \
|
|
--without-newlib \
|
|
--without-headers \
|
|
--disable-nls \
|
|
--disable-shared \
|
|
--disable-multilib \
|
|
--disable-decimal-float \
|
|
--disable-threads \
|
|
--disable-libatomic \
|
|
--disable-libgomp \
|
|
--disable-libquadmath \
|
|
--disable-libssp \
|
|
--disable-libvtv \
|
|
--disable-hosted-libstdcxx \
|
|
--disable-libstdcxx-pch \
|
|
--disable-libstdcxx-verbose \
|
|
--disable-libstdcxx-filesystem-ts \
|
|
--disable-libstdcxx-threads \
|
|
--disable-libstdcxx-backtrace \
|
|
--enable-languages=c,c++ \
|
|
--disable-bootstrap
|
|
\end{minted}
|
|
\caption{GCC configure}
|
|
\label{lst:gcc-configure}
|
|
\end{listing}
|
|
|
|
\section{GCC build and install}
|
|
|
|
Build and install gcc with:
|
|
|
|
\begin{listing}[H]
|
|
\begin{minted}[bgcolor=Beige, bgcolorpadding=0.5em]{shell}
|
|
cd ~/gcc-15.1.0/build
|
|
|
|
make -j$(nproc)
|
|
|
|
make install
|
|
\end{minted}
|
|
\caption{GCC build and install}
|
|
\label{lst:gcc-build-install}
|
|
\end{listing}
|
|
|
|
You will notice that the time required to build GCC is significantly longer than
|
|
the time required to build binutils.
|
|
|
|
You may need to prefix the \texttt{make install} command with \texttt{sudo} or
|
|
\texttt{su} depending on your system.
|
|
|
|
If installed correctly, you should be able to run the \texttt{sh4-none-elf-gcc -v}
|
|
command, which should produce output identical to:
|
|
|
|
\begin{minted}[bgcolor=Beige, bgcolorpadding=0.5em, breaklines, breakanywhere]{text}
|
|
Using built-in specs.
|
|
COLLECT_GCC=sh4-none-elf-gcc
|
|
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/sh4-none-elf/15.1.0/lto-wrapper
|
|
Target: sh4-none-elf
|
|
Configured with: ../configure --target=sh4-none-elf --with-endian=little --with-cpu=m4-single --without-newlib --without-headers --disable-nls --disable-shared --disable-multilib --disable-decimal-float --disable-threads --disable-libatomic --disable-libgomp --disable-libquadmath --disable-libssp --disable-libvtv --disable-hosted-libstdcxx --disable-libstdcxx-pch --disable-libstdcxx-verbose --disable-libstdcxx-filesystem-ts --disable-libstdcxx-threads --disable-libstdcxx-backtrace --enable-languages=c,c++ --disable-bootstrap
|
|
Thread model: single
|
|
Supported LTO compression algorithms: zlib zstd
|
|
gcc version 15.1.0 (GCC)
|
|
\end{minted}
|
|
|
|
\chapter{Dreamcast hardware registers}
|
|
|
|
\section{An absolute minimal demo}
|
|
|
|
The objective of this section is to get code running on Dreamcast while avoiding
|
|
as much boilerplate as possible.
|
|
|
|
\end{document}
|