Files
uv-k5-v3-emulator/apps/minesweeper
mckero ff14dffb67 Fix the blank screen, correct the multiboot note, and add Minesweeper
The blank screen was self-inflicted and the earlier explanation was wrong. The FMP3 marker at 0x100000 is an ordinary state record -- generation, image_size, image_crc32, firmware_slot/slot_inv, config_bank/bank_inv and a matching state_crc32 (0x661286F1) -- not a pending flag. What actually happened: a firmware uploaded over a state that recorded a different identity made the firmware take the restore/adopt path, which draws nothing (panel 1024/1024 bytes zero) while the serial banner printed normally. Restoring the untouched dump fixed it at once (485/1024 bytes lit) and the three apps reinstalled and were confirmed by 0x0730.

Clearing the marker sectors was tried twice (a whole 8 KiB, then just the 24-byte headers) and is not a fix: it sends the firmware down MB_MARK_MISSING = fresh radio, which adopts the running firmware slowly and without drawing, and its own write-back restores the marker anyway. AGENTS.md and AGENTS.zh-CN.md now say so in place of the wrong claim.

apps/minesweeper/ adds our own 9x9 minesweeper for the 4 KiB overlay: no left/right keys exist on this radio (so the cursor walks with UP/DOWN and digits pick a row then a column), 81 cells need three 9-byte bit arrays rather than a uint16_t mask (the uint16_t version compiled fine and was wrong past cell 15), mines are placed after the first reveal so it cannot lose immediately, and the source compiles clean under gcc -Wall -Wextra -Werror against upstream's real app_api.h. It has not been built for ARM or run -- no toolchain here -- and the README says so.
2026-10-01 22:29:36 +08:00
..

Minesweeper — an overlay app for the F4HWN Labs edition

Our own app: a 9x9 minesweeper that runs on the radio inside the 4 KiB overlay that App/apps/app_overlay.h reserves. It is written against upstream's App/apps/app_api.h and built with upstream's app.ld — neither is vendored here (both are Apache-2.0 files from armel/uv-k1-k5v3-firmware-custom), so drop this folder into App/apps/minesweeper/ next to them, or point -I at a copy.

Why it looks the way it does

constraint consequence
the radio has no left/right keys (UP, DOWN, MENU, EXIT, STAR, F, 0-9 only) the cursor walks the field with UP/DOWN and digits jump to a row then a column: 3 5 = row 3, column 5
4 KiB for text+rodata+data+bss together no lookup tables, no floats, no libc; adjacency is counted on the fly and each cell is one bit
81 cells do not fit a 16-bit mask three 9-byte bit arrays addressed by cell >> 3, cell & 7 — a uint16_t version compiled fine and was wrong past cell 15
the resident pixel helpers do not bound-check put()/invert() clip
no rand() in a freestanding blob a small LCG; mines are placed after the first reveal, keeping the 3x3 around it clear

Keys: UP/DOWN move, 1-9 pick row then column, MENU reveal, F flag, STAR new game, EXIT quit. M in the corner is the remaining-mine count, A1 is the cursor.

Build

arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb -Os -std=gnu11 -ffreestanding \
    -nostdlib -nostartfiles -T app.ld -Wl,--defsym,APP_VMA=0x20000280 \
    -o minesweeper.elf minesweeper_app.c
arm-none-eabi-objcopy -O binary minesweeper.elf minesweeper.bin
pack_app.py minesweeper.bin Minesweeper.app --name Minesweeper --ver 1.0 \
    --vma 0x20000280 --api-min 1      # pack_app.py lives in App/apps/

build.sh does exactly that and needs the Arm GNU Toolchain on PATH.

Then install it from the page: Overlay apps → a slot → pick Minesweeper.app → Install → Ask the radio should answer Minesweeper. On the radio press F then 7 and MENU to run it.

What is verified, and what is not

Verified here: the source compiles clean with gcc -Wall -Wextra -Werror against upstream's real app_api.h (that check caught the API's actual member names — api->fb, print_tiny(s, x, y, statusbar, fill) with five arguments — and the fact that APP_KEY_LEFT/APP_KEY_RIGHT do not exist).

Not verified: it has never been built for ARM or run on the radio, because no arm-none-eabi-gcc and no Docker exist on the machine it was written on. Treat the first build and the first run as the real review.