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.
- leosplit-1.1.0a1/PKG-INFO +195 -0
- leosplit-1.1.0a1/README.md +177 -0
- leosplit-1.1.0a1/pyproject.toml +37 -0
- leosplit-1.1.0a1/setup.cfg +4 -0
- leosplit-1.1.0a1/src/leosplit/__init__.py +3 -0
- leosplit-1.1.0a1/src/leosplit/disassembler/__init__.py +1 -0
- leosplit-1.1.0a1/src/leosplit/disassembler/leosplit_asm.py +812 -0
- leosplit-1.1.0a1/src/leosplit/extractor/__init__.py +1 -0
- leosplit-1.1.0a1/src/leosplit/extractor/leosplit_extract.py +614 -0
- leosplit-1.1.0a1/src/leosplit/manifestor/__init__.py +1 -0
- leosplit-1.1.0a1/src/leosplit/manifestor/leosplit_manifest.py +429 -0
- leosplit-1.1.0a1/src/leosplit.egg-info/PKG-INFO +195 -0
- leosplit-1.1.0a1/src/leosplit.egg-info/SOURCES.txt +17 -0
- leosplit-1.1.0a1/src/leosplit.egg-info/dependency_links.txt +1 -0
- leosplit-1.1.0a1/src/leosplit.egg-info/entry_points.txt +4 -0
- leosplit-1.1.0a1/src/leosplit.egg-info/top_level.txt +1 -0
- leosplit-1.1.0a1/tests/test_asm.py +218 -0
- leosplit-1.1.0a1/tests/test_extract.py +179 -0
- leosplit-1.1.0a1/tests/test_manifest.py +66 -0
|
@@ -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 @@
|
|
|
1
|
+
"""Splat-like assembly workspace generation."""
|