| name | annotate-6809-6309-assembly |
| description | Annotate Motorola 6809 and Hitachi 6309 assembly source by adding clear comments to each code line and introducing sensible labels when labels are missing or weak. Use when Codex needs to explain, clean up, or reverse-engineer 6809/6309 assembly listings, ROM disassemblies, monitor source, game code, firmware, macros, data tables, or mixed code/data files without changing program behavior. |
Annotate 6809 6309 Assembly
Annotate 6809 or 6309 assembly in-place so the result is easier for a human to read, review, and continue editing. Preserve behavior, preserve the assembler dialect as much as possible, and default to comment-only edits unless the user explicitly asks for label changes.
Workflow
- Scan the file before editing anything.
- Identify the assembler style already in use:
- comment delimiter, which should be
;
- label column and indentation style
- exported entry labels, which should be written with a trailing colon only when the same symbol has an
EXPORT declaration
- opcode casing, but normalize opcodes and register-like operand tokens to lowercase in the final output
- directives such as
ORG, EQU, FCB, FDB, RMB, FCC
- local-label conventions, if any, including
@-suffixed locals
- Inspect the source header before code/data annotation:
- preserve any existing meaningful title, copyright/license, author, usage, platform, and module-purpose text
- if there is no OS-9-style edit history, add an
Edt/Rev YYYY/MM/DD Modified by history block in the opening comment header
- if a history block exists but uses weak labels such as only
History, Changes, or loose dated notes, normalize it into the OS-9-style Edt/Rev format while preserving the information
- use today's date only for a new annotation/update entry; do not invent historical dates, revision numbers, or author names
- if the author/modifier is unknown, use
Codex for the new annotation/update entry rather than guessing
- keep the header in the file's existing block-comment style; for OS-9 assembly this is usually
* comment lines with separator rows of * or -
- Build a quick map of:
- entry points
- subroutines
- branch and jump targets
- loops
- data tables
- memory-mapped I/O or hardware-related constants
- When disassembling or reverse-engineering function code, identify each function's stack usage:
- parameters
- return address area
- saved registers
- local variables
- temporary stack slots
- For each identified function, define assembler-friendly labels or symbols for stack offsets and use those names in comments and any requested label work instead of hard-coded stack numbers.
- declare stack-offset equates immediately under the function label and above the code they describe
- use the naming form
stk_...
- keep those stack-offset equate names all lowercase
- make each stable stack-shape block start at offset
0, meaning the current top of stack for that frame state
- treat stack-offset equates as valid only for the current stack shape
- after any stack manipulation such as
pshs, puls, leas, bsr, lbsr, jsr, interrupt-frame setup, or local-frame allocation/removal, recompute the offset math before using stk_... names again
- if a routine uses multiple truly different stable stack shapes, define a fresh set of
stk_... equates for each stable state instead of reusing stale offsets
- for short-lived stack changes that only shift an existing frame, do not repeat the same
stk_... names in a second block; keep the original names and use exact byte math such as stk_name+2,s
- when adjusting a stack-relative reference through a temporary push/pop window, account for the full byte width of the saved or restored registers, for example
pshs y shifts later arguments by 2 bytes, pshs d,x shifts them by 4 bytes, and pshs cc shifts them by 1 byte
- Document each identified function's stack frame clearly, including what lives at each named offset and how the routine uses it.
- Identify raw numeric constants that correspond to known symbolic definitions:
- OS calls and service codes
- GetStat and SetStat selectors
- OS error codes
- module-header type and language fields
- file mode, access, and attribute bits
- any other project-wide assembler definitions already available through existing include files
- Replace those raw constants with the proper symbols when doing annotation work, as long as the replacement preserves the exact numeric value and meaning.
- prefer an existing project symbol over introducing a new local
equ
- if the correct shared symbol is missing, add it to the appropriate shared definition include instead of leaving a magic number behind
- do not replace ordinary algorithmic constants, loop bounds, ASCII literals, bit masks, or scratch values unless they clearly correspond to an established symbolic definition
- Add comments to each executable code line, except pseudo-ops that must remain uncommented.
- Do not append comments to conditional pseudo-op lines such as
IFNE, IFEQ, IFGT, IFLT, IFGE, IFLE, IFP1, IFP2, ELSE, or ENDC.
- Apply this exception to equivalent
IF* conditional directives in the assembler dialect.
- Do not append comments to
use, nam, ttl, or pag pseudo-op lines.
- Add or improve labels only if the user explicitly asks for label work, except for stack-offset symbols defined as part of function-frame documentation.
- when an exported symbol is also a label definition, write it with a trailing colon, for example
_foo:, not _foo
- do not add colons to internal/local labels unless they are explicitly exported
- After annotating a file, run the pretty-printer:
python3 /Users/boisy/Projects/coco-shelf/nitros9/scripts/asmprettyprint.py <annotated-file>
- Replace the file contents with the pretty-printed output.
- Do not build, assemble, link, run tests, regenerate archives, or update disk images as part of this skill unless the user explicitly asks for that separate verification step.
- Return the annotated assembly, and briefly note any uncertain interpretations.
Required Output Rules
Labeling Guidance
Apply this section only when the user explicitly asks for label work.
Create labels only when they improve readability. Good candidates:
- subroutine entry points
- loop headers
- conditional branch destinations
- shared fallthrough targets
- dispatch tables
- string or byte tables
- hardware service routines
If the active assembler style supports local labels ending in @, prefer those for short in-scope branch targets instead of inventing a longer global label. Only do this while the target remains in scope; after a blank line, switch to a non-local label.
Use concise, descriptive names based on observed behavior. Prefer names like:
InitVideo
CopySpriteLoop
CheckKeyboard
WaitVBlank
PrintChar
Table_Sine
Ptr_ScreenBuffer
ReturnIfBusy
Avoid vague names like:
Label1
Loop1
Sub1
AddrC123
If you truly do not know the intent, use structured neutral names that still convey role:
Subroutine_C123
BranchTarget_C1A0
Loop_CopyBytes
Table_BytePairs_C400
See references/annotation-patterns.md for naming patterns and examples.
Commenting Guidance
Write comments that explain purpose, not just syntax. Good comment styles include:
- effect on registers or flags when that matters
- why a branch happens
- what a memory location likely represents
- what a loop is copying, scanning, clearing, or counting
- what a data block is used for
Prefer:
LDA ,X+ ; load next byte from source and advance pointer
BEQ Done ; stop when terminator was reached
STD <$10 ; save 16-bit result in temporary work buffer
Avoid restating the mnemonic in empty words:
LDA ,X+ ; load A
BEQ Done ; branch if equal
When flags are the real story, mention them:
CMPA #$0D ; set Z when character is carriage return
BNE ReadNext ; continue until CR is found
When annotating functions that use the stack heavily:
- define stack-offset names near the function entry
- place stack-offset equates directly under the function label
- use lowercase
stk_... names for stack offsets
- start each stable stack-layout block at
0 for the current top of stack, then count upward by bytes
- describe which offsets are parameters, saved registers, locals, or temporaries
- prefer comments like
load parameter pointer or store local byte count over load 6,s
- if the source already has equivalent stack symbols, preserve and improve them instead of inventing a second scheme
- when the routine changes stack depth, stop and recompute the stack math before reusing any
stk_... name
- if needed, create a second or third block of
stk_... equates only when a genuinely new stable stack layout begins
- for short-lived temporary pushes, prefer
stk_name+N,s instead of a second stk_... block, and make N reflect the exact number of bytes added to the stack
When a numeric literal looks like a known platform or project definition:
- prefer
F_*, I_*, SS_*, E_*, mode, attribute, or other shared symbols over raw hex or decimal literals
- add the missing shared definition in the proper include file when the meaning is clear and reused
- keep literals only when they are genuinely local algorithmic values rather than externally defined semantics
Mixed Code And Data
Disassemblies often mix instructions and tables. Before labeling a region as code:
- check whether branch or jump targets enter it
- check for impossible opcode flow
- check for repeating structured bytes
- check for pointer tables or string data
If a region appears to be data, annotate it as data rather than inventing executable behavior.
6309-Specific Notes
- Treat 6309 as a superset of 6809.
- Recognize 6309-only registers and operations such as
E, F, W, Q, MD, TFM, DIVD, DIVQ, MULD, and bit-manipulation instructions.
- Comment 6309-only instructions in terms of their higher-level effect, especially for block transfer or 32-bit math.
Response Shape
When the user asks for direct annotation work:
- Return the edited assembly block.
- Keep the code unchanged unless the user explicitly requested label work.
- Call out uncertain areas such as guessed hardware registers, possible jump tables, or ambiguous data/code boundaries.
When the user asks for guidance instead of a rewrite:
- Explain the likely control flow.
- Suggest label names and comment wording.
- Identify any ambiguous targets or data regions.