Giter Club home page Giter Club logo

jaxe's Introduction

JAXE (Just Another XO-CHIP/CHIP-8 Emulator)

Brix Space Invaders (In Debug Mode)
Black Rainbow DVN8
Super Neat Boy Chicken Scratch

CHIP-8 was a virtual machine/programming language developed by Joseph Weisbecker for the COSMAC VIP in the 1970s. It was designed with 35 opcodes and resembles assembly language, but was made for the easier development of video games on the VIP.

Today, it is a popular target to be emulated because of its simplicity and charm.

Features

  • Fully implemented instruction set (including S-CHIP and XO-CHIP)
  • HI-RES (128x64) mode to support S-CHIP programs
  • Dual display buffers to support XO-CHIP programs
  • Accurate delay and sound timers
  • Extended sound (though can sometimes be a bit noisy)
  • Integrated graphical debugger allowing user to step forward and back through program execution
  • Adjustable CPU/timer/refresh frequencies, display scale, colors, and program start address
  • Toggle S-CHIP "quirks" for compatibility with a wide variety of ROMs
  • Save and load memory dumps
  • Unit tests for those writing a C emulator
  • Emulator decoupled from any particular graphics/media library allowing for easy embedding into other C programs
  • Libretro port

Technical Info

The original CHIP-8 virtual machine was designed with the following specs:

  • 35 opcodes
  • 4kb RAM
  • 16 8-bit general purpose registers
  • 16-bit program counter, stack pointer, and index registers
  • 8-bit delay and sound timer registers
  • 64x32 monochrome display
  • 16-key keypad (0-F)
  • Program memory starting at address 0x200

Due to the way CHIP-8 was designed, the "flicker" that happens when sprites are drawn is normal. Games developed for it also rarely made any attempt to cap their frame rate due to the slow hardware of the time hence the need to artificially slow the CPU down on modern emulators.

In the early 90s, Andreas Gustafsson created a port for the HP48 calculator which was eventually superseded by S-CHIP 1.0/1.1 created by Erik Bryntse. The S-CHIP added several features as well as accidentally (or intentionally?) modifying the behavior of several original opcodes:

  • 9 new opcodes
  • 128x64 HI-RES display
  • Persistent storage
  • Modified Bnnn, Fx55, Fx65, Dxyn, 8xy6, and 8xyE instructions

With time, it seems the S-CHIP became more popular and many programs were written to work with its various quirks. Thus, JAXE defaults to original S-CHIP design however many of its quirks can be toggled for improved compatibility using the flags in the Options section below.

However, recently John Earnest designed the XO-CHIP extension allowing CHIP-8 programs to take advantage of modern hardware to an extent. This extension adds several more instructions and features including:

  • 7 new opcodes
  • 16-bit addressing for a total of ~64kb RAM
  • Second display buffer allowing for 4 colors instead of the typical 2
  • Improved sound support
  • Modified Fx75 and Fx85 instructions to allow for 16 user flags instead of typical 8

JAXE currently supports all of these extensions.

It should also be noted that JAXE stores its fonts in memory starting at address 0x0000 followed immediately by large fonts and finally immediately by the stack. Therefore the stack pointer initially points to address 0x00F0.

TODO

  • Continue to improve sound
  • Continue to improve Windows support
  • Improve build procedures
  • Add more color themes

Requirements

  • SDL2
  • SDL2_ttf (for debug mode)
  • CMake (for automatic build)

Build Procedures

Linux/Windows (MinGW)

mkdir build && cd build
cmake -B . -DCMAKE_BUILD_TYPE=Release ..
make

Windows (non-MinGW)

Unknown at this time. Currently the code uses the POSIX getopt() function to handle command-line arguments. To build without MinGW, remove #define ALLOW_GETOPTS from the top of main.c which will unfortunately remove command-line arguments until I handle them in a portable way.

Run

Linux

./jaxe [options] <path-to-rom/dump-file>
./test (for unit tests)

Windows

If built with MinGW, command line options are available:
jaxe.exe [options] <path-to-rom/dump-file>

Otherwise:
jaxe.exe <path-to-rom/dump-file>
test.exe (for unit tests)

Options

-l Enable legacy mode (for running original CHIP-8 ROMs)
-x Enable XO-CHIP mode
-d Enable debug mode
-m Load dump file instead of ROM
-p Set program start address (in hex)
-c Set CPU frequency (in Hz, value of 0 means uncapped)
-t Set timer frequency (in Hz, value of 0 means uncapped)
-r Set screen refresh frequency (in Hz, value of 0 means uncapped)
-s Set display scale factor
-b Set background color (in hex)
-f Set plane1 color (in hex)
-k Set plane2 color (in hex)
-n Set overlap color (in hex)

Also includes flags for disabling specific S-CHIP "quirks" (which are all enabled by default):

-0 Disable uninitialized RAM
-1 Disable 8xy6/8xyE bug
-2 Disable Fx55/Fx65 bug
-3 Disable Bnnn bug
-4 Disable ban on big sprites being drawn in LO-RES mode
-5 Disable display state remaining the same when 00FE/00FF execute (display is cleared with this disabled)
-6 Disable sprite clipping
-7 Disable collision enumeration
-8 Disable collision check with bottom of screen
-9 Disable undefined VF after logical OR, AND, XOR (VF is set to 0 with this disabled)

Controls

Keyboard (This maps to the key layouts below)

1 2 3 4
Q W E R
A S D F
Z X C V

COSMAC VIP Keypad

1 2 3 C
4 5 6 D
7 8 9 E
A 0 B F

HP48 Keypad

7 8 9 /
4 5 6 *
1 2 3 -
0 . _ +

Other Controls

Key Action
SPACE Pause/Unpause
UP Step Forward (DBG Mode Only)
DOWN Step Back (DBG Mode Only)
RIGHT Increase CPU Speed
LEFT Decrease CPU Speed
ENTER Save/Create Dump File
BACKSPACE Cycle Color Themes
ESC Reset Emulator

Troubleshooting

  • This emulator defaults to S-CHIP mode, which has become more popular since the 90s. Unfortunately, S-CHIP changed the behavior of several instructions and introduced some other quirks, making some programs developed for the original COSMAC VIP not backwards-compatible. If a ROM is not working correctly (especially one written before 1990), try enabling legacy mode with the -l flag.
  • If running an XO-CHIP ROM, enable XO-CHIP mode with the -x flag.
  • This emulator defaults to 0x200 as the start address, however some programs assume other defaults (namely, those written for the ETI-660 which default to 0x600). Try to find out what default address the program assumes and set that with the -p option.
  • If a program is running very slowly, try increasing the CPU speed or even uncapping it (by setting the -c option to 0). Some ROMs are developed around an uncapped execution frequency and will run much more smoothly.
  • There are many CHIP-8 variants and this emulator does not support all of them. If a ROM still does not work correctly after trying the suggestions above, it may have been written for an unsupported variant and thus will simply not work.

Libretro port

Libretro port is intended to run under Retroarch on a wide variety of platforms. Compilation:

  • Default platform:
make -f Makefile.libretro
  • Most platforms
make -f Makefile.libretro platform=PLATFORM
  • Android
cd jni/
ndk-build

Running from command line:

retroarch -L jaxe_libretro.so  roms/chip8archive/br8kout.ch8

I hope to add it to buildbot and official distribution shortly

Default key mapping:

  • 0 to B
  • 1 to START
  • 2 to Y
  • 3 to SELECT
  • 4 to L (shoulder)
  • 5 to D-Pad Up
  • 6 to A
  • 7 to D-Pad Left
  • 8 to D-Pad Down
  • 9 to D-Pad Right
  • A to R (shoulder)
  • B to L2 (trigger)
  • C to X
  • D to R2 (trigger)
  • E to L3 (thumb)
  • F to R3 (thumb)

This is preliminary and subject to change.

Differences and notes compared to standalone version:

  • Debug mode is missing
  • Userflags are saved as SRAM rather than .uf file
  • We use options instead of command line
  • CPU frequency can be set only to predefined values. This is a limitation of options interface
  • Colors can be chosen only from predefined themes. This is a limitation of options interface
  • Setting all quirks to false needs to set all of them manually (there is no equivalent to -x option)
  • To cycle through themes or to change CPU frequencies you need to go to options menu
  • Loading and storing dumps is done through serialization
  • Display scale, pause and exit are handled by frontend
  • Audio is resampled in the core and always outputs at 44100

TODOs:

  • Add more color themes (same as standalone)
  • Investigate if better key mapping is possible
  • Allow frontend to peek into "VRAM"
  • Uncapped CPU frequency
  • Option for PC start address
  • Option for timer frequency
  • Option for refresh frequency
  • Choose resampled audio frequency based on available outputs or make it configurable
  • Maybe have retroachievements support?

Contributing

Anyone is welcome to contribute! I will try to review pull requests as quickly as possible.

License

JAXE is licensed under the MIT license so you are free to do almost whatever you please with this code (see LICENSE file).

ROMs

References

Acknowledgments

jaxe's People

Contributors

jste0 avatar kurtjd avatar phcoder avatar salvacam avatar warmenhoven avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

jaxe's Issues

Seeking libretro port maintainer

Most of the pull requests I receive are in regards to the libretro port which I was not involved with in its development. This makes reviewing PRs for the libretro port difficult as I am less familiar with it.

If anyone sees this who is involved in the libretro port and is interested in being a maintainer, please let me know: [email protected]

Thanks

Timendus' test suite revealing issues with clipping and scrolling

There appear to be issues with sprite clipping and scrolling (as well as display wait not being implemented):

Running quirks test in legacy mode:
./jaxe -l ../roms/optests/chip8-test-suite/5-quirks.ch8

chip8_legacy_5

Running quirks test in S-CHIP mode:
./jaxe ../roms/optests/chip8-test-suite/5-quirks.ch8

S-CHIP Legacy:
chip8_schip_legacy_5
S-CHIP Modern:
chip8_schip_modern_5
^^^ Not sure about the difference between "S-CHIP legacy" and regular CHIP-8 mode (which I call "legacy")

Running scrolling test in S-CHIP mode:
./jaxe ../roms/optests/chip8-test-suite/8-scrolling.ch8

S-CHIP modern lores:
chip8_schip_lores_modern_8

Running scrolling test in XO-CHIP mode:
./jaxe -x ../roms/optests/chip8-test-suite/8-scrolling.ch8

XO-CHIP lores:
chip8_xochip_lores_8

To summarize:

  • Display wait (draw with vertical blank interrupt) needs implementing
  • Sprite clipping has issues
  • Scrolling in XO-CHIP and S-CHIP lores modes has issues

Number of elements in the QUIRKS array does not match

The number of elements in the quirks array does not match.

In the file include/chip.h is defined the constant NUM_QUIRKS with value 10
https://github.com/kurtjd/jaxe/blob/main/include/chip8.h#L32C9-L32C19

In this file is comment each elemente of array
https://github.com/kurtjd/jaxe/blob/main/include/chip8.h#L136
but only 9 is comment

I don't know if the value of NUM_QUIRKS should be 9 or 10

In the file src/main.c is defined the array quirks with 10 elements
https://github.com/kurtjd/jaxe/blob/main/src/main.c#L41
but in the src/libretro.c the array quirks with 9 elements
https://github.com/kurtjd/jaxe/blob/main/src/libretro.c#L256

This does not affect performance or generate errors, neither in the SDL version nor in Retroarch, but I think the number of array elements in the two versions should match.

Wrong VF order in 8xy6 and 8xyE

First of all: Nice project, nice compact implementation and good that there is libretro support as I couldn't get myself doing it. :-)

In all math operations that set a flag result in VF and VF is also Vx, the result register, the result of the operation needs to be the flag result of the operation, not the operation result. This is order is wrong in 8xy6 and 8xyE leading to e.g. VF always being 0 for in case of 8xy6 and a potential flag result of 2 in case of 8xyE.

The flags test of Timendus great test suite can be used to verify this: https://github.com/Timendus/chip8-test-suite#flags-test

JAXE result is:

Bildschirmfoto 2024-03-31 um 10 53 24

So as expected 8xy6 and 8xyE failed the VF order test. This is btw. an error in many emulators as it is described misleadingly in Cowgod's technical reference and Wikipedia.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.