From d76c76e41ef428a02375981edaa095a955ff1654 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Sat, 24 Oct 2026 03:55:22 +0200 Subject: [PATCH] chore: re-profile Linkboy 4.0.0 Linkboy 4.0.0 keeps the three firmware slots, sizes, md5 table and loader behaviour of 3.11.4. Class names and library addresses are re-read from the 4.0.0 Play build, and the firmware import path is documented. --- emulators/linkboy.yml | 51 +++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/emulators/linkboy.yml b/emulators/linkboy.yml index 6b72bafc0..7f7e2680d 100644 --- a/emulators/linkboy.yml +++ b/emulators/linkboy.yml @@ -7,8 +7,8 @@ version_source: url: "https://play.google.com/store/apps/details?id=com.pixelrespawn.linkboy&hl=en" pattern: '\[\[\["([^"]+)"\]\],\[\[\[\d+' author: "Pixel Respawn LLC" -profiled_date: "2026-10-20" -core_version: "3.11.4" +profiled_date: "2026-10-24" +core_version: "4.0.0" display_name: "Nintendo - Game Boy / Color / Advance (Linkboy)" mode: standalone cores: @@ -23,51 +23,60 @@ systems: notes: | Android package com.pixelrespawn.linkboy, closed source, free on Google Play with a - paid unlock, reached by ES-DE through its LINKBOY find rule. Three Play distribution - builds are read here, 3.11.4 (versionCode 93, minSdk 32, targetSdk 36, xapk sha256 + paid unlock, reached by ES-DE through its LINKBOY find rule. Four Play distribution + builds are read here, 4.0.0 (versionCode 95, minSdk 26, targetSdk 37, xapk sha256 + 9a10e00c6dcd2fdc66490000bf77bfa9846b37dffd31f8d96dc89d7c5997fee1), 3.11.4 + (versionCode 93, minSdk 32, targetSdk 36, xapk sha256 4432cf9ab8ce2d148e8a0e89c26b786e4e7d060f43885d062f6d446b03ca4d32), 3.11.0 (versionCode 86, minSdk 26, xapk sha256 83b92276d28d71e491ebcbec3fa85cef42ef49d8ee0c6fd1bbe0045bc118f866) and 1.4.2 (versionCode 12), all carrying the app signing certificate sha256 feb643cfdd9c49f58eb325fde3d869cefcf59e45dfadb8e540beca35a7b1c28e and the Play distribution source stamp. Emulation lives in liblinkboy.so behind a JNI bridge. - Addresses below are armeabi-v7a of 3.11.4 and class names are those of its - obfuscated dex. + Addresses below are armeabi-v7a of 4.0.0 (liblinkboy.so sha256 + 86334694df475bfba4ec312ef69ca71e45dfda65e51eb074660ca177d80c88f3) and class names + are those of its obfuscated dex. - Four subsystems are declared: GBA, GBC, GB and SGB (ve0.java:16-21). An SGB - cartridge runs in GB mode when prefer-sgb is off (wo0.java:62, c51.java:183-185). + Four subsystems are declared: GBA, GBC, GB and SGB (rd0.java:16-21). An SGB + cartridge runs in GB mode when prefer-sgb is off (y72.java:43, i71.java:203-205, + 285-287). The three firmware images are the only files the emulator reads that it does not - write itself. One table holds their names, sizes and md5 sums (cr.java:8), and the + write itself. One table holds their names, sizes and md5 sums (uq.java:8), and the firmware screen reports each as present, mismatched or absent by comparing the - size and then the md5 of the whole file (br.java:24-88, yz1.java:39, hr1.java:110). + size and then the md5 of the whole file (tq.java:22-85, t32.java:197-204). + Importing a slot from that screen writes firmware/ and the name: a picked zip + gives its first entry whose length equals the slot size, any other document is + copied when its own length does (h.java:127-145, oq.java:58-167). Saves, cheats, thumbnails, keymaps and the ips, ups and bps patches picked up next to a ROM are written or supplied per game, not fixed files. An image is read only while the use-bios preference is on, which is off until set - (wo0.java:63, b75.java:165-173, c51.java:186,268, w41.java:243). The loader appends - firmware/ and the name to the directory handed to setDataDir, the app's external - files directory (c51.java:69, hg3.java:32-38), and opens the result with fopen "rb". + (y72.java:44, tf5.java:186-194, i71.java:207,289, b71.java:233). The loader appends + /firmware/ and the name to the directory handed to setDataDir, the app's external + files directory or its internal one when none is mounted (i71.java:74, + qm3.java:32-41), and opens the result with fopen "rb". A file whose length is not exactly the expected size is closed and treated as absent, as is a short read. On success the loader returns the crc32 of the bytes - (liblinkboy.so 0x1ca40-0x1cbe0, crc32 at 0x1c69c). + (liblinkboy.so 0x1cb10-0x1cd1c, crc32 at 0x1c76c). A missing image stops nothing. The GBA path copies a 236 byte replacement bios compiled into the library over the 16 KB region and zero fills the remainder. Since 3.11.4 a second variant of that replacement is taken when the game code is B4GJ or - B4SJ (0x10a06c-0x10a108). The GB and GBC path hands the reset routine a boot rom + B4SJ (0x10a22c-0x10a2c8). The GB and GBC path hands the reset routine a boot rom present flag, false when no image was loaded, and the machine starts from its post - boot state (0x14f7f4-0x14f878, 0x14f8f8-0x14f914). + boot state (0x14f9b4-0x14fa38, 0x14fab8-0x14fad4). Since 3.11.4 a loaded GBA image is not run for every cartridge. When the ROM is at least 0xa0 bytes the crc32 of the 156 header bytes from offset 4 is compared with a fixed value, and a mismatch logs "Invalid logo, skipping BIOS" and resets with the boot flag false. The image stays installed and the machine starts from its post - boot state (0x10a14c-0x10a1a4). + boot state (0x10a2ec-0x10a364). Save states record the crc32 of the image they were made under. Loading a state whose value differs from the running machine re-reads the file and refuses the state - when the crc32 still disagrees (0x10ad00-0x10ad58, 0x1500c0-0x150124). + when the crc32 still disagrees (0x10aecc-0x10af24, 0x1501b0-0x1501bc, + 0x150280-0x1502e4). files: - name: gba_bios.bin @@ -81,7 +90,7 @@ files: config_key: "use-bios" description: "Game Boy Advance BIOS" note: "Read into the 16 KB bios region when use-bios is on. Absent, mismatched in size or short, the region is filled with a replacement bios compiled into the library and zero padded. A cartridge whose header logo fails the crc32 test boots past it." - source_ref: "Linkboy 3.11.4 cr.java:8, br.java:24-88, liblinkboy.so 0x10a06c-0x10a108 (size argument 0x4000), 0x10a14c-0x10a1a4 (logo test), loader 0x1ca40-0x1cbe0" + source_ref: "Linkboy 4.0.0 uq.java:8, tq.java:22-85, liblinkboy.so 0x10a22c-0x10a2c8 (size argument 0x4000 at 0x10a260), 0x10a2ec-0x10a364 (logo test), loader 0x1cb10-0x1cd1c" - name: gbc_bios.bin path: firmware/gbc_bios.bin @@ -94,7 +103,7 @@ files: config_key: "use-bios" description: "Game Boy Color boot ROM" note: "Read when use-bios is on and the machine is a Game Boy Color. Without it the reset routine receives a false boot rom flag and the machine starts from its post boot state." - source_ref: "Linkboy 3.11.4 cr.java:8, br.java:24-88, liblinkboy.so 0x14f860-0x14f870 (size argument 0x900), 0x14f8f8-0x14f914, loader 0x1ca40-0x1cbe0" + source_ref: "Linkboy 4.0.0 uq.java:8, tq.java:22-85, liblinkboy.so 0x14fa20-0x14fa2c (size argument 0x900), 0x14fab8-0x14fad4, loader 0x1cb10-0x1cd1c" - name: gb_bios.bin path: firmware/gb_bios.bin @@ -107,4 +116,4 @@ files: config_key: "use-bios" description: "Game Boy boot ROM" note: "Read when use-bios is on and the machine is a Game Boy. Without it the reset routine receives a false boot rom flag and the machine starts from its post boot state." - source_ref: "Linkboy 3.11.4 cr.java:8, br.java:24-88, liblinkboy.so 0x14f84c-0x14f85c (size argument 0x100), 0x14f8f8-0x14f914, loader 0x1ca40-0x1cbe0" + source_ref: "Linkboy 4.0.0 uq.java:8, tq.java:22-85, liblinkboy.so 0x14fa0c-0x14fa18 (size argument 0x100), 0x14fab8-0x14fad4, loader 0x1cb10-0x1cd1c"