Skip to content

Instantly share code, notes, and snippets.

@codeman38
Created February 20, 2022 16:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codeman38/8d3b96f4fffb655293de3aa7ac67650b to your computer and use it in GitHub Desktop.
Save codeman38/8d3b96f4fffb655293de3aa7ac67650b to your computer and use it in GitHub Desktop.
Decode and display the boot logo in a Game Boy ROM
#!/usr/bin/python3
# Reads the Nintendo logo from a Game Boy ROM,
# pairs up 32-bit DWORDs from each half of the logo,
# pairs up nibbles from each half of the DWORD,
# then outputs the decoded logo as a readable bitmap.
#
# codeman38
# original script coded 8 June 2010
# revised 3 July 2011
# cleaned up and updated for Python 3, 20 Feb 2022
import argparse
import struct
def main():
parser = argparse.ArgumentParser(
description='Decodes a Game Boy boot logo in a ROM.')
parser.add_argument('filename',
help='ROM filename')
parser.add_argument('offset', nargs='?',
type=int, default=0x184,
help='offset to read from (default: %(default)d)')
args = parser.parse_args()
fp = open(args.filename, 'rb')
address = args.offset
fp.seek(address)
logo = fp.read(0x30)
dwords = struct.unpack('>12I',logo)
decoded = [decode_dword(d) for d in pair_dwords(dwords)]
logo_dec = struct.pack('>12I', *decoded)
print_logo(logo_dec)
def pair_dwords(dwords):
"""
Logo is stored as all even-numbered DWORDs followed by
all odd-numbered DWORDs. This gets them in the right order.
"""
for x in range(len(dwords)//2):
yield dwords[x]
yield dwords[len(dwords)//2 + x]
def decode_dword(dword):
"""
For input nibbles 12345678, output nibbles are 15263748.
In other words, pair up nibbles from each half of the DWORD.
"""
outval = 0
for x in range(3,-1,-1):
outval *= 16
outval += (dword>>16+4*x)%16
outval *= 16
outval += (dword>>4*x)%16
return outval
def print_logo(logo):
lines = ['']*8
for y in range(len(logo)):
lines[y%8] += '{0:08b}'.format(logo[y])
for y in lines:
print(y.replace('0',' ').replace('1','#'))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment