devkitSMS

repository·master·Indexed 43 days ago

https://github.com/sverx/devkitsms

A collection of tools and libraries for developing homebrew software for SEGA Master System, Game Gear, SG-1000/SC-3000, and ColecoVision using C and the SDCC compiler. Includes SMSlib for high-level system tasks, MBMlib for MoonBlaster module playback on FM chips, and PSGlib for PSG music and sound effect management.

Tokens
16.3K
Snippets
60
Records
73
Agent score
49%

What's inside devkitSMS

  1. Understand assets2banks attribute processing order

    master

    When a config file is used, assets2banks processes attributes in a specific sequence. Understanding this order is critical when combining multiple attributes:

    1. Setup: :format, :text, :ignore, and :alias are applied first.
    2. Import: Data is imported from the file (respecting :segment instructions).
    3. Discard: :discard attributes are applied to remove unwanted data.
    4. Manipulate: :overwrite, :modify, and :replace are applied to the remaining data.
    5. Finalize: :header and :append are applied last to add leading/trailing values.
  2. How Multibank support works in PSGlib

    master

    If PSGLIB_MULTIBANK is defined before including PSGlib.h, the library supports song data larger than 16kB by automatically switching ROM banks.

    Key Behaviors

    • Automatic Switching: When using the multibank versions of PSGPlay, PSGPlayLoops, or PSGPlayNoRepeat, you provide an initial bank. PSGlib remembers this bank and automatically switches banks during PSGFrame() calls if the song data spans multiple banks.
    • Data Requirement: Song data must be consecutive in ROM; it cannot be segmented across non-contiguous addresses.
    • Bank Side Effects: When PSGFrame() returns, the current bank in slot 2 may have changed. You should take steps to manage this, such as manually setting the bank again or using SMS_saveROMBank/restoreROMBank to ensure your program's execution context remains correct.

    Without Multibank

    If PSGLIB_MULTIBANK is not defined:

    • Song data cannot exceed 16kB.
    • You must manually set the correct bank before calling PSGFrame().
  3. Compile and link SMS/Game Gear programs with SMSlib

    master

    To build a program for the Sega Master System (SMS) or Game Gear using SMSlib, you must follow a three-step compilation and linking process using sdcc and ihx2sms.

    SMS Compilation Workflow

    1. Compile source files: Use sdcc with the -mz80 flag, include the SMSlib source directory with -I, and provide the peep-file rules.
    2. Link objects: Link the startup code (crt0_sms.rel), the SMSlib library, and your compiled .rel files. Ensure crt0_sms.rel is the first object in the link command. Use --no-std-crt0 and specify the data location (e.g., --data-loc 0xC000).
    3. Convert to SMS format: Convert the resulting .ihx file to a .sms file using ihx2sms.

    Game Gear Compilation Differences

    When targeting the Game Gear instead of the SMS:

    • Define TARGET_GG by adding the -DTARGET_GG flag to the sdcc command.
    • Use SMSlib_GG.lib instead of SMSlib.lib during the linking step.
    # Step 1: Compile to .rel
    sdcc -mz80 -I../../SMSlib/src --peep-file ../../SMSlib/src/peep-rules.txt -c main.c
    
    # Step 2: Link to .ihx
    sdcc -o first.ihx --no-std-crt0 --data-loc 0xC000 ../../crt0/crt0_sms.rel ../../SMSlib/src/SMSlib.lib main.rel
    
    # Step 3: Convert to .sms
    ihx2sms first.ihx first.sms
  4. Compile and link SMSlib programs

    master

    To build a program for the Sega Master System using SMSlib, you must follow a three-step compilation and linking process using sdcc and ihx2sms.

    1. Compile source files: Use sdcc with the -mz80 target. You must include the SMSlib source directory with the -I flag and provide the peep-rules file using --peep-file to ensure correct Z80 instruction optimization.
    2. Link objects: Link the compiled .rel files. The linking order is critical: the startup code (crt0_sms.rel) must come first, followed by the SMSlib library (SMSlib.lib), and finally your application's .rel files. Use --no-std-crt0 and specify the data location (e.g., --data-loc 0xC000).
    3. Convert to SMS format: Convert the resulting .ihx file to a .sms file using the ihx2sms tool.
    # Step 1: Compile source files
    sdcc -mz80 -I../../SMSlib/src --peep-file ../../SMSlib/src/peep-rules.txt -c main.c
    
    # Step 2: Link files
    sdcc -o hello.ihx --no-std-crt0 --data-loc 0xC000 ../../crt0/crt0_sms.rel ../../SMSlib/src/SMSlib.lib main.rel
    
    # Step 3: Convert to .sms
    ihx2sms hello.ihx hello.sms
  5. Convert IHX to ColecoVision MegaCart ROMs with makecvmc

    master

    Use the makecvmc tool to convert Intel Hex (.ihx) files (typically generated by SDCC) into binary (.rom) files compatible with ColecoVision MegaCart ROMs.

    The tool supports specific ROM sizes: 128, 256, 512, or 1024 KiB. Files of any other size are not supported and will not be generated.

    makecvmc [options] infile.ihx outfile.rom
  6. Load SGlib code onto a BASIC IIIa/IIIb cartridge

    master

    You can load SGlib software onto an SC-3000 BASIC cartridge via the cassette interface. The program is loaded to address 0x9800 and executed using CALL &H9800 in BASIC.

    Steps:

    1. Link with BASIC crt0: Use crt0_BASIC.rel and set --code-loc 0x98a0 to place code after the interrupt handler.
    2. Convert to Binary: Use objcopy to convert the .ihx output to a .bin file.
    3. Create Audio File: Use a tool like SC-TapeWave to convert the binary into an SC-3000 formatted audio file.

    Note: Program size is limited by RAM: BASIC IIIa has 12 KiB available after the load address; BASIC IIIb has 26 KiB.

    # 1. Link
    sdcc -o your_program.ihx -mz80 --no-std-crt0 --code-loc 0x98a0 --data-loc 0xC000 crt0_BASIC.rel your_program.rel SGlib.lib
    
    # 2. Convert to binary
    objcopy -Iihex -Obinary your_program.ihx your_program.bin
  7. Allocate large assets or create a 32 KiB ROM using --firstbank

    master

    The --firstbank option can be used to allocate a single asset or asset group larger than 16 KB, or to consolidate all assets into a single 32 KiB ROM block.

    To create a 32 KiB block for assets:

    assets2banks assets --firstbank=1,32768 --compile

    Linking for 32 KiB ROM

    If using --compile (Segmented): Use the -Wl-b_BANK1=0x0000 flag:

    sdcc -o output.ihx -mz80 --data-loc 0xC000 -Wl-b_BANK1=0x0000 --no-std-crt0 crt0_sms.rel main.rel SMSlib.lib bank1.rel

    If compiling bank1.c manually (Non-segmented): Omit the BANK1 linker instruction:

    sdcc -o output.ihx -mz80 --data-loc 0xC000 --no-std-crt0 crt0_sms.rel main.rel SMSlib.lib bank1.rel
    assets2banks assets --firstbank=1,32768  --compile
  8. Compile SMSlib examples using the provided Makefile

    master

    To build the palette64 example, use the included Makefile. This process assumes that sdcc and ihx2sms are available in your system's PATH. If you have compiled SMSlib yourself, you must edit the Makefile to point to your custom library location instead of the pre-compiled version in the repository.

    The compilation workflow follows three steps:

    1. Compile source files: Individual .c files are compiled into .rel objects using sdcc with the -c flag, including the SMSlib source directory and peep-file rules.
    2. Link objects: The .rel files are linked into an .ihx file. The linker requires crt0_sms.rel to be listed first, followed by the SMSlib.lib library, and finally the individual object files.
    3. Convert to SMS: The .ihx file is converted to a playable .sms ROM using the ihx2sms tool.
    # Step 1: Compile to .rel
    sdcc -mz80 -I../../SMSlib/src --peep-file ../../SMSlib/src/peep-rules.txt -c main.c
    
    # Step 2: Link to .ihx
    sdcc -o palette64.ihx --no-std-crt0 --data-loc 0xC000 ../../crt0/crt0_sms.rel ../../SMSlib/src/SMSlib.lib main.rel
    
    # Step 3: Convert to .sms
    ihx2sms palette64.ihx palette64.sms
  9. Project structure and library requirements by platform

    master

    Depending on your target hardware, you must place specific runtime files and libraries in your project root (or in subfolders like crt0/, SMSlib/, etc.).

    Target PlatformRuntime File (in crt0/)Library Files (in SMSlib/ or SGlib/)
    Master System (SMS)crt0_sms.relSMSlib.h, SMSlib.lib
    Game Gear (GG)crt0_sms.relSMSlib.h, SMSlib_GG.lib
    SG-1000/SC-3000crt0_sg.relSGlib.h, SGlib.lib
    ColecoVision (CV)crt0_cv.relSGlib.h, SGlib_CV.lib

    Optional Libraries:

    • PSG Audio: PSGlib.h and PSGlib.lib (use PSGlib_CV.lib for ColecoVision).
    • MoonBlaster (FM): MBMlib.h and MBMlib.rel.
  10. Build a SEGA Master System (SMS) program

    master

    To build an SMS program, include SMSlib.h in your source code. The build process involves three steps: compiling, linking, and generating the ROM.

    1. Compile: Use sdcc with the -mz80 flag and the peep-rules.txt file.

    2. Link: Link with crt0_sms.rel first, then your object file, then SMSlib.lib last. Use --no-std-crt0 and specify the data location.

    3. Generate ROM: Use the makesms utility to convert the .ihx file to a .sms file. The utility handles ROM size padding (multiples of 16 KiB) and checksums if a SEGA header is present.

    # 1. Compile
    sdcc -c -mz80 --peep-file peep-rules.txt your_program.c
    
    # 2. Link (Note order: crt0 first, library last)
    sdcc -o your_program.ihx -mz80 --no-std-crt0 --data-loc 0xC000 crt0_sms.rel your_program.rel SMSlib.lib
    
    # 3. Build ROM
    makesms your_program.ihx your_program.sms
  11. Use SEGA ROM paging for SMS/GG/SG/SC (> 48 KiB)

    master

    To use ROMs larger than 48 KiB, you must use bank mapping.

    1. Code Constraints: Your main code must be restricted to the first 32 KiB, as the last 16 KiB is paged out. Use the SMS_mapROMBank(n) or SG_mapROMBank(n) macro to map banks.

    2. Data Organization: Place data into separate .c files for each 16 KiB bank (e.g., bank2.c, bank3.c). Compile each with a unique CONST segment name:

    sdcc -c -mz80 --constseg BANK2 bank2.c

    3. Linking: Instruct the linker to place data banks at 0x8000 + (bank_number * 0x10000). For example, BANK2 goes to 0x28000. The crt0 file must come first, and bank .rel files must come last in ascending order.

    Example Linker Command:

    sdcc -o your_program.ihx -mz80 --no-std-crt0 --data-loc 0xC000 -Wl-b_BANK2=0x28000 -Wl-b_BANK3=0x38000 crt0_sms.rel your_program.rel SMSlib.lib bank2.rel bank3.rel
    # Compile data banks
    sdcc -c -mz80 --constseg BANK2 bank2.c
    sdcc -c -mz80 --constseg BANK3 bank3.c
    
    # Link everything
    sdcc -o your_program.ihx -mz80 --no-std-crt0 --data-loc 0xC000 -Wl-b_BANK2=0x28000 -Wl-b_BANK3=0x38000 crt0_sms.rel your_program.rel SMSlib.lib bank2.rel bank3.rel