Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Silicon8 for Thumby v2.0.0 #3

Open
wants to merge 43 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
c5e802e
Add support for grayscale, I mean ugly flickering... ;)
Timendus Jan 5, 2022
1510243
Use new grayscale library instead (untested)
Timendus May 19, 2022
56d33cd
Fix this, technically works now. Only memory issues left to deal with.
Timendus May 20, 2022
1c05ac3
Load program file directly into CHIP8 memory, saving some Thumby RAM
Timendus May 20, 2022
ada1838
Support colour maps (WIP)
Timendus May 22, 2022
d5cd23a
Generate lookup table from cmap
Timendus May 22, 2022
59a416c
Remove some dead code
Timendus May 22, 2022
3e7cc82
Have optimizations where they make sense
Timendus May 22, 2022
988c284
More fancy memory stats
Timendus May 27, 2022
f55455a
Save 3.6k RAM by keeping fonts in a bin file
Timendus May 27, 2022
72d7847
Initialize CHIP8 ram first, because it needs a large continuous regio…
Timendus May 27, 2022
efe71f1
Move splash image to a .bin file too
Timendus Jun 4, 2022
8261d40
Run at higher CPU frequency
Timendus Jun 4, 2022
186c712
Make display waiting more precise
Timendus Jun 4, 2022
aa11aa5
Add link to Ampy
Timendus Jun 4, 2022
ad0dc0d
Reduce possible memory leaks / things that need garbage collecting
Timendus Jun 5, 2022
6b1b7f4
Only import grayscale if we need if
Timendus Jun 5, 2022
5c8fb53
Move grayscale calibration tool to be its own import
Timendus Jun 5, 2022
4603d6d
Rewrite send script in Python, send .mpy files when available, build …
Timendus Jun 5, 2022
c101f44
Build the .mpy files
Timendus Jun 5, 2022
dbcffc2
Add __pycache__ to .gitignore
Timendus Jun 5, 2022
e8dd2ff
Move build.py and send.py into thumby.py which now accepts a parameter
Timendus Jun 15, 2022
fed0621
This should be (2^16)-512
Timendus Jul 23, 2022
94963d3
Eliminate the use of machine.Timer, run on a single thread instead
Timendus Aug 4, 2022
f78ec16
Be more cautious of memory fragmentation
Timendus Aug 4, 2022
f0d1ab6
Swap out old grayscale library for Doogle's new version
Timendus Aug 4, 2022
fb9a00d
Prepare for loading ROMs after soft reboot
Timendus Aug 4, 2022
2364e02
Recompile mpy files
Timendus Aug 4, 2022
d33f761
Restructure main file to soft reset the Thumby between ROM loads
Timendus Aug 4, 2022
4b2c599
Add some new games
Timendus Aug 4, 2022
3660775
Woops, that should not have been committed ;)
Timendus Aug 4, 2022
d1f9717
Stricter imports to reduce memory usage (bonus: don't beep for XO-CHI…
Timendus Aug 4, 2022
75b9167
Compile more files to mpy, compile with right architecture, remove py…
Timendus Aug 4, 2022
2087ff8
Don't allocate new buffers for each colour transformation
Timendus Aug 4, 2022
567b300
Dump errors to file
Timendus Aug 4, 2022
562676d
Clean this up a bit
Timendus Aug 4, 2022
7be336b
Recompile cpu.mpy
Timendus Aug 4, 2022
f498582
Swap out v2 library for v2.1 library
Timendus Aug 8, 2022
8fce11f
Recompile mpy's
Timendus Aug 8, 2022
a0e1883
Upgrade to the fancy new ramgpu version of the grayscale library
Timendus Aug 30, 2022
b57ee01
Add grayscale scaling fun!
Timendus Aug 30, 2022
103d1be
Add some more games
Timendus Aug 30, 2022
c7887bc
This is a better workaround for the viper compilation issue
Timendus Aug 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
TODO.md
playground
send.time
__pycache__
210 changes: 158 additions & 52 deletions Games/Silicon8/Silicon8.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,73 +7,179 @@
# See https://github.com/Timendus/thumby-silicon8 for more information and
# licensing information.

import thumby

splash = bytearray([
0,0,0,0,0,0,0,224,248,60,14,14,7,7,3,3,7,7,14,14,12,0,0,0,0,0,32,32,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,240,120,28,14,6,6,6,14,28,120,240,224,0,
0,0,0,0,0,0,0,15,31,56,112,96,96,224,192,192,192,128,128,0,0,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,15,30,184,240,224,224,224,240,184,30,15,7,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,3,15,254,248,0,0,196,64,0,0,255,0,0,196,64,0,0,0,128,64,64,64,0,0,0,128,64,64,128,0,0,0,192,64,64,64,128,0,0,0,252,254,15,3,1,0,0,0,1,3,15,254,252,0,
0,48,112,112,224,224,192,192,192,192,192,192,192,192,224,96,112,56,28,15,7,1,0,0,63,0,0,0,63,0,0,63,0,0,0,15,16,32,32,32,0,0,15,16,32,32,16,15,0,0,63,0,0,0,0,63,0,0,3,7,15,28,56,48,48,48,56,28,15,7,3,0,
0,60,66,66,66,0,124,16,16,124,0,122,0,124,20,20,8,0,40,84,84,40,0,0,0,66,126,66,0,124,4,4,120,0,62,68,0,56,84,84,88,0,124,8,4,0,124,20,20,8,0,124,8,4,0,56,84,84,88,0,62,68,0,56,84,84,88,0,124,8,4,0
])

# Stop sound and show splash while we wait ;)
thumby.audio.stop()
thumby.display.setFPS(0)
thumby.display.blit(splash, 0, 0, 72, 40, -1, 0, 0)
thumby.display.update()
_WATCHDOG_BASE=const(0x40058000)
_SCRATCH0_ADDR=const(_WATCHDOG_BASE+0x0C)

from machine import freq, mem32, reset, soft_reset
freq(250000000)

# Fix import path so it finds our modules above all else
import sys
sys.path.insert(0, '/Games/Silicon8')
from sys import path
myPath = "/".join(__file__.split("/")[0:-1])
path.insert(0, myPath)

import time
import gc
import machine
import thumbyinterface
import roms
import cpu
import menu

gc.threshold(2000)
gc.enable()

index = 0
scroll = 0

def gb_collect():
print("Free memory before garbage collect:", gc.mem_free())
a1 = gc.mem_alloc()
f1 = gc.mem_free()
gc.collect()
a2 = gc.mem_alloc()
f2 = gc.mem_free()
print("### \t\tUsed\t\tAllocated\tFree")
print("# Before gc\t{}%\t{}\t\t{}".format(a1/(a1+f1)*100, a1, f1))
print("# After gc\t{}%\t{}\t\t{}".format(a2/(a2+f2)*100, a2, f2))
print("# => Freed {} bytes ({}%)".format(f2-f1, (f2-f1)/(a2+f2)))
gc.collect()
print("Free memory after garbage collect:", gc.mem_free())

def runSilicon8():
global index, scroll
# Ask user to choose a ROM
while True:
gb_collect()
program, index, scroll = menu.Menu(index, scroll).choose(roms.catalog())
if not program["file"]:
return False
if menu.Confirm().choose(program):
break
autorun = False
try:
file = open(myPath + "/autorun", "r")
autorun = file.read()
file.close()
except OSError:
pass

if autorun:

### Launch CHIP-8 program!

# Show simple loading screen
from thumbyGraphics import display
display.drawText('Loading...', 8, 17, 1)
display.update()

# Make sure we boot back into the menu next time
from os import remove
try:
remove(myPath + "/autorun")
except OSError:
pass

# Load dependencies, limiting memory fragmentation
gc.collect()
from roms import loadFile, loadinto
gc.collect()
import thumbyinterface
gc.collect()
import cpu
gc.collect()
from types import VIP, SCHIP, XOCHIP
gc.collect()

# How to get back to the menu
def resetToMenu():
mem32[_SCRATCH0_ADDR] = 1
soft_reset()

# Load the program to run
program = loadFile(autorun)

# Set desired execution speed
if program["type"] == VIP:
freq(50000000)
if program["type"] == SCHIP:
freq(125000000)
if program["type"] == XOCHIP:
freq(250000000)

# Let's get started!
gb_collect()
instance = cpu.CPU() # Instantiate interpreter

# Instantiate interpreter
instance = cpu.CPU()
# Clear screen
display.fill(0)
display.update()

# Set up 60Hz interrupt handler
timer = machine.Timer()
timer.init(mode=timer.PERIODIC, period=17, callback=instance.clockTick)
# Start the display, which may start a grayscale thread
try:
thumbyinterface.display.start(program["disp"])
except NotImplementedError as err:
# User is not on at least MicroPython v1.19.1, and grayscale library
# can't run. This should be handled more gracefully, but for now, reset.
print("We need at least MicroPython v1.19.1 for grayscale programs")
resetToMenu()

# Start the interpreter
# Initialize the rest of the interpreter
thumbyinterface.setKeys(program["keys"])
thumbyinterface.display.setColourMap(program["cmap"])
gb_collect()
instance.reset(program["type"])
thumby.display.fill(0)
thumby.display.update()
instance.run(roms.load(program))
return True

while runSilicon8():
pass
# Load program file directly into memory, unless it doesn't fit
memory = memoryview(instance.ram)
if loadinto(program, memory[512:]) == -1:
print("Not enough CHIP-8 RAM to load the program")
resetToMenu()

gb_collect()
try:
instance.run() # This will block as long as the program is running
except Exception as err:
file = open(myPath + '/error.log', 'w')
file.write(str(err))
file.close()
raise err
resetToMenu()

else:

### Show the menu

# Reset screen brightness to system default
from thumbyGraphics import display
brightnessSetting=2
try:
file = open("thumby.cfg", "r")
conf = file.read().split(',')
for k in range(len(conf)):
if(conf[k] == "brightness"):
brightnessSetting = int(conf[k+1])
file.close()
except OSError:
pass
brightnessVals=[0,28,127]
display.brightness(brightnessVals[brightnessSetting])

# Show splash while we wait ;)
from thumbySprite import Sprite
display.drawSprite(Sprite(72, 40, myPath + "/assets/splash.bin"))
display.update()

thumby.reset()
# Stop audio if still playing
from thumbyAudio import audio
audio.stop()

# Load dependencies
import roms
import menu

# How to load a program
def resetToProgram(program):
display.fill(0)
display.drawText('Loading...', 8, 17, 1)
display.update()
try:
file = open(myPath + "/autorun", "w")
file.write(program["file"])
file.close()
except OSError:
print("Could not write autorun file")
reset()
mem32[_SCRATCH0_ADDR] = 1
soft_reset()

freq(125000000)
index = 0
scroll = 0

# Ask user to choose a ROM
while True:
gb_collect()
program, index, scroll = menu.Menu(index, scroll).choose(roms.catalog())
if not program["file"]:
reset()
if menu.Confirm().choose(program):
resetToProgram(program)
1 change: 1 addition & 0 deletions Games/Silicon8/assets/chip8font.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
𐐐�` p�����p�� ������������������PpP�������PPP�����������<~������~<8X<>� 0`��<~��~<6f����������~<>|������~<�� 0```<~��~~��~<<~��?>|
1 change: 1 addition & 0 deletions Games/Silicon8/assets/schipfont.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
𐐐� ` p�����p����������� @@���������������������������������<~������~<8X<>� 0`��<~��~<6f����������~<>|������~<�� 0```<~��~~��~<<~��?>|
Binary file added Games/Silicon8/assets/splash.bin
Binary file not shown.
Binary file added Games/Silicon8/chip8/3dvipermaze.ch8
Binary file not shown.
16 changes: 16 additions & 0 deletions Games/Silicon8/chip8/3dvipermaze.ch8.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "3D Viper Maze (Timendus, 2020)",
"link": "https://github.com/Timendus/3d-viper-maze",
"desc": "NOTE: this is a grayscale game, and does not work in the emulator.\n\n3D Viper Maze is an homage to the Sinclair ZX81 game 3D Monster Maze from 1981. This is not a game with an endless supply of randomly generated mazes, however. Instead, it has handcrafted levels with vipers, coins and buttons. Your challenge, if you accept it: to find the exit in each maze, while collecting all the coins, in a series of ever more difficult puzzles.\n\nMove around with UP, DOWN, LEFT and RIGHT. Use A or B to show a map of the maze.",
"type": "XOCHIP",
"disp": "GRAYSCALE",
"cmap": "LDWB",
"keys": {
"up": 5,
"down": 8,
"left": 7,
"right": 9,
"a": 1,
"b": 1
}
}
Binary file added Games/Silicon8/chip8/glitch-ghost.ch8
Binary file not shown.
14 changes: 14 additions & 0 deletions Games/Silicon8/chip8/glitch-ghost.ch8.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "Glitch Ghost (Jackie Kircher, 2014)",
"link": "https://johnearnest.github.io/chip8Archive/play.html?p=glitchGhost",
"desc": "Glitch ghost is all alone in the cemetery, please help them make some friends by turning the trespassing humans into new ghosts!\n\nGoal\nEach screen of the cemetery has a unique layout of tombstones. You'll need to figure out how to get each person to run into their own graves. Once scared, each person will run away from glitch ghost and turn right whenever they encounter an obstacle, be it a grave, the fence, or even glitch ghost themselves. Only one person will enter the cemetery at a time, and they'll always come in through the front gate.",
"type": "XOCHIP",
"keys": {
"up": 5,
"left": 7,
"right": 9,
"down": 8,
"a": 6,
"b": 6
}
}
Binary file added Games/Silicon8/chip8/rockto.ch8
Binary file not shown.
15 changes: 15 additions & 0 deletions Games/Silicon8/chip8/rockto.ch8.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "Rockto (SupSuper, 2014)",
"link": "https://johnearnest.github.io/chip8Archive/play.html?p=rockto",
"desc": "An adaptation of \"Boulder Dash\" for CHIP-8",
"type": "SCHIP",
"disp": "SCALED",
"keys": {
"up": 5,
"left": 7,
"right": 9,
"down": 8,
"a": 6,
"b": 6
}
}
Binary file added Games/Silicon8/chip8/slipperyslope.ch8
Binary file not shown.
14 changes: 14 additions & 0 deletions Games/Silicon8/chip8/slipperyslope.ch8.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "Slippery Slope (John Earnest, 2018)",
"link": "https://johnearnest.github.io/chip8Archive/play.html?p=slipperyslope",
"desc": "A very cute little game where you find yourself sliding around, trying to solve each puzzle to get to the exit.\n\nSlide around using UP, DOWN, LEFT and RIGHT. Reset the level with A or B.",
"type": "SCHIP",
"keys": {
"up": 5,
"down": 8,
"left": 7,
"right": 9,
"a": 6,
"b": 6
}
}
3 changes: 2 additions & 1 deletion Games/Silicon8/chip8/snake.ch8.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "Snake",
"name": "Snake (Timo Triisa, 2014)",
"link": "https://github.com/JohnEarnest/chip8Archive/tree/master/src/snake",
"desc": "A very minimalistic implementation of the popular game Snake. Eat the apples to grow the snake, but be careful that you don't hit your tail!\n\nMove the snake around using UP, DOWN, LEFT and RIGHT.",
"type": "VIP",
"keys": {
Expand Down
Binary file added Games/Silicon8/cpu.mpy
Binary file not shown.
Loading