Skip to content

Instantly share code, notes, and snippets.

@HTV04
Last active July 24, 2023 20:53
Show Gist options
  • Save HTV04/c0300c5446f5bb19684e65f142ea6ff5 to your computer and use it in GitHub Desktop.
Save HTV04/c0300c5446f5bb19684e65f142ea6ff5 to your computer and use it in GitHub Desktop.
Mega Drive ROM Header Generator
#!/usr/bin/env python
# Mega Drive ROM Header Generator v1.0
# By HTV04
# Usage: romhead.py [output file]
# Note: ROM header generated is incomplete, complete with romfix (https://github.com/sikthehedgehog/mdtools)
# MIT License
#
# Copyright (c) 2023 HTV04
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import sys
from enum import Enum
class Console(Enum):
DEFAULT = b"MEGA DRIVE"
DEFAULT_US = b"GENESIS"
SEGA_32X = b"32X" # Currently unsupported by SGDK
EVERDRIVE = b"EVERDRIVE"
MEGA_EVERDRIVE = b"SSF" # Used for SGDK bank switching
MEGAWIFI = b"MEGAWIFI"
class RomInfo:
console = Console.DEFAULT.value
copyright_id = b"SEGA"
title_j = b"JAPANESE TITLE"
title_ue = b"OVERSEAS TITLE"
io_support = b"J"
sram_size = 1024
def pad_str(s, l):
s_len = len(s)
if s_len > l:
raise ValueError("String {} is too long ({} > {})".format(s, s_len, l))
return s + (b" " * (l - s_len))
bin = [
pad_str(b"SEGA " + RomInfo.console, 16), # Console
pad_str(b"(C)" + RomInfo.copyright_id, 16), # Copyright (date will be set by romfix)
pad_str(RomInfo.title_j, 48), # Title (Japan)
pad_str(RomInfo.title_ue, 48), # Title (US/Europe)
b"GM 00000000-00", # Serial (blank)
pad_str(b"", 2), # Checksum (will be set by romfix)
pad_str(RomInfo.io_support, 16), # I/O support
b"\x00\x00\x00\x00", # ROM start
pad_str(b"", 4), # ROM end (will be set by romfix)
b"\x00\xFF\x00\x00", # RAM start
b"\x00\xFF\xFF\xFF", # RAM end
b"RA", # SRAM signature
b"\xF8\x20", # SRAM type (SGDK default)
b"\x00\x20\x00\x01", # SRAM start (SGDK default)
(0x1fffff + (RomInfo.sram_size * 2)).to_bytes(4, "big"), # SRAM end
pad_str(b"", 12), # Modem support (blank)
pad_str(b"", 40), # Blank
pad_str(b"JUE", 16) # Region support (all regions)
]
if __name__ == "__main__":
with open(sys.argv[1], "wb") as f:
for i in bin:
f.write(i)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment