Shared base for pure-Python C64 SID tracker parsers: PSID/RSID container, loaded-image model, and packed/relocating playroutine detection
Project description
pysidtracker
Shared base for the pure-Python C64 SID tracker parsers (pygoattracker, pysidwizard, pydmcsid, pyfuturecomposer, pymusicassembler, pydefmon, pyjch, pysoundmonitor).
Reads .sid containers (PSID/RSID) and bare .prg images into a 64 KiB C64
memory model, and detects packed/relocating playroutines by running the tune's
init in a 6502 emulator — container headers are not trusted. Each format
package subclasses BaseSidParser for a consistent read / parse / detect
API.
Components
parse_sid_header/SidHeader— PSID/RSID container header parsing.SidImage— a loaded 64 KiB C64 memory image with absolute-addressed accessors, from a.sidcontainer or a bare.prg.read_bytes— path /bytes/ file-like source dispatch.SidErrorhierarchy —SidParseError,SidFormatError,EmulatorUnavailable.detect_playroutine/PlayroutineKind— static signature recognition, then an emulated init run to classifyDIRECT/RELOCATED/PACKED/UNKNOWN.BaseSidParser— the base class each format subclasses.CodePattern/find_code_all/find_code_first— masked 6502 code-fragment search with operand capture.registers— C64 hardware register map (SID/CIA/VIC, IRQ/NMI and CPU vectors) with predicates andfind_register_stores.trace_init/InitTrace— run a tune's init under a write observer to report CIA timer cadence and the IRQ/NMI vectors an IRQ-driven header hides.playroutine_cadence/Cadence/TriggerSource— derive the play-routine cadence (PAL/NTSC video frame vs CIA-timer latch) from what init programs, not the header.native_decrunch— native exomizer unpack (pydexomizer), an init-free alternative depack path; opt-in viadetect_playroutine(..., native=True).reglog—RegWriteregister-log format (read_reglog/write_reglog) andframe_writes, the shared per-frame SID-write framing loop.oracle— per-frame SID register grids:register_grid(py65), the stdlibgrid_from_writesframer,read_sidwr(preframr-sidtrace.sidwr.bin), andaligned_match.testing— HVSC tune fetch/resolve for test suites (fetch_tune,resolve_tune,make_tune_fixtures).audio—render_samples/render_wavthrough an emulated SID (pyresidfp,audioextra), plusresolve_device/seconds_to_frames.- Writers —
SidHeader.to_bytes/write_psid/SidImage.to_prg(the inverse of the parsers),parse_prg, andencode_cstr/decode_cstr. SidImageabsolute-address accessors —byte_at/word_at/contains/poke, relocation-safe and bounds-checked.mos6502— shared 6502 primitives:OP_LEN, opcode-class sets,s8/adc/sbc,SidWriteCapturingMemory,walk_until.MemPlayer— per-frame register-diff player scaffold; subclasses implement_init/_frame.register_writes_from_playerdrives it to a reglog.notefreq—NoteFreqTable, computed PAL/NTSC pitch tables, andlocate_note_freq(find hi/lo tables from paired absolute-indexed reads).make_package_errors— per-package error hierarchy factory whose*ParseError/*FormatErrorsubclass the base ones, so baseexceptclauses catch them.cli— shared argparse scaffold:run_cli,add_reglog_command,add_wav_command,print_info.registersadditions —SID_VOICES, voice/global register indices, and theattack_decay/sustain_releaseADSR nibble packers.resolve_entry_points/is_jmp_vector,cadence_from_latch, and theByteCursor/check/byte_rangeparse helpers.
Install
pip install pysidtracker # core (includes py65 for init emulation)
pip install pysidtracker[fast] # + numpy, to accelerate the image scan
pip install pysidtracker[audio] # + pyresidfp, for WAV/sample rendering
py65 and pydexomizer are required core dependencies (detection runs a tune's
6502 init, and native_decrunch unpacks exomizer-packed images natively).
numpy is optional; a pure-stdlib scan is used when it is absent.
Usage
from pysidtracker import BaseSidParser, PlayroutineKind
class MyParser(BaseSidParser):
def recognize(self, image):
return image.find(b"MYSIG") # truthy anchor when found
def parse(self, data, **kw):
image = self.load_image(data) # .sid or .prg -> SidImage
... # decode image.mem into a model
det = MyParser().detect("tune.sid")
if det.kind is PlayroutineKind.PACKED:
... # header was not trustworthy
Development
pip install -e ".[dev]"
pytest --cov=pysidtracker
See docs/design.md for the detection model and shared primitives.
License
Apache 2.0 — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pysidtracker-0.5.0.tar.gz.
File metadata
- Download URL: pysidtracker-0.5.0.tar.gz
- Upload date:
- Size: 74.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd2bc867cd131348457482e73d33c8401bc9b5fade1deac7b9adf2503473a3b3
|
|
| MD5 |
fbccf214f6484d8e15e56eb0e075f0d3
|
|
| BLAKE2b-256 |
cd4877ab48e0267d3343f0f11fc80a9d13a2309002a812484d0465b27fbe429a
|
Provenance
The following attestation bundles were made for pysidtracker-0.5.0.tar.gz:
Publisher:
publish.yml on anarkiwi/pysidtracker
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pysidtracker-0.5.0.tar.gz -
Subject digest:
fd2bc867cd131348457482e73d33c8401bc9b5fade1deac7b9adf2503473a3b3 - Sigstore transparency entry: 2139759800
- Sigstore integration time:
-
Permalink:
anarkiwi/pysidtracker@ba6a2553aff3f66f81388a996ab9a8f905e88575 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/anarkiwi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ba6a2553aff3f66f81388a996ab9a8f905e88575 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pysidtracker-0.5.0-py3-none-any.whl.
File metadata
- Download URL: pysidtracker-0.5.0-py3-none-any.whl
- Upload date:
- Size: 61.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e3b1d942ae7125ff609ac5a1eeea7033c23cb36bedcbc9aef73571de7d36653
|
|
| MD5 |
7493291329d99ff5d6fc774ac12ab3ce
|
|
| BLAKE2b-256 |
c59b8f375bef1fe179807511d5e9dc5009c528440d0725b93600f6fd8a6f4dee
|
Provenance
The following attestation bundles were made for pysidtracker-0.5.0-py3-none-any.whl:
Publisher:
publish.yml on anarkiwi/pysidtracker
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pysidtracker-0.5.0-py3-none-any.whl -
Subject digest:
1e3b1d942ae7125ff609ac5a1eeea7033c23cb36bedcbc9aef73571de7d36653 - Sigstore transparency entry: 2139759837
- Sigstore integration time:
-
Permalink:
anarkiwi/pysidtracker@ba6a2553aff3f66f81388a996ab9a8f905e88575 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/anarkiwi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ba6a2553aff3f66f81388a996ab9a8f905e88575 -
Trigger Event:
release
-
Statement type: