AgentSkillsCN

S1disasm Guide

S1 disasm 指南

SKILL.md

s1disasm Navigation Guide

This skill provides guidance on finding, identifying, and interpreting items in the Sonic 1 disassembly (docs/s1disasm/).

Directory Structure

The disassembly is organized into these major directories:

DirectoryContentsNotes
_incObj/Object codeOne file per object: HEX Name.asm (e.g., 1F Crabmeat.asm)
_anim/Animation scriptsPer-object animation data (e.g., Crabmeat.asm)
_maps/Sprite mappingsPer-object frame definitions (e.g., Crabmeat.asm)
artnem/Nemesis-compressed artSprite and tile art (.nem extension or .bin)
artkos/Kosinski-compressed artLevel tile patterns
artunc/Uncompressed artRaw tile data (.bin)
collide/Collision dataHeight arrays and per-zone collision indices
levels/Level layoutsUncompressed FG/BG layouts (e.g., ghz1.bin)
map16/16x16 block mappingsPer-zone chunk definitions
map256/256x256 metatile mappingsPer-zone block definitions
palette/Palette filesUncompressed .bin files (32 bytes = 16 colors)
objpos/Object placement dataPer-act object positions
demodata/Demo recordingsInput playback data
misc/Miscellaneous dataCredits, ending data, etc.

Key Source Files

FileContents
sonic.asmMain assembly source (equivalent of S2's s2.asm)
Constants.asmRAM addresses, object field offsets, sound IDs
Macros.asmAssembly macros
MacroSetup.asmMacro setup and configuration
s1.sounddriver.asmSMPS Z80 sound driver

Compression Types

ExtensionTypeTool FlagDescription
.nem / .bin (in artnem/)NemesisnemSprite art, HUD graphics
.kos / .bin (in artkos/)KosinskikosLevel tiles
.bin (in artunc/)UncompressedbinRaw tile data, palettes
.eniEnigmaeniBlock mappings (if present)

Note: Sonic 1 disassembly often uses .bin extension for all types. The directory determines the compression: artnem/ = Nemesis, artkos/ = Kosinski, artunc/ = Uncompressed.

Finding Items with RomOffsetFinder

Important: All RomOffsetFinder commands for Sonic 1 require the --game s1 flag.

Search Command (Most Common)

bash
# Search by partial name
mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s1 search Crabmeat" -q

# Search for zone-specific items
mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s1 search GHZ" -q

# Search for palettes
mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s1 search Pal_" -q

List Command

bash
# List all Nemesis-compressed items
mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s1 list nem" -q

# List all uncompressed items
mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s1 list bin" -q

# List all compression types
mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s1 list" -q

Verify and Export

bash
# Verify a single offset
mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s1 verify Nem_Crabmeat" -q

# Batch verify all Nemesis items
mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s1 verify-batch nem" -q

# Export as Java constants
mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s1 export nem ART_" -q

Label Naming Conventions

Sonic 1 uses different label prefixes from Sonic 2:

S1 PrefixS2 EquivalentMeaningExample
Nem_ArtNem_Nemesis artNem_Crabmeat, Nem_GHZ_1st
Kos_ArtKos_Kosinski artKos_GHZ, Kos_LZ
Unc_ArtUnc_Uncompressed artUnc_Sonic
Map_MapUnc_Sprite mappingsMap_Crabmeat, Map_Sonic
Ani_(inline)Animation scriptsAni_Crabmeat, Ani_Sonic
Blk16_(16x16 mappings)16x16 blocksBlk16_GHZ
Blk256_(128x128 mappings)256x256 metatilesBlk256_GHZ
Pal_Pal_Palette (same as S2)Pal_GHZ, Pal_Sonic
PLC_PLC_Pattern Load CuePLC_GHZ, PLC_Main
Obj_ / ObjXXObj_Object code entryObj1F (Crabmeat)
SonAni_(inline)Sonic animation IDSonAni_Walk, SonAni_Roll
DPLC_(inline)Dynamic Pattern Load CueDPLC_Sonic

Zone Abbreviations

AbbrevFull NameZone ID
GHZGreen Hill Zone0x00
LZLabyrinth Zone0x01
MZMarble Zone0x02
SLZStar Light Zone0x03
SYZSpring Yard Zone0x04
SBZScrap Brain Zone0x05
FZFinal Zone (Ending)0x06
SSSpecial Stage0x07

Object File Organization

Unlike Sonic 2 where objects are defined inline in s2.asm, Sonic 1 has separate files per object in _incObj/:

File Naming Pattern

code
_incObj/HEX Name.asm

Where HEX is the 2-digit hexadecimal object ID.

Examples:

  • _incObj/1F Crabmeat.asm - Crabmeat badnik (ID 0x1F)
  • _incObj/22 Buzz Bomber.asm - Buzz Bomber badnik (ID 0x22)
  • _incObj/41 Springs.asm - Springs (ID 0x41)
  • _incObj/3D Boss - Green Hill (part 1).asm - GHZ Boss

Multi-Part Objects

Some objects span multiple files:

  • _incObj/11 Bridge (part 1).asm, _incObj/11 Bridge (part 2).asm, etc.
  • _incObj/3D Boss - Green Hill (part 1).asm, _incObj/3D Boss - Green Hill (part 2).asm

Related Files

Each object typically has corresponding files in:

  • _anim/Name.asm - Animation script definitions
  • _maps/Name.asm - Sprite frame mappings (5-byte piece format)

Object System Reference

Object RAM Layout

S1 uses $FFFFCF00 as Object_RAM base (vs S2's $FFB000).

Object Status Table Offsets

S1 uses named field macros that differ from S2:

S1 FieldS2 EquivalentOffsetSizeDescription
obIDid0x00byteObject ID
obRenderrender_flags0x01byteRender flags
obGfxart_tile0x02wordArt tile base
obMapmappings0x04longMappings pointer
obXx_pos0x08word+byteX position (16.8 fixed)
obScreenYy_screen0x0AwordScreen-relative Y (unused in some objects)
obYy_pos0x0Cword+byteY position (16.8 fixed)
obVelXx_vel0x10wordX velocity
obVelYy_vel0x12wordY velocity
obInertiainertia0x14wordGround speed
obHeighty_radius0x16byteY radius
obWidthx_radius0x17byteX radius
obPrioritypriority0x18wordDisplay priority
obActWidwidth_pixels0x19byteActive width for display
obFramemapping_frame0x1AbyteCurrent mapping frame
obAnimanim0x1CbyteCurrent animation
obPrevAniprev_anim0x1DbytePrevious animation
obAniFrameanim_frame0x1EbyteAnimation frame index
obTimeFrameanim_frame_duration0x1FbyteFrame duration counter
obColTypecollision_flags0x20byteCollision type + size
obColPropcollision_property0x21byteCollision property (e.g., hit count)
obStatusstatus0x22byteStatus bits
obRespawnNorespawn_index0x23byteRespawn table index
obRoutineroutine0x24byteCurrent routine
ob2ndRoutroutine_secondary0x25byteSecondary routine
obAngleangle0x26byteAngle
obSubtypesubtype0x28byteObject subtype

Object Routine Pattern

asm
ObjXX:                              ; Object entry point
    moveq   #0,d0
    move.b  obRoutine(a0),d0
    move.w  ObjXX_Index(pc,d0.w),d1
    jmp     ObjXX_Index(pc,d1.w)

ObjXX_Index:
    dc.w ObjXX_Init - ObjXX_Index   ; routine 0
    dc.w ObjXX_Main - ObjXX_Index   ; routine 2
    dc.w ObjXX_Delete - ObjXX_Index ; routine 4

Sprite Mappings Format (S1 Format)

S1 uses a 5-byte per piece format (S2 uses 6 bytes):

code
Frame header:
  dc.b  <piece_count>              ; Single byte (S2 uses dc.w)

Per piece (5 bytes):
  dc.b  <y_offset>                 ; Signed byte
  dc.b  <size>                     ; bits 0-1: width-1, bits 2-3: height-1
  dc.b  <pattern_hi>               ; High byte of pattern word
  dc.b  <pattern_lo>               ; Low byte of pattern word
  dc.b  <x_offset>                 ; Signed byte (S2 uses dc.w for X)

Key difference from S2: X offset is a single signed byte (-128 to +127), not a word.

Size byte encoding (same as S2):

  • 0x00 = 1x1 (8x8 pixels)
  • 0x05 = 2x2 (16x16 pixels)
  • 0x0F = 4x4 (32x32 pixels)

Level Data Differences

AspectSonic 1Sonic 2
Block size256x256 pixels128x128 pixels
Block mappingsmap256/ dirmappings/128x128/ dir
Chunk mappingsmap16/ dirmappings/16x16/ dir
Level layoutsUncompressed levels/*.binKosinski compressed
Layout indexWord offsets from baseWord offsets from base
Object positionsobjpos/*.binInline in main ASM
Collision indicesPer-zone .bin in collide/Per-zone .bin in collision/

Common Search Patterns

Finding Badnik Art

bash
# Search for specific badnik
mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s1 search Crabmeat" -q

# Find all Nemesis art
mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s1 search Nem_" -q

Finding Zone Data

bash
# All GHZ resources
mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s1 search GHZ" -q

# Zone palette
mvn exec:java -Dexec.mainClass="uk.co.jamesj999.sonic.tools.disasm.RomOffsetFinder" -Dexec.args="--game s1 search Pal_LZ" -q

Finding Object Code

Look directly in the disassembly files:

bash
# Crabmeat object code
cat docs/s1disasm/_incObj/"1F Crabmeat.asm"

# Crabmeat animation
cat docs/s1disasm/_anim/Crabmeat.asm

# Crabmeat mappings
cat docs/s1disasm/_maps/Crabmeat.asm

RAM Address Reference

Key RAM addresses for understanding Sonic 1 disassembly:

AddressNameDescription
$FFFFCF00Object_RAMObject status table base
$FFFFF700Camera_X_posCamera X position
$FFFFF704Camera_Y_posCamera Y position
$FFFFFB00v_lvllayoutLevel layout pointer
$FFFFF600v_gamemodeCurrent game mode
$FFFFF628v_ringsRing count
$FE00v_palettePalette RAM

Quick Reference Card

code
Search:  --game s1 search <pattern>      Find items by name
List:    --game s1 list [type]           List items (nem/kos/bin)
Test:    --game s1 test <offset> <type>  Test decompression
Verify:  --game s1 verify <label>        Check calculated offset
Export:  --game s1 export <type> [prefix] Generate Java constants

Troubleshooting

Address Verification

Critical: Addresses derived from s1disasm labels may NOT match the compiled ROM binary exactly. The disassembly source uses labels that resolve to different offsets depending on assembly options and ROM revision. Always verify addresses by searching the actual ROM binary for known data patterns. See MEMORY.md for verified addresses.

"Item not found"

  • Check spelling and case sensitivity
  • Try partial names (e.g., "Crab" instead of "Crabmeat")
  • S1 labels use Nem_ prefix, not ArtNem_
  • Use list command to see all items of a type

Compression Detection

  • Files in artnem/ are Nemesis regardless of .bin extension
  • Files in artkos/ are Kosinski regardless of extension
  • Files in artunc/ are raw uncompressed data