# Quirks test # This is a visual adaptation of some of the tests I wrote for Silicon8 # (https://github.com/Timendus/silicon8/tree/main/tests) and some newly written # tests for specific quirks. :include "../utils/helpers.8o" :include "../utils/menu.8o" :include "../utils/text-rendering.8o" :const OFF 0 :const ON 1 :const BOTH 2 :const NONE 3 :const LORES 4 :const HIRES 5 :const ERR1 6 :const ERR2 7 :const ERR3 8 :const CHIP8 1 :const SCHIP_MODERN 2 :const XOCHIP 3 :const SCHIP_LEGACY 4 : main clear i := 0x1FF load v0 if v0 == CHIP8 then jump quirks-chip8 if v0 == SCHIP_MODERN then jump quirks-schip if v0 == SCHIP_LEGACY then jump quirks-schip-legacy if v0 == XOCHIP then jump quirks-xochip text 6 2 quirks-choose text 10 10 quirks-str-chip8 text 10 15 quirks-str-schip text 10 20 quirks-str-xochip render-version :unpack 0xA quirks-menu v2 := 2 jump menu-start : superchip-menu clear text 10 2 quirks-choose-superchip text 18 12 quirks-str-modern text 18 17 quirks-str-legacy render-version :unpack 0xA superchip-target-menu v2 := 1 jump menu-start : render-version x := 50 y := 27 i := version-0-0 sprite x y 4 x := 58 i := version-1-0 sprite x y 4 return :segment data : quirks-menu 6 11 :pointer quirks-chip8 6 16 :pointer superchip-menu 6 21 :pointer quirks-xochip : quirks-choose str "PICK PLATFORM" 0 : quirks-str-chip8 str "1 CHIP-8" 0 : quirks-str-schip str "2 SUPER-CHIP" 0 : quirks-str-xochip str "3 XO-CHIP" 0 : superchip-target-menu 14 13 :pointer quirks-schip 14 18 :pointer quirks-schip-legacy : quirks-choose-superchip str "PICK TARGET" 0 : quirks-str-modern str "1 MODERN" 0 : quirks-str-legacy str "2 LEGACY" 0 :segment code : quirks-chip8 i := scratchpad v0 := CHIP8 save v0 jump quirks-run-tests : quirks-schip i := scratchpad v0 := SCHIP_MODERN save v0 jump quirks-run-tests : quirks-schip-legacy i := scratchpad v0 := SCHIP_LEGACY save v0 jump quirks-run-tests : quirks-xochip i := scratchpad v0 := XOCHIP save v0 : quirks-run-tests waitKeyRelease clear # Determine frames per second for dispQuirk i := scratchpad load v0 if v0 == CHIP8 begin get-frames-per-second-chip8 # We expect the inner loop with 30 `sprite`s to have been able to run six # times in the timespan of 180 interrupts v0 := ON if v3 != 0 then v0 := OFF if v2 > 6 then v0 := OFF if v2 < 6 then v0 := ERR1 i := scratchpad-plus-1 save v0 else # Superchip & XO-CHIP get-frames-per-second-schip-xochip # We expect the inner loop with 30 `sprite`s to have been able to run 3 # times in the timespan of 90 interrupts v0 := ON if v3 != 0 then v0 := OFF if v2 > 3 then v0 := OFF if v2 < 3 then v0 := ERR1 i := scratchpad-plus-1 save v0 # Do the test again, but now in hires mode hires clear get-frames-per-second-hires # We expect the inner loop with 30 `sprite`s to have been able to run 3 # times in the timespan of 90 interrupts v1 := ON if v3 != 0 then v1 := OFF if v2 > 3 then v1 := OFF if v2 < 3 then v1 := ERR1 i := scratchpad-plus-1 load v0 if v0 == ERR1 then jump quirks-combined-vblank-skip if v1 == ERR1 begin v0 := ERR1 jump quirks-combined-vblank-skip end if v0 == OFF begin if v1 == OFF then v0 := NONE if v1 == ON then v0 := HIRES end if v0 == ON begin if v1 == OFF then v0 := LORES if v1 == ON then v0 := BOTH end : quirks-combined-vblank-skip i := scratchpad-plus-1 save v0 lores end # Determine if sprites get clipped vertically clear i := cursor v0 := 28 v1 := 29 sprite v0 v1 6 v0 := 22 v1 := 2 sprite v0 v1 2 v5 := vF v0 := 34 sprite v0 v1 2 v6 := vF # Determine if sprites get clipped horizontally clear i := cursor v0 := 61 v1 := 5 sprite v0 v1 6 v0 := 3 v1 := 4 sprite v0 v1 2 v7 := vF v1 := 10 sprite v0 v1 2 v8 := vF # Determine if sprites get wrapped (both directions) clear v0 := 110 v1 := 50 sprite v0 v1 6 # Should draw at 46,18 v0 := 40 v1 := 17 sprite v0 v1 2 v9 := vF v0 := 52 sprite v0 v1 2 v9 += vF v1 := 23 sprite v0 v1 2 v9 += vF v0 := 40 sprite v0 v1 2 v9 += vF # Save result v0 := OFF # Clipping if v5 == 0 then v0 := ON if v5 != v6 then v0 := ERR1 if v5 != v7 then v0 := ERR1 if v5 != v8 then v0 := ERR1 # Wrapping if v9 != 4 then v0 := ERR2 i := scratchpad-plus-2 save v0 # If SuperCHIP or XO-CHIP, do it again in hires i := scratchpad load v0 if v0 != CHIP8 begin hires # Determine if sprites get clipped vertically clear i := cursor v0 := 60 v1 := 61 sprite v0 v1 6 v0 := 54 v1 := 2 sprite v0 v1 2 v5 := vF v0 := 66 sprite v0 v1 2 v6 := vF # Determine if sprites get clipped horizontally clear i := cursor v0 := 125 v1 := 5 sprite v0 v1 6 v0 := 3 v1 := 4 sprite v0 v1 2 v7 := vF v1 := 10 sprite v0 v1 2 v8 := vF # Determine if sprites get wrapped (both directions) clear v0 := 174 v1 := 82 sprite v0 v1 6 # Should draw at 46,18 v0 := 40 v1 := 17 sprite v0 v1 2 v9 := vF v0 := 52 sprite v0 v1 2 v9 += vF v1 := 23 sprite v0 v1 2 v9 += vF v0 := 40 sprite v0 v1 2 v9 += vF # Determine result v1 := OFF # Clipping if v5 == 0 then v1 := ON if v5 != v6 then v1 := ERR1 if v5 != v7 then v1 := ERR1 if v5 != v8 then v1 := ERR1 # Wrapping if v9 != 4 then v1 := ERR2 # Compare with previous result i := scratchpad-plus-2 load v0 if v0 == ERR1 begin if v1 == ERR1 then jump quirks-combined-wrapping-skip v0 := ERR3 jump quirks-combined-wrapping-skip end if v0 == ERR2 begin if v1 == ERR2 then jump quirks-combined-wrapping-skip v0 := ERR3 jump quirks-combined-wrapping-skip end if v1 == ERR1 begin v0 := ERR3 jump quirks-combined-wrapping-skip end if v1 == ERR2 begin v0 := ERR3 jump quirks-combined-wrapping-skip end if v0 == ON begin if v1 == ON then v0 := BOTH if v1 == OFF then v0 := LORES end if v0 == OFF begin if v1 == ON then v0 := HIRES if v1 == OFF then v0 := NONE end : quirks-combined-wrapping-skip i := scratchpad-plus-2 save v0 lores end # Present results clear # vfQuirk # When using &, | or ^, the flags register always gets reset to 0 text 1 1 quirks-vf v5 := 0 vF := 15 v0 &= v0 if vF == 0 then v5 := 1 v6 := 0 vF := 15 v0 |= v0 if vF == 0 then v6 := 1 v7 := 0 vF := 15 v0 ^= v0 if vF == 0 then v7 := 1 i := scratchpad load v0 i := flag-err if v0 == CHIP8 begin if v5 == 1 then i := flag-ok else # Selected SCHIP or XO-CHIP if v5 == 0 then i := flag-ok end x := 59 y := 2 sprite x y 3 i := quirks-off if v5 == 1 then i := quirks-on if v5 != v6 then i := quirks-inconsistent-1 if v5 != v7 then i := quirks-inconsistent-2 vD := 42 vE := 1 drawText # memQuirk # When reading or writing memory, i gets incremented text 1 6 quirks-mem v0 := 1 v1 := 2 v2 := 3 v3 := 4 v4 := 5 i := scratchpad-plus-3 save v4 v0 := 11 v1 := 12 v2 := 13 i := scratchpad-plus-3 save v2 load v0 v5 := v0 load v0 v6 := v0 i := scratchpad load v0 i := flag-err v1 := 0 if v0 == CHIP8 then jump expect-memquirk if v0 == SCHIP_MODERN then jump expect-no-memquirk if v0 == SCHIP_LEGACY then jump expect-no-memquirk if v0 == XOCHIP then jump expect-memquirk : expect-memquirk if v5 == 4 begin if v6 == 5 begin i := flag-ok else v1 := 1 end end jump memquirk-done : expect-no-memquirk if v5 == 11 begin if v6 == 11 begin i := flag-ok else v1 := 1 end end : memquirk-done x := 59 y := 7 sprite x y 3 i := quirks-on if v5 == 11 then i := quirks-off if v1 == 1 then i := quirks-inconsistent-1 vD := 42 vE := 6 drawText # dispQuirk # When drawing a sprite to the screen, the interpreter waits for v-blank text 1 11 quirks-disp i := scratchpad load v1 i := flag-err if v0 == CHIP8 begin if v1 == ON then i := flag-ok end if v0 == SCHIP_MODERN begin if v1 == NONE then i := flag-ok end if v0 == SCHIP_LEGACY begin if v1 == LORES then i := flag-ok end if v0 == XOCHIP begin if v1 == NONE then i := flag-ok end x := 59 y := 12 sprite x y 3 i := quirks-off if v1 == ON then i := quirks-on if v1 == ERR1 then i := quirks-slow if v1 == LORES then i := quirks-lores if v1 == HIRES then i := quirks-hires if v1 == BOTH then i := quirks-both if v1 == NONE then i := quirks-none vD := 42 vE := 11 drawText # clipQuirk # Sprites wrap to the top of the screen text 1 16 quirks-clip i := scratchpad load v2 i := flag-err if v0 == CHIP8 begin if v2 == ON then i := flag-ok end if v0 == SCHIP_MODERN begin if v2 == BOTH then i := flag-ok end if v0 == SCHIP_LEGACY begin if v2 == BOTH then i := flag-ok end if v0 == XOCHIP begin if v2 == NONE then i := flag-ok end x := 59 y := 17 sprite x y 3 i := quirks-off if v2 == ON then i := quirks-on if v2 == LORES then i := quirks-lores if v2 == HIRES then i := quirks-hires if v2 == BOTH then i := quirks-both if v2 == NONE then i := quirks-none if v2 == ERR1 then i := quirks-inconsistent-1 if v2 == ERR2 then i := quirks-inconsistent-2 if v2 == ERR3 then i := quirks-inconsistent-3 vD := 42 vE := 16 drawText # shiftQuirk # When shifting a register, the interpreter always shifts register X into # register X (instead of shifting register Y into register X) text 1 21 quirks-shift v5 := 0 v6 := 8 v7 := 0 v8 := 32 v5 <<= v6 v7 >>= v8 i := scratchpad load v0 i := flag-err if v0 == CHIP8 begin if v5 != 0 then i := flag-ok end if v0 == SCHIP_MODERN begin if v5 == 0 then i := flag-ok end if v0 == SCHIP_LEGACY begin if v5 == 0 then i := flag-ok end if v0 == XOCHIP begin if v5 != 0 then i := flag-ok end x := 59 y := 22 sprite x y 3 i := quirks-off if v5 == 0 then i := quirks-on if v5 != v7 then i := quirks-inconsistent-1 vD := 42 vE := 21 drawText # jumpQuirk # When using `jump0` (BNNN) the interpreter doesn't jump to NNN + v0 but to # NNN + vX where X is the highest nibble of NNN text 1 26 quirks-jump v0 := 0x98 vE := 0x9C jump0 0xE00 # This jumps to one of two routines defined in index.8o (for : quirks-resume # reasons of having to put them in precisely the right spot) i := scratchpad load v0 i := flag-err if v0 == CHIP8 begin if v5 == 0 then i := flag-ok end if v0 == SCHIP_MODERN begin if v5 != 0 then i := flag-ok end if v0 == SCHIP_LEGACY begin if v5 != 0 then i := flag-ok end if v0 == XOCHIP begin if v5 == 0 then i := flag-ok end x := 59 y := 27 sprite x y 3 i := quirks-off if v5 == 1 then i := quirks-on vD := 42 vE := 26 drawText v0 := key waitKeyRelease jump main :segment data : quirks-vf str "VF RESET" 0 : quirks-mem str "MEMORY" 0 : quirks-disp str "DISP.WAIT" 0 : quirks-clip str "CLIPPING" 0 : quirks-shift str "SHIFTING" 0 : quirks-jump str "JUMPING" 0 : quirks-on str "ON" 0 : quirks-off str "OFF" 0 : quirks-slow str "SLOW" 0 : quirks-lores str "LRES" 0 : quirks-hires str "HRES" 0 : quirks-both str "BOTH" 0 : quirks-none str "NONE" 0 : quirks-inconsistent-1 str "ERR1" 0 : quirks-inconsistent-2 str "ERR2" 0 : quirks-inconsistent-3 str "ERR3" 0 : cursor 0b11111110 0b11111110 0b11111110 0b11111110 0b11111110 0b11111110 :segment code : get-frames-per-second-chip8 quirks-show-splash-lores i := quirks-values load v6 # v0 := 10 # v1 := 31 # v2 := 0 # v3 := 0 # v4 := 1 # v5 := 180 # v6 := 0 i := quirks-image delay := v5 loop v5 := 30 loop sprite v0 v1 1 if vF == 0 begin v0 := 54 v6 := delay v6 >>= v6 v6 >>= v6 v0 -= v6 end v5 -= 1 if v5 != 0 then again v2 += v4 v3 += vF vE := delay if vE != 0 then again return : get-frames-per-second-schip-xochip quirks-show-splash-lores i := quirks-values load v6 # v0 := 10 # v1 := 31 # v2 := 0 # v3 := 0 # v4 := 1 # v5 := 180 # v6 := 0 v5 >>= v5 i := quirks-image delay := v5 loop v5 := 30 loop sprite v0 v1 1 if vF == 0 begin v0 := 32 v6 := delay v6 >>= v6 v6 >>= v6 v0 -= v6 end v5 -= 1 if v5 != 0 then again v2 += v4 v3 += vF vE := delay if vE != 0 then again return : quirks-show-splash-lores v0 := 8 v1 := 0 v2 := 15 i := splash-0-0 loop sprite v0 v1 15 i += v2 v0 += 8 if v0 == 56 begin v0 := 8 v1 += 15 end if v1 != 30 then again return : get-frames-per-second-hires v0 := 16 v1 := 0 v2 := 32 i := splash2x-0-0 loop sprite v0 v1 0 i += v2 v0 += 16 if v0 == 112 begin v0 := 16 v1 += 16 end if v1 != 64 then again # 11th pixel i := quirks-values load v6 # v0 := 10 # v1 := 31 # v2 := 0 # v3 := 0 # v4 := 1 # v5 := 180 # v6 := 0 v0 += v0 v1 += v1 v5 >>= v5 i := quirks-line loop sprite v0 v1 2 v0 += 8 if v0 != 60 then again i := quirks-image loop sprite v0 v1 2 v0 += 1 if v0 != 64 then again delay := v5 loop v5 := 15 loop sprite v0 v1 2 if vF == 0 begin v0 := 108 v6 := delay v6 >>= v6 v0 -= v6 end v5 -= 1 if v5 != 0 then again v2 += v4 v3 += vF vE := delay if vE != 0 then again return :segment data : quirks-values 10 31 0 0 1 180 0 : quirks-image 0b10000000 0b10000000 : quirks-line 0b11111111 0b11111111 :include "../../pictures/version.png" :include "../../pictures/splash.png" :include "../../pictures/splash2x.png" 16x16 # Jump quirk targets: :org 0xE98 # We jump here when using v0 in the `jump0` quirks test v5 := 0 jump quirks-resume :org 0xE9C # We jump here when using vE in the `jump0` quirks test v5 := 1 jump quirks-resume