Building and running the Dreamcast JVM


Contents

Introduction
Additional notes
Generate classpath
Flycast settings
Run the Dreamcast JVM on Linux/Windows/macOS
JVM debug print
Unsolved problems
Boot class path
Nested class filenames contain the dollar-sign character
Unused class/method removal

Introduction

The jvm project’s Dreamcast build system depends on the dreamcast project. This dependency is limited mostly to sharing Make rules. Clone both of these as siblings of the same parent directory, as in:

git clone https://github.com/buhman/dreamcast

git clone https://github.com/buhman/jvm

If you would like to use a .cdi image, the build process also depends on cdi4dc. It is assumed that this tool exists in the same directory that contains the dreamcast and jvm directories. On Linux, do:

curl -LO https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_02b_linux.zip

unzip cdi4dc_02b_linux.zip

chmod +x cdi4dc

To build everything, do the following:

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

You should change the value of TARGET=sh-elf- to whatever matches your GCC SH installation. If for example your GCC is named sh4-none-elf-gcc then the correct TARGET value would be TARGET=sh4-none-elf- (including the trailing hyphen).

You can then run the generated jvm.cdi on Dreamcast hardware or emulators.

Additional notes

Generate classpath

The generate_classpath.sh script is terrible. It is a “quick hack” to work around multiple unsolved problems.

If you wish to modify the build process to include newly-written classes, you should append them to the application_classes array in generate_classpath.sh.

Flycast settings

I recommend the following Flycast settings:

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.

make clean

make main

You should run 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:

make classes/test/TestIntegerBitCount.class

Run the Dreamcast JVM like this:

cd classes

# ../main [entry_class_name] [class_file...]

../main test/TestIntegerBitCount test/*.class java/lang/*.class java/io/*.class

Note that for no specific reason, the Dreamcast JVM main method declaration is

public static void main()

rather than the standard

public static void main(String[] args)

I may change this in the future (it is not hard to support either, or even both).

JVM debug print

DEBUG_PRINT is 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 Makefile or Makefile.dreamcast.mk by commenting/uncommenting the line

CFLAGS += -DDEBUG_PRINT

When changing CFLAGS, remove all previously-built object files with the command:

make clean

Unsolved problems

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:

Boot class path

The Dreamcast JVM includes its own versions the classes from java.lang. The OpenJDK javac, however, will attempt to link against OpenJDK’s own version of java.lang.

In many cases, this will coincidentally not cause issues. However, it is better to explicitly reference the Dreamcast JVM’s version of java.lang to be able to catch any linking errors as early as possible (javac’s error messages are also much better than those you’d get from jvm.bin).

However, javac doesn’t appear to support this in a convenient way. The best invocation I’ve found so far is:

cd jvm/classes

javac -Xlint:-options --source 8 --target 8 --boot-class-path . path/to/YourClass.java

This does limit you to Java 8 language features, but this appears to be the only way to enable the --boot-class-path option, for which there is no clear replacement in newer versions.

Nested class filenames contain the dollar-sign character

I have not managed to make my Make rules tolerant of $ characters in filenames. This is the main reason why generate_classpath.sh exists, and it’s also the reason why it’s terrible.

Unused class/method removal

It would be nice to have a build process/tool that works like this:

I will create this tool at some point.