207 lines
6.0 KiB
TeX
207 lines
6.0 KiB
TeX
\documentclass[20pt]{article}
|
|
|
|
\usepackage{hyperref}
|
|
\hypersetup{
|
|
colorlinks=true,
|
|
linkcolor=blue,
|
|
filecolor=magenta,
|
|
urlcolor=cyan,
|
|
pdftitle={Dreamcast},
|
|
pdfpagemode=FullScreen,
|
|
}
|
|
|
|
\usepackage{graphicx}
|
|
\graphicspath{ {./images/} }
|
|
|
|
\title{Building and running the Dreamcast JVM}
|
|
\date{}
|
|
|
|
\setcounter{secnumdepth}{0}
|
|
|
|
\begin{document}
|
|
|
|
\maketitle
|
|
|
|
\tableofcontents
|
|
\section{Introduction}
|
|
|
|
The \texttt{jvm} project's Dreamcast build system depends on the
|
|
\texttt{dreamcast} project. This dependency is limited mostly to sharing Make
|
|
rules. Clone both of these as siblings of the same parent directory, as in:
|
|
|
|
\begin{verbatim}
|
|
git clone https://github.com/buhman/dreamcast
|
|
|
|
git clone https://github.com/buhman/jvm
|
|
\end{verbatim}
|
|
|
|
If you would like to use a \texttt{.cdi} image, the build process also depends
|
|
on \texttt{cdi4dc}. It is assumed that this tool exists in the same directory
|
|
that contains the \texttt{dreamcast} and \texttt{jvm} directories. On Linux, do:
|
|
|
|
\begin{verbatim}
|
|
curl -LO https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_02b_linux.zip
|
|
|
|
unzip cdi4dc_02b_linux.zip
|
|
|
|
chmod +x cdi4dc
|
|
\end{verbatim}
|
|
|
|
To build everything, do the following:
|
|
|
|
\begin{verbatim}
|
|
cd jvm
|
|
|
|
sh generate_classpath.sh
|
|
|
|
rm -f main.bin main.elf jvm.iso
|
|
|
|
make -f Makefile.dreamcast.mk TARGET=sh-elf- jvm.iso
|
|
|
|
../cdi4dc jvm.iso jvm.cdi
|
|
\end{verbatim}
|
|
|
|
You should change the value of \texttt{TARGET=sh-elf-} to whatever matches your
|
|
GCC SH installation. If for example your GCC is named \texttt{sh4-none-elf-gcc}
|
|
then the correct \texttt{TARGET} value would be \texttt{TARGET=sh4-none-elf-}
|
|
(including the trailing hyphen).
|
|
|
|
You can then run the generated \texttt{jvm.cdi} on Dreamcast hardware or
|
|
emulators.
|
|
|
|
\section{Additional notes}
|
|
|
|
\subsection{Generate classpath}
|
|
|
|
The \texttt{generate\_classpath.sh} script is terrible. It is a ``quick hack''
|
|
to work around \hyperref[sec:unsolved]{multiple unsolved problems}.
|
|
|
|
If you wish to modify the build process to include newly-written classes, you
|
|
should append them to the \texttt{application\_classes} array in
|
|
\texttt{generate\_classpath.sh}.
|
|
|
|
\subsection{Flycast settings}
|
|
|
|
I recommend the following Flycast settings:
|
|
|
|
\begin{itemize}
|
|
\item Video → Transparent Sorting → Per Pixel (selected)
|
|
\item Video → Rendering Options → Full Framebuffer Emulation (checked)
|
|
\item Video → Advanced → Copy Rendered Textures to VRAM (checked)
|
|
\item Advanced → Other → Serial Console (checked)
|
|
\end{itemize}
|
|
|
|
\subsection{Run the Dreamcast JVM on Linux/Windows/macOS}
|
|
|
|
The Dreamcast JVM can also run as a application on a PC operating system. This
|
|
can be useful for testing general Java features independently of running on a
|
|
Dreamcast.
|
|
|
|
\begin{verbatim}
|
|
make clean
|
|
|
|
make main
|
|
\end{verbatim}
|
|
|
|
You should run \texttt{make clean} any time you wish to swap between the PC and
|
|
Dreamcast versions of the JVM.
|
|
|
|
Compile one of the tests as an example:
|
|
|
|
\begin{verbatim}
|
|
make classes/test/TestIntegerBitCount.class
|
|
\end{verbatim}
|
|
|
|
Run the Dreamcast JVM like this:
|
|
|
|
\begin{verbatim}
|
|
cd classes
|
|
|
|
# ../main [entry_class_name] [class_file...]
|
|
|
|
../main test/TestIntegerBitCount test/*.class java/lang/*.class java/io/*.class
|
|
\end{verbatim}
|
|
|
|
Note that for no specific reason, the Dreamcast JVM main method declaration is
|
|
\begin{verbatim}
|
|
public static void main()
|
|
\end{verbatim}
|
|
rather than the standard
|
|
\begin{verbatim}
|
|
public static void main(String[] args)
|
|
\end{verbatim}
|
|
I may change this in the future (it is not hard to support either, or even
|
|
both).
|
|
|
|
\subsection{JVM debug print}
|
|
|
|
\texttt{DEBUG\_PRINT} is \textbf{very slow} and unintelligibly verbose for
|
|
non-trivial programs. It is mostly useful for doing low-level debugging of the
|
|
JVM itself for very simple programs.
|
|
|
|
This can be disabled/enabled in either \texttt{Makefile} or
|
|
\texttt{Makefile.dreamcast.mk} by commenting/uncommenting the line
|
|
\begin{verbatim}
|
|
CFLAGS += -DDEBUG_PRINT
|
|
\end{verbatim}
|
|
|
|
When changing \texttt{CFLAGS}, remove all previously-built object files with the
|
|
command:
|
|
|
|
\begin{verbatim}
|
|
make clean
|
|
\end{verbatim}
|
|
|
|
\section{Unsolved problems}
|
|
\label{sec:unsolved}
|
|
|
|
There are a few issues that currently cause the build process to be uglier than
|
|
I'd like it to be. I welcome any suggestions regarding any of these topics:
|
|
|
|
\subsection{Boot class path}
|
|
|
|
The Dreamcast JVM includes its own versions the classes from
|
|
\texttt{java.lang}. The OpenJDK \texttt{javac}, however, will attempt to link
|
|
against OpenJDK's own version of \texttt{java.lang}.
|
|
|
|
In many cases, this will coincidentally not cause issues. However, it is better
|
|
to explicitly reference the Dreamcast JVM's version of \texttt{java.lang} to be
|
|
able to catch any linking errors as early as possible (\texttt{javac}'s error
|
|
messages are also much better than those you'd get from \texttt{jvm.bin}).
|
|
|
|
However, \texttt{javac} doesn't appear to support this in a convenient way. The
|
|
best invocation I've found so far is:
|
|
|
|
\begin{verbatim}
|
|
cd jvm/classes
|
|
|
|
javac -Xlint:-options --source 8 --target 8 --boot-class-path . path/to/YourClass.java
|
|
\end{verbatim}
|
|
|
|
This does limit you to Java 8 language features, but this appears to be the only
|
|
way to enable the \texttt{--boot-class-path} option, for which there is no clear
|
|
replacement in newer versions.
|
|
|
|
\subsection{Nested class filenames contain the dollar-sign character}
|
|
|
|
I have not managed to make my Make rules tolerant of \texttt{\$} characters in
|
|
filenames. This is the main reason why \texttt{generate\_classpath.sh} exists,
|
|
and it's also the reason why it's terrible.
|
|
|
|
\subsection{Unused class/method removal}
|
|
|
|
It would be nice to have a build process/tool that works like this:
|
|
|
|
\begin{itemize}
|
|
\item give the name of the ``main''/entrypoint class as a command-line argument
|
|
\item automatically/recursively calculate the minimum set of
|
|
classes/methods/fields that ``main'' depends on
|
|
\item from the full library of available classes, emit a reduced/minimal set of
|
|
(compiled) class files that only contain the methods and fields that are
|
|
reachable via ``main''.
|
|
\end{itemize}
|
|
|
|
I will create this tool at some point.
|
|
|
|
\end{document}
|