Skip to content

Commit adb1b38

Browse files
authored
Merge pull request #14 from Timendus/superchip-has-vblank
v4.1 release
2 parents 9ff3560 + 81e8558 commit adb1b38

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+5858
-303
lines changed

README.md

Lines changed: 178 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,31 @@
33
# CHIP-8 test suite
44

55
_A collection of ROM images with tests that will aid you in developing your own
6-
CHIP-8, SCHIP or XO-CHIP interpreter (or "emulator")_
6+
CHIP-8, SUPER-CHIP or XO-CHIP interpreter (or "emulator")_
77

88
## Table of contents
99

1010
* [Introduction](#introduction)
11+
* [Baseline](#baseline)
1112
* [Available tests](#available-tests)
1213
* [CHIP-8 splash screen](#chip-8-splash-screen)
1314
* [IBM logo](#ibm-logo)
1415
* [Corax+ opcode test](#corax-opcode-test)
1516
* [Flags test](#flags-test)
1617
* [Quirks test](#quirks-test)
1718
* [Keypad test](#keypad-test)
19+
* [Beep test](#beep-test)
20+
* [Scrolling test](#scrolling-test)
1821
* [Contributing](#contributing)
1922
* [Community response 😄](#community-response-)
2023

2124
# Introduction
2225

2326
I found it hard to find reliable sources on what is the right behaviour and what
2427
is not, especially with the subtle differences between the original "Cosmac VIP"
25-
CHIP-8 and the HP84's SCHIP (or "superchip"). Now that I have written and ported
26-
a couple of interpreters as well as a few programs and games for the platform, I
27-
thought it was time to put that knowledge into code.
28+
CHIP-8 and the HP48's SUPER-CHIP (or "S-CHIP"). Now that I have written and
29+
ported a couple of interpreters as well as a few programs and games for the
30+
platform, I thought it was time to put that knowledge into code.
2831

2932
If you're having issues with your interpreter, you can find help in the [EmuDev
3033
discord channel `#chip-8`](https://discord.gg/dkmJAes). Every test has a clearly
@@ -33,6 +36,40 @@ share a screenshot. If you discover a problem with this test ROM itself, feel
3336
free to file an issue or open a pull request. It's open source, licensed under
3437
the GPLv3, and you're welcome to [contribute](#contributing).
3538

39+
# Baseline
40+
41+
Most tests have been written to run equally well on all three major CHIP-8
42+
platforms, unless otherwise specified. The [quirks test](#quirks-test) is the
43+
most interesting one, since it was designed to test the differences between
44+
those three platforms. If the test suite itself is wrong, we're not helping
45+
anyone. So what are we testing the test suite against?
46+
47+
## CHIP-8
48+
49+
There are several good Cosmac VIP emulators, so we can quite faithfully run the
50+
original CHIP-8 interpreter and check the results. We use [Emma
51+
O2](https://www.emma02.hobby-site.com/) and/or
52+
[Cadmium](https://github.com/gulrak/cadmium) in `VIP-CHIP-8` mode to validate
53+
the test suite.
54+
55+
If you have an actual, physical Cosmac VIP and would like to verify the test
56+
suite, let me know! 😄
57+
58+
## SUPER-CHIP
59+
60+
For SUPER-CHIP, the test suite has been tested against real HP48 graphing
61+
calculators, in the various interpreters that exist for that system.
62+
[Gulrak](https://github.com/gulrak) from the CHIP-8 community has both an HP48SX
63+
and an HP48GX, and has been so kind as to check if the test suite ROMs behave as
64+
expected.
65+
66+
## XO-CHIP
67+
68+
The XO-CHIP extension was written by [John
69+
Earnest](https://github.com/johnearnest) and was first implemented in his IDE
70+
slash interpreter Octo. As such, we treat [Octo](http://octo-ide.com/) as the
71+
gold standard for how an XO-CHIP system should behave, and test against that.
72+
3673
# Available tests
3774

3875
## CHIP-8 splash screen
@@ -242,20 +279,22 @@ for more information on the arithmetic operations and the flags.
242279
* [Run this ROM in Octo](https://timendus.github.io/chip8-test-suite/5-quirks.html)
243280
to see what's supposed to happen
244281

245-
CHIP-8, SCHIP and XO-CHIP have subtle differences in the way they interpret the
246-
bytecode. We often call these differences quirks. This test detects which quirks
247-
your interpreter implements, and if those quirks match the platform you're
248-
trying to target. This is one of the hardest parts to "get right" and often a
249-
reason why "some games work, but some don't".
282+
CHIP-8, SUPER-CHIP and XO-CHIP have subtle differences in the way they interpret
283+
the bytecode. We often call these differences quirks. This test detects which
284+
quirks your interpreter implements, and if those quirks match the platform
285+
you're trying to target. This is one of the hardest parts to "get right" and
286+
often a reason why "some games work, but some don't".
250287

251288
### The menu
252289

253-
The test asks you to choose the platform you are targeting:
290+
The test asks you to choose the platform you are targeting. If you select
291+
SUPER-CHIP, if will then also ask you if you want to test for the "modern" or
292+
the "legacy" behaviour. When in doubt, go for the "modern" one.
254293

255294
![Choosing a target platform in the quirks test](./pictures/quirks-platform.png)
256295

257-
You can press any of the numbers `1` to `3` on the CHIP-8 keypad to jump to the
258-
corresponding test.
296+
You can press any of the numbers `1` to `3` on the CHIP-8 keypad to make the
297+
corresponding selection.
259298

260299
Alternatively, you can move the cursor up and down with CHIP-8 keys `E` and `F`
261300
and select an item with `A`. This feature mainly exists so people implementing
@@ -264,9 +303,14 @@ can map their buttons to those CHIP-8 keys and have an intuitive interface too.
264303

265304
If you want to repeat a test often or even automate them, having to use the
266305
graphical menu just gets in the way. In that case, you can force this ROM to
267-
select a specific platform by loading a value between `1` and `3` into memory at
306+
select a specific platform by loading a value between `1` and `4` into memory at
268307
the address `0x1FF` (`512`).
269308

309+
* `1` - CHIP-8
310+
* `2` - SUPER-CHIP with modern behaviour
311+
* `3` - XO-CHIP
312+
* `4` - SUPER-CHIP with legacy behaviour
313+
270314
### The test
271315

272316
The test will now run through a couple of steps, which you will see on the
@@ -280,14 +324,15 @@ or an error) and if that matches your chosen target platform (a checkmark or a
280324
cross).
281325

282326
* `vF reset` - The AND, OR and XOR opcodes (`8xy1`, `8xy2` and `8xy3`) reset the
283-
flags register to zero. Test will show `E1` if the AND and OR tests don't
284-
behave the same and `E2` if the AND and XOR tests don't behave the same.
327+
flags register to zero. Test will show `ERR1` if the AND and OR tests don't
328+
behave the same and `ERR2` if the AND and XOR tests don't behave the same.
285329
* `Memory` - The save and load opcodes (`Fx55` and `Fx65`) increment the index
286-
register. More information [here](https://laurencescotford.net/chip-8-on-the-cosmac-vip-loading-and-saving-variables/) and [here](https://tobiasvl.github.io/blog/write-a-chip-8-emulator/#fx55-and-fx65-store-and-load-memory).
330+
register. More information [here](https://laurencescotford.net/chip-8-on-the-cosmac-vip-loading-and-saving-variables/)
331+
and [here](https://tobiasvl.github.io/blog/write-a-chip-8-emulator/#fx55-and-fx65-store-and-load-memory).
287332
* `Display wait` - Drawing sprites to the display waits for the vertical blank
288333
interrupt, limiting their speed to max 60 sprites per second. More information
289334
[here](https://laurencescotford.net/chip-8-on-the-cosmac-vip-drawing-sprites/).
290-
Test will show `LOW` if the number of cycles per frame is too low for the test
335+
Test will show `SLOW` if the number of cycles per frame is too low for the test
291336
to be deterministic (this is not necessarily an error, but a suggestion to
292337
rerun the test with a higher number of cycles per frame).
293338
* `Clipping` - Sprites drawn at the bottom edge of the screen get clipped
@@ -296,18 +341,43 @@ cross).
296341
of the screen. This also tests that sprites drawn at coordinates of `x > 63`
297342
and/or `y > 31` wrap around to `x % 64` and `y % 32`. More information
298343
[here](https://laurencescotford.net/chip-8-on-the-cosmac-vip-drawing-sprites/).
299-
Test will show `E1` if the clipping is inconsistent in different dimensions or
300-
wrapping to the wrong coordinates and `E2` if sprites don't wrap around as
301-
expected.
344+
Test will show `ERR1` if the clipping is inconsistent in different dimensions
345+
or wrapping to the wrong coordinates and `ERR2` if sprites don't wrap around
346+
as expected.
302347
* `Shifting` - The shift opcodes (`8xy6` and `8xyE`) only operate on `vX`
303348
instead of storing the shifted version of `vY` in `vX` (more information
304-
[here](https://tobiasvl.github.io/blog/write-a-chip-8-emulator/#8xy6-and-8xye-shift)). Test will show `E1` if the shift opcodes behave differently.
349+
[here](https://tobiasvl.github.io/blog/write-a-chip-8-emulator/#8xy6-and-8xye-shift)).
350+
Test will show `ERR1` if the shift opcodes behave differently.
305351
* `Jumping` - The "jump to some address plus `v0`" instruction (`Bnnn`) doesn't
306352
use `v0`, but `vX` instead where `X` is the highest nibble of `nnn` (more
307353
information [here](https://tobiasvl.github.io/blog/write-a-chip-8-emulator/#bnnn-jump-with-offset))
308354

309355
Note that you need timer support for this test to run.
310356

357+
### SUPER-CHIP / XO-CHIP
358+
359+
If you select SUPER-CHIP or XO-CHIP in the menu, half of the test will be
360+
executed in `hires` mode, and the behaviour of `Display wait` and `Clipping`
361+
will be tested in both `lores` and `hires` modes. This means you will not just
362+
see "on" or "off" for these quirks, but instead one of these values:
363+
364+
* `NONE` - The quirk is disabled in both modes
365+
* `HRES` - The quirk is only enabled in `hires` mode
366+
* `LRES` - The quirk is only enabled in `lores` mode
367+
* `BOTH` - The quirk is enabled in both modes
368+
369+
If the test finds different errors for the `Clipping` test in `hires` mode
370+
compared to `lores` mode, it will show `ERR3`. In that case, first make sure
371+
your modes produce the same wrapping and clipping results, and see which errors
372+
pop up after that.
373+
374+
Wondering why testing `hires` has been added, or if a quirk can ever be enabled
375+
in only one of the modes? Or just wondering why SUPER-CHIP has a "legacy" and a
376+
"modern" version of the test? You can [read the full story
377+
here](./legacy-superchip.md).
378+
379+
### More information
380+
311381
See this [excellent
312382
table](https://chip8.gulrak.net) by Gulrak for
313383
an overview of all the known quirks for the relatively popular CHIP-8 versions.
@@ -383,7 +453,84 @@ See [this
383453
article](https://laurencescotford.net/chip-8-on-the-cosmac-vip-keyboard-input/)
384454
for more information.
385455

386-
## Contributing
456+
## Beep test
457+
458+
* [Download ROM](https://github.com/Timendus/chip8-test-suite/raw/main/bin/7-beep.ch8)
459+
(source code available [here](./src/tests/7-beep.8o))
460+
* [Run this ROM in Octo](https://timendus.github.io/chip8-test-suite/7-beep.html)
461+
to see what's supposed to happen (sound may not actually play due to browser
462+
restrictions)
463+
464+
This test allows you to test if your buzzer is working. It will beep SOS in
465+
morse code and flash a speaker icon on the display in the same pattern. If you
466+
press the CHIP-8 button `B` it will give you manual control over the buzzer.
467+
Press `B` to beep.
468+
469+
![The beep test beeping](./pictures/beep.png)
470+
471+
## Scrolling test
472+
473+
* [Download ROM](https://github.com/Timendus/chip8-test-suite/raw/main/bin/8-scrolling.ch8)
474+
(source code available [here](./src/tests/8-scrolling.8o))
475+
* [Run this ROM in Octo](https://timendus.github.io/chip8-test-suite/8-scrolling.html)
476+
to see what's supposed to happen
477+
478+
This test is only applicable to SUPER-CHIP and XO-CHIP interpreters, since
479+
regular CHIP-8 does not have scrolling instructions. It will test to see if your
480+
scrolling opcodes scroll the display in the right directions by the right
481+
amounts of pixels. One literal "edge"-case that it does **not** cover is what
482+
happens at the edges of the screen.
483+
484+
### The menu
485+
486+
The test asks you to choose the platform and resolution you are targeting. For
487+
SUPER-CHIP `lores`, it will also ask you to choose between "modern" or "legacy"
488+
behaviour. When in doubt, go for the "modern" one.
489+
490+
![Choosing a target platform in the scrolling test](./pictures/scrolling-platform.png)
491+
492+
You can press any of the numbers `1` or `2` on the CHIP-8 keypad to select the
493+
corresponding entry.
494+
495+
Alternatively, you can move the cursor up and down with CHIP-8 keys `E` and `F`
496+
and select an item with `A`. This feature mainly exists so people implementing
497+
interpreters for platforms with limited input devices (like a game controller)
498+
can map their buttons to those CHIP-8 keys and have an intuitive interface too.
499+
500+
If you want to repeat a test often or even automate them, having to use the
501+
graphical menu just gets in the way. In that case, you can force this ROM to
502+
select a specific platform by loading a value between `1` and `5` into memory at
503+
the address `0x1FF` (`512`).
504+
505+
* `1` - SUPER-CHIP `lores` with modern behaviour
506+
* `2` - SUPER-CHIP `lores` with legacy behaviour
507+
* `3` - SUPER-CHIP `hires`
508+
* `4` - XO-CHIP `lores`
509+
* `5` - XO-CHIP `hires`
510+
511+
### The test
512+
513+
The test will show you a visual with arrows and boxes. If everything works as
514+
expected for the target you have selected, all the arrows will end up in their
515+
boxes, like so:
516+
517+
![Result of the scrolling test for `lores` SUPER-CHIP](./pictures/lores-scrolling.png)
518+
519+
If you have issues with one or more of your scrolling instructions, some arrows
520+
will be (partially) outside their boxes. The arrows all point in the directions
521+
that they should be scrolled in, so the ones that have not moved in the
522+
direction that they point in represent the scrolling instructions that are not
523+
working properly.
524+
525+
For example, this is what you see if none of the scrolling instructions have
526+
been implemented:
527+
528+
![Result of the scrolling test with no implemented scrolling](./pictures/lores-no-scrolling.png)
529+
530+
A note on legacy versus modern behaviour for SUPER-CHIP's `lores` mode can be
531+
found in the document [Legacy SUPER-CHIP](./legacy-superchip.md).
532+
533+
# Contributing
387534

388535
Do you find an issue in this test suite that you think you can fix? Feel free to
389536
submit a PR! Here's how to build the project, assuming you have Nodejs and NPM
@@ -399,12 +546,14 @@ npm install
399546
npm start
400547

401548
# Build a specific test:
402-
npm run build-logo
403-
npm run build-ibm
404-
npm run build-corax
405-
npm run build-flags
406-
npm run build-quirks
407-
npm run build-keypad
549+
TEST=1-chip8-logo npm run build-test
550+
TEST=2-ibm-logo npm run build-test
551+
TEST=3-corax+ npm run build-test
552+
TEST=4-flags npm run build-test
553+
TEST=5-quirks npm run build-test
554+
TEST=6-keypad npm run build-test
555+
TEST=7-scrolling npm run build-test
556+
TEST=8-beep npm run build-test
408557
```
409558

410559
Note that the `npm` scripts use the MacOS command `pbcopy` to copy
@@ -416,7 +565,7 @@ not work properly. Edit `package.json` and remove this part from the end of `scr
416565
&& cat bin/${TEST}.8o | pbcopy
417566
```
418567

419-
## Community response 😄
568+
# Community response 😄
420569

421570
[![DUDE THANKS! I was writing a CHIP-8 emulator and THIS HELPED ME SO FRICKING MUCH, THANKS! / same here, this is amazing](./pictures/testimonial1.png)](https://github.com/Timendus/chip8-test-suite/issues/1)
422571

bin/1-chip8-logo.8o

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
: splash-3-1
6262
0xce 0xfc 0xf8 0xc0 0xd4 0xdc 0xc4 0xc5 0x00 0x00 0x30 0x44 0x24 0x14 0x63
6363
: splash-4-1
64-
0xf1 0x03 0x07 0x07 0x77 0x57 0x53 0x71 0x00 0x00 0x28 0x8e 0xa8 0xa8 0xa6
64+
0xf1 0x03 0x07 0x07 0x27 0x67 0x23 0x71 0x00 0x00 0x28 0x8e 0xa8 0xa8 0xa6
6565
: splash-5-1
6666
0xce 0x87 0x03 0x03 0x03 0x87 0xfe 0xfc 0x00 0x00 0x60 0x90 0xf0 0x80 0x70
6767

bin/1-chip8-logo.ch8

0 Bytes
Binary file not shown.

bin/2-ibm-logo.8o

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,5 @@
5858
: ibm-4-0
5959
0x03 0x00 0x07 0x00 0x0f 0x00 0xbf 0x00 0xfb 0x00 0xf3 0x00 0xe3 0x00 0x43
6060
: ibm-5-0
61-
0xe5 0x05 0xe2 0x00 0x85 0x07 0x81 0x01 0x80 0x02 0x80 0x07 0xe5 0x05 0xe7
61+
0xe5 0x05 0xe2 0x00 0x85 0x07 0x81 0x01 0x80 0x02 0x80 0x02 0xe6 0x02 0xe7
6262

bin/2-ibm-logo.ch8

0 Bytes
Binary file not shown.

bin/3-corax+.8o

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,5 +416,5 @@
416416
: version-0-0
417417
0x0a 0xae 0xa2 0x42
418418
: version-1-0
419-
0x38 0x28 0x28 0xb8
419+
0x10 0x30 0x10 0xb8
420420

bin/3-corax+.ch8

0 Bytes
Binary file not shown.

bin/4-flags.8o

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,15 +187,28 @@
187187

188188
# Subtraction in one direction (no carry)
189189
opcode-digit 0x5 # 0x85
190+
# Edge cases:
191+
# Check that vF -= vX results in no carry
190192
vF := 20
191193
vF -= 15_in_a_register # 5 (0x05), but should be overwritten by flag, so 1
192194
v4 := vF
195+
# Check that vX -= vF results in the correct result and no carry
193196
v3 := 20
194197
vF := 15
195198
v3 -= vF # 5 (0x05)
199+
# Check that N - N (for the same N) does not result in carry
200+
v5 := 10
201+
vF := 10
202+
v5 -= vF
203+
v5 := vF
204+
# Base case: check that subtracting two regular registers results in the
205+
# correct value and no carry set, and that the carry register actually gets
206+
# overwritten.
196207
vF := 0xAA
197208
v2 := 50
198209
v2 -= 15_in_a_register # 35 (0x23)
210+
# Check all our assertions
211+
if v5 != 1 then vF := 2
199212
expect-v2-vf-v3-v4 35 1 5 1
200213

201214
y += 5
@@ -214,16 +227,29 @@
214227

215228
# Subtraction in the other direction (no carry)
216229
opcode-digit 0x7 # 0x87
230+
# Edge cases:
231+
# Check that vF =- vX results in no carry
217232
vF := 10
218233
vF =- 15_in_a_register # 5 (0x5), but should be overwritten by flag, so 1
219234
v4 := vF
235+
# Check that vX =- vF results in the correct result and no carry
220236
v3 := 15
221237
vF := 20
222238
v3 =- vF # 5 (0x05)
239+
# Check that N - N (for the same N) does not result in carry
240+
v5 := 10
241+
vF := 10
242+
v5 =- vF
243+
v5 := vF
244+
# Base case: check that subtracting two regular registers results in the
245+
# correct value and no carry set, and taht the carry register actually gets
246+
# overwritten.
223247
vF := 0xAA
224248
v2 := 15
225249
v1 := 50
226250
v2 =- v1 # 35 (0x23)
251+
# Check all our assertions
252+
if v5 != 1 then vF := 2
227253
expect-v2-vf-v3-v4 35 1 5 1
228254
x += 1
229255

@@ -528,5 +554,5 @@
528554
: version-0-0
529555
0x0a 0xae 0xa2 0x42
530556
: version-1-0
531-
0x38 0x28 0x28 0xb8
557+
0x10 0x30 0x10 0xb8
532558

bin/4-flags.ch8

24 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)