Skeetendo

’Cause all games were better on the GBC

You are not logged in.

#1 2017-06-26 15:36:22

Rangi
Member
Registered: 2016-05-09
Post 747/870

disasm.py: a Python 3 disassembler

I wrote a disassembler for GameBoy Z80 code in Python 3.

Here it is on GitHub: disasm.py

You run it with:

$ ./disasm.py a.bin > a.asm

Or to specify an entry point other than the start of the file, e.g. address $10ab:

$ ./disasm.py a.bin 10ab > a.asm

One GameBoy-specific feature is that it uses the hardware register names from gbhw.asm.

It can parse the entire gbc_bios.bin bootloader responsible for displaying this screen:

MhaUNyi.png

Here's a sample of its output:

ENTRY_POINT:
    ld sp, $fffe                                      ; 000000: 31 fe ff
    ld a, $02                                         ; 000003: 3e 02
    jp Function007c                                   ; 000005: c3 7c 00

    db $d3, $00, $98, $a0, $12, $d3, $00, $80         ; 000008-00000f
    db $00, $40, $1e, $53, $d0, $00, $1f, $42         ; 000010-000017
    db $1c, $00, $14, $2a, $4d, $19, $8c, $7e         ; 000018-00001f
    ...

Function0200:
    ld hl, $8000                                      ; 000200: 21 00 80
Function0203:
    xor a                                             ; 000203: af
Function0204:
    ld [hli], a                                       ; 000204: 22
    bit 5, h                                          ; 000205: cb 6c
    jr z, Function0204                                ; 000207: 28 fb
    ret                                               ; 000209: c9

Function020a:
    ld a, [hli]                                       ; 00020a: 2a
    ld [de], a                                        ; 00020b: 12
    inc de                                            ; 00020c: 13
    dec c                                             ; 00020d: 0d
    jr nz, Function020a                               ; 00020e: 20 fa
    ret                                               ; 000210: c9

Function0211:
    push hl                                           ; 000211: e5
    ld hl, $ff0f                                      ; 000212: 21 0f ff
    res 0, [hl]                                       ; 000215: cb 86
Function0217:
    bit 0, [hl]                                       ; 000217: cb 46
    jr z, Function0217                                ; 000219: 28 fc
    pop hl                                            ; 00021b: e1
    ret                                               ; 00021c: c9

Function021d:
    ld de, $ff00                                      ; 00021d: 11 00 ff
    ld hl, $d003                                      ; 000220: 21 03 d0
    ld c, $0f                                         ; 000223: 0e 0f
    ld a, $30                                         ; 000225: 3e 30
    ld [de], a                                        ; 000227: 12
    ld a, $20                                         ; 000228: 3e 20
    ld [de], a                                        ; 00022a: 12
    ld a, [de]                                        ; 00022b: 1a
    cpl                                               ; 00022c: 2f
    and c                                             ; 00022d: a1
    swap a                                            ; 00022e: cb 37
    ld b, a                                           ; 000230: 47
    ld a, $10                                         ; 000231: 3e 10
    ld [de], a                                        ; 000233: 12
    ld a, [de]                                        ; 000234: 1a
    cpl                                               ; 000235: 2f
    and c                                             ; 000236: a1
    or b                                              ; 000237: b0
    ld c, a                                           ; 000238: 4f
    ld a, [hl]                                        ; 000239: 7e
    xor c                                             ; 00023a: a9
    and $f0                                           ; 00023b: e6 f0
    ld b, a                                           ; 00023d: 47
    ld a, [hli]                                       ; 00023e: 2a
    xor c                                             ; 00023f: a9
    and c                                             ; 000240: a1
    or b                                              ; 000241: b0
    ld [hld], a                                       ; 000242: 32
    ld b, a                                           ; 000243: 47
    ld a, c                                           ; 000244: 79
    ld [hl], a                                        ; 000245: 77
    ld a, $30                                         ; 000246: 3e 30
    ld [de], a                                        ; 000248: 12
    ret                                               ; 000249: c9

(The line breaks were added by me. Everything else was auto-generated.)

Last edited by Rangi (2017-06-26 18:08:23)


Pokémon Polished Crystal (GitHub) — version 2.2.0 released
Pokémon Red★ and Blue★: Space World Edition (GitHub) — updated August 19!
Polished Map: pokered+pokecrystal map, tileset, and palette editor — version 3.5.1 released!

Offline

#2 2017-06-26 18:20:15

Rangi
Member
Registered: 2016-05-09
Post 748/870

Re: disasm.py: a Python 3 disassembler

Unfortunately it cannot be used to disassemble whole games. I was able to disassemble Pokémon Crystal, but only these 1,500 lines were recognized as code, and the rest became raw db data.

The problem is that jump tables, and other forms of indirect calling, are not understood. So code like this in pokecrystal's engine/intro_menu.asm:

StartTitleScreen: ; 6219
    ...
    ld e, a
    ld d, 0
    ld hl, .dw
    add hl, de
    add hl, de
    ld a, [hli]
    ld h, [hl]
    ld l, a
    jp [hl]
; 626a

.dw
    dw _MainMenu
    dw DeleteSaveData
    dw CrystalIntroSequence
    dw CrystalIntroSequence
    dw ResetClock

is disassembled to this by my program:

Function6219:
    ...
    ld e, a                                           ; 00625e: 5f
    ld d, $00                                         ; 00625f: 16 00
    ld hl, $626a                                      ; 006261: 21 6a 62
    add hl, de                                        ; 006264: 19
    add hl, de                                        ; 006265: 19
    ld a, [hli]                                       ; 006266: 2a
    ld h, [hl]                                        ; 006267: 66
    ld l, a                                           ; 006268: 6f
    jp hl                                             ; 006269: e9
    db $e8, $5a, $89, $63, $0b, $62, $0b, $62         ; 00626a-006271
    db $92, $63                                       ; 006272-006273

Last edited by Rangi (2017-06-26 19:20:17)


Pokémon Polished Crystal (GitHub) — version 2.2.0 released
Pokémon Red★ and Blue★: Space World Edition (GitHub) — updated August 19!
Polished Map: pokered+pokecrystal map, tileset, and palette editor — version 3.5.1 released!

Offline

Board footer

Powered by FluxBB