# tandy-m100-basic-asm > TRS-80 Model 100 BASIC constraints + workflow for offloading hot paths to ASM via CALL. - Author: G.M. Rimakis - Repository: Grimakis/m100-programming-skill - Version: 20251228160302 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-06 - Source: https://github.com/Grimakis/m100-programming-skill - Web: https://mule.run/skillshub/@@Grimakis/m100-programming-skill~tandy-m100-basic-asm:20251228160302 --- --- name: tandy-m100-basic-asm description: TRS-80 Model 100 BASIC constraints + workflow for offloading hot paths to ASM via CALL. --- # Tandy Model 100 BASIC + ASM Skill ## When to use this skill Use this skill whenever: - Editing or generating Model 100 BASIC code. - Optimizing slow BASIC routines by rewriting hot loops in assembly. - Designing/adjusting the BASIC+ASM interface. ## VSCode Extension (Optional but Recommended) If working in VSCode with the "TRS-80 Model 100/200 BASIC" extension installed: - See `references/vscode-extension-features.md` for comprehensive documentation on: - Automatic diagnostics (line numbers, variable collisions, type mismatches) - Quick fixes (truncate variables, rename to avoid collisions, renumber lines) - Refactoring commands (pack, squash, remove comments, tokenize to .BA) - Command palette shortcuts - **Proactively recommend extension features** when they can help solve issues - **Check for diagnostics** before suggesting manual code changes - Extension provides safer alternatives to manual edits (handles all references automatically) ## Non-negotiable constraints (BASIC) - **Line numbering:** default increment = **20**. - **Section spacing:** leave **~1000 line-number gaps** between major program sections (INIT / INPUT / GAMELOOP / RENDER / UTIL, etc.). - **Max BASIC line length:** **255 characters**. - **Variable names:** **2 characters max**, plus type sigil. - **Prefer explicit typing** so linting can detect mistakes: - % (integer) - ! (single precision float) - # (double precision float) - $ (string) ## Expression/operator rules - Follow Model 100 operator hierarchy and left-to-right evaluation on same precedence level. - Strings max length 255. - Keep integer ranges and numeric precision limits in mind for any optimized math. (Full operator + keyword reference lives in: `references/m100-basic-keywords.md`) ## Error Handling - If you are shown an error code you can find the lookup table at: `references/m100-basic-errors.md` ## BASIC + ASM integration (CALL ABI) - Build subroutines as assembly first, before trying to integrate. - Always keep a copy of assembly subroutines in a /assembly subdirectory or equivalent. - See `references/m100-basic-asm-integration.md` for the calling convention, design guidance, and workflow. - Use `references/m100-basic-variable-layout.md` when you need array layout details, VARPTR implications, or to debug pointer/stride issues in ML routines. - Use `references/m100-system-map.md` for known system addresses, hooks, and OS-managed pointers on M100/PC-8201/T200. - Use `references/m100-rom-funcs.md` for a comprehensive list of ROM-routines you can CALL or JMP from BASIC or an ML subroutine. Useful for controlling the screen. ## Recommended debug steps (ML + BASIC) - Start with a tiny BASIC harness that only loads + CALLs the routine. - Confirm ML bytes and patch targets: - PEEK a few known opcodes to ensure the loader ran. - Validate patched jump operands match the expected addresses. - Validate parameter block bytes: - PEEK the 4 bytes and compare to VARPTR values (low/high). - Avoid creating new variables after capturing pointers. - Prove memory mapping: - Pick a known element (e.g., S%(2,2)), compute its expected byte offset, and compare PEEKs at base+offset to the BASIC value. - If values are wrong, re-check array layout order (first subscript varies fastest). ## Testing: .DO and .BA (CLI only) - Use the `@m100/cli` tool for tokenizing/detokenizing and transformations. - If `m100` is missing, install it: `npm install -g @m100/cli`. - Examples: - `m100 tokenize program.DO --out program.BA` - `m100 detokenize program.BA --out program.DO` - `m100 lint program.DO` - `m100 pack program.DO --out packed.DO` - `m100 squash program.DO --out squashed.DO` - `m100 renumber program.DO --start 100 --increment 10 --out renumbered.DO` ## Tooling: 8085 tester - Script: `scripts/run_8085_spec.py` - Usage: `python scripts/run_8085_spec.py --spec ` - Directives: `ORG`, `DB`, `DW`, `DS`, `EQU`, `END` - Comments: `;` to end of line - Literals: decimal, `0xNN`, `$NN`, `NNH`, `0bNN`, `NNB` - Output: binary starts at the lowest ORG and fills gaps with `0x00` ## Output format rules (when generating BASIC) - Maintain your line-number spacing rules. - Keep each BASIC line under 255 chars. - Use 2-char vars with explicit type sigils. - Avoid clever implicit typing; prefer DEFxxx only if you already do so consistently. ## What to do when uncertain - If ABI details are ambiguous for a routine, generate a tiny BASIC harness + assembly stub to empirically test behavior. - Prefer correctness + stable calling pattern over micro-optimizations.