reading-assembly
Skill4 starsChanged 7 months agoMITView on GitHub
Read and translate RISC OS ObjAsm/ARM assembly into another language, PyModule, tests, or interface documentation. Use when converting `s/*` assembler modules, reconstructing SWI behaviour, validating comments against generated tables/disassembly, or proving binary-compatible data layout and boundary behaviour.
We split this skill into the rules it gives an agent
27 rules. About 0 are common, 25 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈25
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 14
Start from the public module surface, not the algorithm comments.
- Distinctive: line 15
Read the module header, exported headers, SWI names table, command table, service table, and error blocks before translating implementation …
- Distinctive: line 22
Treat comments as hypotheses.
- Distinctive: line 23
Verify them against instructions, generated lookup tables, and the built binary.
- Distinctive: line 38
Write independent behavioural tests.
- Distinctive: line 39
Use a second implementation in BASIC, C, or a small host script to generate expected results.
- Distinctive: line 45
Use this order when source is available:
- Distinctive: line 68
Do not infer source pixel order from words like "leftmost" in comments.
- Distinctive: line 80
Create a tiny data test that prints raw output words.
- Distinctive: line 89
Check whether index 0 is omitted because code avoids zero lookups.
- Very specific: line 90
Check negative indexing such as LDRB ..., [table, -index].
- Distinctive: line 92
Check whether version conditionals select a different table layout.
- Distinctive: line 94
If a direct mathematical translation disagrees with the native module, inspect the table bytes and derive the weights or values from them.
- Distinctive: line 99
Read the path after the main inner loop separately.
- Distinctive: line 118
When a routine appears to hand work off to a symbol that is not defined nearby:
- Distinctive: line 121
treat those helper sources as part of the same implementation unit
- Distinctive: line 122
if code is not provided, ask the user for implementation details or example code
- Distinctive: line 140
Prefer a clear reference implementation first:
- Distinctive: line 144
Run the tests against the original module.
- Distinctive: line 146
Run the same tests against the conversion.
- Distinctive: line 147
Add edge cases for validation failures, empty/null inputs, and final-word boundaries.
- Distinctive: line 150
When converting to a PyModule:
- Very specific: line 154
Use self.ro.memory[address].byte, .word, read_bytes, and write_bytes for guest memory.
- Distinctive: line 159
Keep the Python code readable.
- Distinctive: line 164
Before declaring a conversion correct:
- Distinctive: line 166
Run tests against the original assembled module and the converted module.
- Distinctive: line 169
Check raw output words, not only rendered images or high-level summaries.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Reading Assembly For Conversion
Core Workflow
- Start from the public module surface, not the algorithm comments. Read the module header, exported headers, SWI names table, command table, service table, and error blocks before translating implementation code.
- Record the calling contract before writing code: input registers, output registers, preserved/corrupted registers, V flag behaviour, processor mode, IRQ state, and error block numbers/messages.
- Treat comments as hypotheses. Verify them against instructions, generated lookup tables, and the built binary. Old assembler comments often describe the intended maths but not the exact boundary behaviour or packing order.
- Validate external interfaces against documentation before translating calls that cross a module, vector, SWI, or service boundary. If the register contract cannot be found in local docs, PRM-in-XML, source comments, or an authoritative external reference, report that uncertainty to the user instead of filling in registers from guesswork.
- Translate the observed behaviour, not the apparent structure. It is acceptable for the target language to use clear loops where the assembler uses lookup tables, register reuse, or carry tricks, but outputs and errors must match exactly.
- Write independent behavioural tests. Use a second implementation in BASIC, C, or a small host script to generate expected results. Run the same tests against the original module and the converted implementation.
What To Read
Use this order when source is available:
docs/*andprminxml/*to provide development and implementation details.hdr/*or exported interface files: SWI base, names, "internal use" notes.- any equivalent C reference implementation
- Module header in
s/*: title, help string, SWI chunk, handler offsets, feature flags, command table, message file. - SWI dispatch code: how R11 or reason registers are decoded, and how unknown SWIs branch to errors.
- Entry comments near labels: useful for register contracts, but verify.
- Parameter checks: bit masks, signed comparisons, null cases, and special exits.
- Main loops: pointer increments, loop counters, alignment assumptions, and final-iteration paths.
- Generated tables: table shape and indexing direction may reveal the true algorithm better than prose comments.
- Built binary with
riscos-dumpi: final code after conditional assembly, macro expansion, version conditionals, and linker layout.
Assembly Patterns To Prove
Bit And Nibble Order
Do not infer source pixel order from words like "leftmost" in comments. Check the actual shifts and masks:
AND ..., word, LSR shiftwithshift += 4reads from low bits upward.ORR outword, pixel, outword, LSR #4packs each new high-nibble pixel while shifting earlier pixels downward; the stored word may have the first output pixel in the least significant nibble after finalisation.- A final
MOV outword, outword, LSR #4beforeSTRchanges the apparent packing order. - Cross-word cases using
oldword LSR #nandnewword LSL #(32-n)may start at a different source bit than the regular loop.
Create a tiny data test that prints raw output words. Compare the first word against candidate interpretations before committing to a data layout.
Lookup Tables
For generated DCB tables:
- Reconstruct the formula by testing table entries, not by trusting nearby comments.
- Check whether index 0 is omitted because code avoids zero lookups.
- Check negative indexing such as
LDRB ..., [table, -index]; the label may point to the middle or end of a combined table. - Check whether version conditionals select a different table layout.
If a direct mathematical translation disagrees with the native module, inspect the table bytes and derive the weights or values from them.
Boundary Paths
Read the path after the main inner loop separately. It often handles the last pixel or the word boundary and may not be equivalent to the regular loop.
Watch for:
- Column counters based on byte stride rather than pixel count.
- "Do not do last pixel" branches that leave the final nibble unused.
- Cross-word reads that intentionally use bits from the next source word.
- Reads which assume spare storage or an unused end bit.
- Null operations such as
SUBS rowcount, rowcount, #3followed by an immediate return on equality.
Included helper sources
Some RISC OS sources mix assembler dispatch code with included helper
implementations. In the SpriteOp sources, for example, SprExtend pulls in the
tiling implementation from s_c.tile after gettile_renderfunc. If you only
read the entrypoint and stop there, you will miss the real algorithm.
When a routine appears to hand work off to a symbol that is not defined nearby:
- scan the bottom of the file for
GETincludes - treat those helper sources as part of the same implementation unit
- if code is not provided, ask the user for implementation details or example code
Error handling
Translate exact error behaviour:
- V set returns R0 as an error block pointer.
- V clear may still corrupt R0 if the contract says so.
- Standard-looking errors may use module-local tokens with standard error numbers.
- Parameter checks such as
AND rowcount,#&80000003also reject negative values; preserve that, rather than checking onlyvalue MOD 4.
For PyModules, raise RISCOSSyntheticError(ro, number, message) when matching
an existing module error that is not naturally defined by error_base.
Conversion Strategy
Prefer a clear reference implementation first:
- Implement a direct version in the target language.
- Build BASIC tests that calculate expected values independently.
- Run the tests against the original module.
- Fix the reference if the original proves different from the comments.
- Run the same tests against the conversion.
- Add edge cases for validation failures, empty/null inputs, and final-word boundaries.
When converting to a PyModule:
- Define
swi_base,swi_prefix, andswi_namesfrom the assembler header. - Dispatch by SWI offset.
- Use
self.ro.memory[address].byte,.word,read_bytes, andwrite_bytesfor guest memory. Do not use host file or byte objects as substitutes for RISC OS memory. - Preserve guest-visible side effects: output size, untouched padding, error flags, and which registers are intentionally left alone.
- Keep the Python code readable; performance optimisations can wait until behavioural tests are green.
Validation Checklist
Before declaring a conversion correct:
- Run tests against the original assembled module and the converted module.
- Include tests for both normal and error paths.
- Include at least one case that crosses an input word boundary.
- Check raw output words, not only rendered images or high-level summaries.
- Re-run documentation lint/build if interface documentation was corrected.
- Note any case where source comments were corrected because the binary proved different behaviour.
In this repository47 other files it gives its agents.
- allocating-resourcesSkill
- ci-testingSkill
- creating-pull-requestsSkill
- designing-modulesSkill
- porting-to-riscos-cSkill
- riscos-commandsSkill
- riscos-desktop-fileractionSkill
- riscos-filer-likeSkill
- riscos-filesystemSkill
- riscos-graphics-convertersSkill
- riscos-network-dcistatisticsSkill
- riscos-network-resolverSkill
- riscos-outputSkill
- riscos-reSkill
- riscos-styleSkill
- riscos-throwbackSkill
- riscos-urls-fetchingSkill
- riscos-urls-launchingSkill
- riscos-wimp-appSkill
- riscos-wimpSkill
- riscos-wimp-templatesSkill
- updating-robe-skillsSkill
- using-bbcbasicSkill
- using-cmhgSkill
- using-ghSkill
- using-gitSkill
- using-libasmSkill
- using-libgcontextSkill
- using-liboslibSkill
- using-libriscoslibSkill
- using-libtoolboxSkill
- using-makefilesSkill
- using-perlSkill
- using-stronghelpSkill
- using-toolbox-imagefilegadgetSkill
- using-tooltesterSkill
- writing-assemblySkill
- writing-assembly-testsSkill
- writing-cmodulesSkill
- writing-cplusplusSkill
- writing-cSkill
- writing-fortranSkill
- writing-oslib-defsSkill
- writing-pascalSkill
- writing-prminxmlSkill
- writing-pymodulesSkill
- writing-pyromaniac-integration-testsSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

