leosplit 1.1.0a1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,195 @@
1
+ Metadata-Version: 2.4
2
+ Name: leosplit
3
+ Version: 1.1.0a1
4
+ Summary: 64DD disk image splitting and decompilation helpers
5
+ Author: leosplit contributors
6
+ Keywords: 64dd,n64,decompilation,romhacking,splat
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Environment :: Console
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Topic :: Software Development :: Disassemblers
15
+ Classifier: Topic :: System :: Archiving
16
+ Requires-Python: >=3.9
17
+ Description-Content-Type: text/markdown
18
+
19
+ # leosplit
20
+
21
+ A binary splitting tool for 64DD `.ndd` images, built to assist decompilation and modding projects.
22
+
23
+ `leosplit` is intended to fill a role similar to Splat for 64DD disk images:
24
+ identify loadable binaries, record their disk/LBA and RDRAM mapping metadata,
25
+ then extract those ranges into standalone files for tools like Ghidra.
26
+
27
+ ## Features
28
+
29
+ - **64DD Load Table Detection**: Finds LBA ranges paired with N64 RDRAM load/entry addresses
30
+ - **Mario Artist 64DD Metadata Fallback**: Extracts repeated disk metadata labels only when no load tables are found
31
+ - **DOL Fallback**: Automatically detects and parses GameCube DOL executable files if native metadata is not found
32
+ - **Multiple Output Formats**: JSON (default) or YAML output
33
+ - **File Identification**: Extracts cartridge file/module names and metadata
34
+ - **MFS Binary Extraction**: Traverses 64DD MFS directory entries and carves exact byte ranges from `.ndd` images
35
+ - **Manifest Binary Extraction**: Still supports generated manifests for load-table based workflows
36
+ - **Splat-like Assembly Workspace**: Emits raw bins, MIPS assembly listings, symbol hints, and a YAML segment skeleton
37
+
38
+ ## Usage
39
+
40
+ Install for local development:
41
+
42
+ ```bash
43
+ python -m pip install -e .
44
+ ```
45
+
46
+ Generate a manifest:
47
+
48
+ ```bash
49
+ leosplit-manifest input.ndd -o manifest.json
50
+ ```
51
+
52
+ Extract files directly from a 64DD MFS image:
53
+
54
+ ```bash
55
+ leosplit-extract input.ndd -o extracted
56
+ ```
57
+
58
+ List detected MFS entries without extracting:
59
+
60
+ ```bash
61
+ leosplit-extract input.ndd --list
62
+ ```
63
+
64
+ Extract binaries from a manifest:
65
+
66
+ ```bash
67
+ leosplit-extract input.ndd manifest.json -o extracted
68
+ ```
69
+
70
+ Create a Splat-like assembly workspace from the manifest:
71
+
72
+ ```bash
73
+ leosplit-asm input.ndd manifest.json -o split --overwrite --verbose
74
+ ```
75
+
76
+ LeoSplit infers the YAML project name and basename from known 64DD disk codes,
77
+ manifest metadata, embedded title strings, or finally the image filename. It
78
+ also emits a compiler guess with a detection reason. Override any of these when
79
+ you know better:
80
+
81
+ ```bash
82
+ leosplit-asm NUD-DSCJ-JPN.ndd simcity64.json -o split-simcity --overwrite \
83
+ --name "SimCity 64" --basename simcity64 --compiler IDO
84
+ ```
85
+
86
+ Restrict disassembly when you know a specific code span:
87
+
88
+ ```bash
89
+ leosplit-asm input.ndd manifest.json -o split --overwrite \
90
+ --code-range 3:0x80280000-0x802C0000
91
+ ```
92
+
93
+ This writes:
94
+ - `split/bin/*.bin`: exact carved segment bytes
95
+ - `split/asm/*.s`: big-endian MIPS assembly listings using manifest VRAM addresses
96
+ - `split/symbols/*.sym`: entry labels, branch/jump labels, and rough data boundary hints
97
+ - `split/leosplit.yaml`: a Splat-style segment skeleton for the project
98
+
99
+ The manifest includes:
100
+ - `file_id`: Unique identifier for each file entry
101
+ - `file_name`: Extracted cartridge metadata or file name
102
+ - `lba_start`: Logical block address (sector-based offset)
103
+ - `lba_length`: Length in sectors
104
+ - `load_address`: N64 RDRAM load address (if available)
105
+ - `entry_point`: N64 program entry point (if available)
106
+
107
+ ## Output Formats
108
+
109
+ - **JSON** (default): `leosplit-manifest input.ndd -o manifest.json`
110
+ - **YAML**: `leosplit-manifest input.ndd --format yaml`
111
+
112
+ The extractor accepts either generated JSON or generated YAML:
113
+
114
+ ```bash
115
+ leosplit-extract NUD-DMTJ-JPN1.ndd talentstudio.json -o extracted
116
+ leosplit-extract NUD-DMTJ-JPN1.ndd talentstudio.yaml -o extracted --overwrite
117
+ ```
118
+
119
+ ## Example
120
+
121
+ ```bash
122
+ # Generate JSON manifest
123
+ leosplit-manifest NUD-DMTJ-JPN1.ndd -o manifest.json
124
+
125
+ # Output YAML to stdout
126
+ leosplit-manifest input.ndd --format yaml
127
+
128
+ # Verbose output with parsing details
129
+ leosplit-manifest input.ndd --verbose
130
+
131
+ # Extract files and print offsets/load addresses
132
+ leosplit-extract input.ndd manifest.json -o extracted --verbose
133
+
134
+ # Build a decompilation workspace with asm and symbol hints
135
+ leosplit-asm input.ndd manifest.json -o split --overwrite --verbose
136
+ ```
137
+
138
+ Extractor output files are named with the manifest ID and sanitized file name,
139
+ for example `extracted/03_NICHIYOUBI.bin`.
140
+
141
+ ## How It Works
142
+
143
+ 1. **Primary Method**: Scans for 64DD load table records
144
+ - Looks for `lba_start`, `lba_end`, `ram_start`, `ram_end`, and entry/init addresses
145
+ - Keeps clustered records to avoid treating random data as files
146
+ - Uses nearby ASCII labels when available, otherwise names entries by table offset
147
+
148
+ 2. **Fallback Method**: If no metadata found, searches for embedded DOL (GameCube executable) headers
149
+ - Validates DOL header structure
150
+ - Extracts load address and entry point from RDRAM addresses
151
+
152
+ 3. **Direct MFS Extraction**: Reads 64DD MFS directory entries
153
+ - Uses the real zone-dependent `.ndd` LBA map for full 64DD images
154
+ - Applies each entry's start LBA, intra-block offset, and byte-exact file size
155
+ - Writes carved files using their MFS name/type metadata
156
+
157
+ 4. **Manifest Extraction**: Reads each manifest entry
158
+ - Uses the real `.ndd` LBA map for full 64DD images, or fixed sectors for test images
159
+ - Reads `lba_length` blocks unless a byte-exact `file_size` is present
160
+ - Writes the result as a standalone `.bin`
161
+
162
+ 5. **Assembly Workspace Generation**: Uses manifest load metadata as segment hints
163
+ - Treats each carved file as a loaded N64 MIPS segment
164
+ - Infers project name/basename from disk code, embedded strings, manifest data, or filename
165
+ - Detects obvious compiler markers, otherwise records the N64/N64DD IDO default assumption
166
+ - Disassembles words using big-endian MIPS decoding
167
+ - Accepts explicit code ranges by file ID, manifest name, or generated segment name
168
+ - Labels entry points and local branch/jump targets
169
+ - Emits comments for possible data boundaries such as string regions and long zero runs
170
+
171
+ ## Testing
172
+
173
+ ```bash
174
+ python -m pytest
175
+ ```
176
+
177
+ ## Sample Output
178
+
179
+ ```json
180
+ {
181
+ "source_file": "NUD-DMTJ-JPN1.ndd",
182
+ "sector_size": 2048,
183
+ "file_count": 17,
184
+ "files": [
185
+ {
186
+ "file_id": 1,
187
+ "file_name": "keyword_pmotion2",
188
+ "lba_start": 43,
189
+ "lba_length": 1,
190
+ "load_address": "0x80218980",
191
+ "entry_point": "0x802189D0"
192
+ }
193
+ ]
194
+ }
195
+ ```
@@ -0,0 +1,177 @@
1
+ # leosplit
2
+
3
+ A binary splitting tool for 64DD `.ndd` images, built to assist decompilation and modding projects.
4
+
5
+ `leosplit` is intended to fill a role similar to Splat for 64DD disk images:
6
+ identify loadable binaries, record their disk/LBA and RDRAM mapping metadata,
7
+ then extract those ranges into standalone files for tools like Ghidra.
8
+
9
+ ## Features
10
+
11
+ - **64DD Load Table Detection**: Finds LBA ranges paired with N64 RDRAM load/entry addresses
12
+ - **Mario Artist 64DD Metadata Fallback**: Extracts repeated disk metadata labels only when no load tables are found
13
+ - **DOL Fallback**: Automatically detects and parses GameCube DOL executable files if native metadata is not found
14
+ - **Multiple Output Formats**: JSON (default) or YAML output
15
+ - **File Identification**: Extracts cartridge file/module names and metadata
16
+ - **MFS Binary Extraction**: Traverses 64DD MFS directory entries and carves exact byte ranges from `.ndd` images
17
+ - **Manifest Binary Extraction**: Still supports generated manifests for load-table based workflows
18
+ - **Splat-like Assembly Workspace**: Emits raw bins, MIPS assembly listings, symbol hints, and a YAML segment skeleton
19
+
20
+ ## Usage
21
+
22
+ Install for local development:
23
+
24
+ ```bash
25
+ python -m pip install -e .
26
+ ```
27
+
28
+ Generate a manifest:
29
+
30
+ ```bash
31
+ leosplit-manifest input.ndd -o manifest.json
32
+ ```
33
+
34
+ Extract files directly from a 64DD MFS image:
35
+
36
+ ```bash
37
+ leosplit-extract input.ndd -o extracted
38
+ ```
39
+
40
+ List detected MFS entries without extracting:
41
+
42
+ ```bash
43
+ leosplit-extract input.ndd --list
44
+ ```
45
+
46
+ Extract binaries from a manifest:
47
+
48
+ ```bash
49
+ leosplit-extract input.ndd manifest.json -o extracted
50
+ ```
51
+
52
+ Create a Splat-like assembly workspace from the manifest:
53
+
54
+ ```bash
55
+ leosplit-asm input.ndd manifest.json -o split --overwrite --verbose
56
+ ```
57
+
58
+ LeoSplit infers the YAML project name and basename from known 64DD disk codes,
59
+ manifest metadata, embedded title strings, or finally the image filename. It
60
+ also emits a compiler guess with a detection reason. Override any of these when
61
+ you know better:
62
+
63
+ ```bash
64
+ leosplit-asm NUD-DSCJ-JPN.ndd simcity64.json -o split-simcity --overwrite \
65
+ --name "SimCity 64" --basename simcity64 --compiler IDO
66
+ ```
67
+
68
+ Restrict disassembly when you know a specific code span:
69
+
70
+ ```bash
71
+ leosplit-asm input.ndd manifest.json -o split --overwrite \
72
+ --code-range 3:0x80280000-0x802C0000
73
+ ```
74
+
75
+ This writes:
76
+ - `split/bin/*.bin`: exact carved segment bytes
77
+ - `split/asm/*.s`: big-endian MIPS assembly listings using manifest VRAM addresses
78
+ - `split/symbols/*.sym`: entry labels, branch/jump labels, and rough data boundary hints
79
+ - `split/leosplit.yaml`: a Splat-style segment skeleton for the project
80
+
81
+ The manifest includes:
82
+ - `file_id`: Unique identifier for each file entry
83
+ - `file_name`: Extracted cartridge metadata or file name
84
+ - `lba_start`: Logical block address (sector-based offset)
85
+ - `lba_length`: Length in sectors
86
+ - `load_address`: N64 RDRAM load address (if available)
87
+ - `entry_point`: N64 program entry point (if available)
88
+
89
+ ## Output Formats
90
+
91
+ - **JSON** (default): `leosplit-manifest input.ndd -o manifest.json`
92
+ - **YAML**: `leosplit-manifest input.ndd --format yaml`
93
+
94
+ The extractor accepts either generated JSON or generated YAML:
95
+
96
+ ```bash
97
+ leosplit-extract NUD-DMTJ-JPN1.ndd talentstudio.json -o extracted
98
+ leosplit-extract NUD-DMTJ-JPN1.ndd talentstudio.yaml -o extracted --overwrite
99
+ ```
100
+
101
+ ## Example
102
+
103
+ ```bash
104
+ # Generate JSON manifest
105
+ leosplit-manifest NUD-DMTJ-JPN1.ndd -o manifest.json
106
+
107
+ # Output YAML to stdout
108
+ leosplit-manifest input.ndd --format yaml
109
+
110
+ # Verbose output with parsing details
111
+ leosplit-manifest input.ndd --verbose
112
+
113
+ # Extract files and print offsets/load addresses
114
+ leosplit-extract input.ndd manifest.json -o extracted --verbose
115
+
116
+ # Build a decompilation workspace with asm and symbol hints
117
+ leosplit-asm input.ndd manifest.json -o split --overwrite --verbose
118
+ ```
119
+
120
+ Extractor output files are named with the manifest ID and sanitized file name,
121
+ for example `extracted/03_NICHIYOUBI.bin`.
122
+
123
+ ## How It Works
124
+
125
+ 1. **Primary Method**: Scans for 64DD load table records
126
+ - Looks for `lba_start`, `lba_end`, `ram_start`, `ram_end`, and entry/init addresses
127
+ - Keeps clustered records to avoid treating random data as files
128
+ - Uses nearby ASCII labels when available, otherwise names entries by table offset
129
+
130
+ 2. **Fallback Method**: If no metadata found, searches for embedded DOL (GameCube executable) headers
131
+ - Validates DOL header structure
132
+ - Extracts load address and entry point from RDRAM addresses
133
+
134
+ 3. **Direct MFS Extraction**: Reads 64DD MFS directory entries
135
+ - Uses the real zone-dependent `.ndd` LBA map for full 64DD images
136
+ - Applies each entry's start LBA, intra-block offset, and byte-exact file size
137
+ - Writes carved files using their MFS name/type metadata
138
+
139
+ 4. **Manifest Extraction**: Reads each manifest entry
140
+ - Uses the real `.ndd` LBA map for full 64DD images, or fixed sectors for test images
141
+ - Reads `lba_length` blocks unless a byte-exact `file_size` is present
142
+ - Writes the result as a standalone `.bin`
143
+
144
+ 5. **Assembly Workspace Generation**: Uses manifest load metadata as segment hints
145
+ - Treats each carved file as a loaded N64 MIPS segment
146
+ - Infers project name/basename from disk code, embedded strings, manifest data, or filename
147
+ - Detects obvious compiler markers, otherwise records the N64/N64DD IDO default assumption
148
+ - Disassembles words using big-endian MIPS decoding
149
+ - Accepts explicit code ranges by file ID, manifest name, or generated segment name
150
+ - Labels entry points and local branch/jump targets
151
+ - Emits comments for possible data boundaries such as string regions and long zero runs
152
+
153
+ ## Testing
154
+
155
+ ```bash
156
+ python -m pytest
157
+ ```
158
+
159
+ ## Sample Output
160
+
161
+ ```json
162
+ {
163
+ "source_file": "NUD-DMTJ-JPN1.ndd",
164
+ "sector_size": 2048,
165
+ "file_count": 17,
166
+ "files": [
167
+ {
168
+ "file_id": 1,
169
+ "file_name": "keyword_pmotion2",
170
+ "lba_start": 43,
171
+ "lba_length": 1,
172
+ "load_address": "0x80218980",
173
+ "entry_point": "0x802189D0"
174
+ }
175
+ ]
176
+ }
177
+ ```
@@ -0,0 +1,37 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "leosplit"
7
+ version = "1.1.0a1"
8
+ description = "64DD disk image splitting and decompilation helpers"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ authors = [
12
+ { name = "leosplit contributors" }
13
+ ]
14
+ keywords = ["64dd", "n64", "decompilation", "romhacking", "splat"]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Environment :: Console",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.9",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Topic :: Software Development :: Disassemblers",
24
+ "Topic :: System :: Archiving"
25
+ ]
26
+
27
+ [project.scripts]
28
+ leosplit-manifest = "leosplit.manifestor.leosplit_manifest:main"
29
+ leosplit-extract = "leosplit.extractor.leosplit_extract:main"
30
+ leosplit-asm = "leosplit.disassembler.leosplit_asm:main"
31
+
32
+ [tool.setuptools.packages.find]
33
+ where = ["src"]
34
+
35
+ [tool.pytest.ini_options]
36
+ testpaths = ["tests"]
37
+ pythonpath = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """64DD disk splitting and decompilation helpers."""
2
+
3
+ __version__ = "1.1.0a1"
@@ -0,0 +1 @@
1
+ """Splat-like assembly workspace generation."""