Skip to content

Instantly share code, notes, and snippets.

@blu
Last active March 5, 2025 18:44
Show Gist options
  • Save blu/00501400ba73c1a010946deb4d92deb7 to your computer and use it in GitHub Desktop.
Save blu/00501400ba73c1a010946deb4d92deb7 to your computer and use it in GitHub Desktop.
game-and-watch homebrew quickstart on macos Big Sur

A guide how to get game-and-watch-base and game-and-watch-retro-go built and deployed from macOS Big Sur

NOTE: All device-comm steps given for G&W Mario over ST-link/V2; update accordingly for G&W device and SWD iface

External references

https://github.com/Upcycle-Electronics/game-and-watch-hardware
https://github.com/ghidraninja/game-and-watch-backup
https://github.com/ghidraninja/game-and-watch-base
https://github.com/STMicroelectronics/STM32CubeH7
https://sourceware.org/pub/newlib
https://github.com/kbeckmann/game-and-watch-retro-go

base steps

arm-none-eabi-gcc

NOTE: Current MacPorts arm-none-eabi-gcc version 12.2.0

$ sudo port install arm-none-eabi-binutils
$ sudo port install arm-none-eabi-gcc

open-ocd

$ brew install open-ocd

game-and-watch-backup

$ git clone https://github.com/ghidraninja/game-and-watch-backup
$ cd game-and-watch-backup
$ ./1_sanity_check.sh stlink mario
$ ./2_backup_flash.sh stlink mario
$ ./3_backup_internal_flash.sh stlink mario
$ ./4_unlock_device.sh stlink mario
$ ./5_restore.sh stlink mario

newlib 4.2.0

NOTE: MacPorts arm-none-eabi-gcc 12.2.0 uses newlib 4.2.0.20211231 -- it's imperative to use the exact same version

$ wget ftp://sourceware.org/pub/newlib/newlib-4.2.0.20211231.tar.gz
$ tar xf newlib-4.2.0.20211231.tar.gz
$ cd newlib-4.2.0.20211231
$ ./configure \
    --target=arm-none-eabi \
    --enable-newlib-nano-formatted-io \
    --enable-newlib-nano-malloc \
    --enable-lite-exit \
    --enable-newlib-reent-small \
    --enable-newlib-global-atexit \
    --disable-newlib-fvwrite-in-streamio \
    --disable-newlib-fseek-optimization \
    --disable-newlib-wide-orient \
    --disable-newlib-unbuf-stream-opt \
    --disable-nls \
    --disable-newlib-supplied-syscalls
$ make
$ cp arm-none-eabi/thumb/v7e-m+dp/hard/newlib/libc.a /opt/local/arm-none-eabi/lib/libc_nano.a
$ cp arm-none-eabi/thumb/v7e-m+dp/hard/newlib/libg.a /opt/local/arm-none-eabi/lib/libg_nano.a

STM32CubeH7

$ git clone https://github.com/STMicroelectronics/STM32CubeH7
$ cd STM32CubeH7
$ git checkout tags/v1.9.1
$ export STM32CubeH7=$PWD

STM32CubeH7 minimal (sparse checkout)

As STM32CubeH7 is massive one may want to do a sparse checkout of the subtree of interest instead:

$ mkdir STM32CubeH7
$ cd STM32CubeH7
$ git init
$ git remote add -f origin https://github.com/STMicroelectronics/STM32CubeH7
$ git sparse-checkout set Drivers
$ git checkout tags/v1.9.1
$ export STM32CubeH7=$PWD

game-and-watch-base

$ git clone https://github.com/ghidraninja/game-and-watch-base
$ cd game-and-watch-base
$ ln -s $STM32CubeH7/Drivers
$ make
$ make OCDIFACE=interface/stlink.cfg flash

retro-go extra steps

arm-none-eabi-gdb

On Big Sur MacPorts 2.8.0 provides arm-none-eabi-gdb only for x86-64 hosts. But arm-none-eabi-gdb can be built manually from port sources on arm64 hosts, as long as one patches the file /opt/local/var/macports/sources/rsync.macports.org/macports/release/tarballs/ports/_resources/port1.0/group/crossgdb-1.0.tcl to not check for the host arch:

        # gdb is not supported on macOS ARM now
        # See https://inbox.sourceware.org/gdb/3185c3b8-8a91-4beb-a5d5-9db6afb93713@Spark
        supported_archs x86_64 i386

Just comment out the supported_archs clause above. Then you can build and install the port:

$ sudo port build arm-none-eabi-gdb
$ sudo port install arm-none-eabi-gdb

game-and-watch-retro-go

$ git clone --recurse-submodules https://github.com/kbeckmann/game-and-watch-retro-go
$ cd game-and-watch-retro-go
$ pip3 install -r requirements.txt
$ ln -s $STM32CubeH7/Drivers
$ make GNW_TARGET=mario
$ make ADAPTER=stlink GNW_TARGET=mario flash

If the fist make step above results in a link error:

/opt/local/lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld: /opt/local/lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/lib/libc_nano.a(lib_a-syscalls.o): in function `_sbrk':
/Users/blu/proj/newlib-4.2.0.20211231/arm-none-eabi/thumb/v7e-m+dp/hard/newlib/libc/sys/arm/../../../../../../../.././newlib/libc/sys/arm/syscalls.c:519: undefined reference to `end'
collect2: error: ld returned 1 exit status

That means your newlib-nano was built with --enable-newlib-supplied-syscalls for some reason (e.g. by default). The following patch to retro-go ld script saves you a newlib-nano rebuild:

diff --git a/STM32H7B0VBTx_FLASH.ld b/STM32H7B0VBTx_FLASH.ld
index 3fe7886..1651102 100644
--- a/STM32H7B0VBTx_FLASH.ld
+++ b/STM32H7B0VBTx_FLASH.ld
@@ -502,6 +502,13 @@ SECTIONS
     __bss_end__ = _ebss;
   } >DTCMRAM
 
+  ._ender :
+  {
+    . = ALIGN(8);
+    PROVIDE ( end = . );
+    PROVIDE ( _end = . );
+  } >DTCMRAM
+
   ._persistent (NOLOAD) :
   {
     . = ALIGN(8);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment