names.s gives each distinct identifier a 1-byte ID (1-255), comparing
case-insensitively across both PETSCII letter ranges. The table lives in
bank 1: 64 hash-chain heads plus 20-byte records holding the original
spelling. name_declare replaces the first-use spelling with the first
declaration's spelling, so forward references keep the declared form.
A full table returns NAMES_ERR_FULL and writes nothing.
Verified in x128: the C128 dump equals a host model byte for byte across
case variants, an 8-name collision chain with an identical-hash pair, and
a 260-name overflow, with a guard after the table intact. A mutation that
skips the text compare is caught. D120 (proposed): 255-name limit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lexer.s turns cached source lines into tokens with stable kinds and error
codes (tokens.inc): 32 keywords, identifiers folded across both PETSCII
letter ranges, decimal/hex/binary numbers to 65535, strings and character
literals with escapes, all operators, and comments. An error reports its
exact column, then the rest of the line is skipped.
An independent host reference lexer and the C128 lexer in x128 both
reproduce the reviewed golden token files: 10 fixtures, 1,119 tokens,
including one fixture per error kind. A case-folding mutation is caught.
Spec 2.2 now lists <= and >=, matching section 8. D119 (proposed): the \n
and \r escapes both produce $0D. The monitor helper now reads RAM bank 0,
because BASIC ROM hides $4000+ after a program returns.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
src_load reads a SEQ file from device 8 once into a bank-1 cache (D118).
It enforces the 80-byte line, 599-line, and 18,999-byte limits as bytes
arrive and reports stable codes with exact positions. src_rewind and
src_next_line replay the cache one logical line at a time for every pass.
diskio.s wraps the KERNAL file calls; channels close on every path.
Verified in x128 with a 1581: eight fixtures, including the exact limits,
each limit error, a missing file (DOS 62), and a missing final $0D, all
match host-computed line counts, Fletcher-16 checksums, and positions.
Adds a shared PowerShell test library for x128 scripts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add cfg/compiler.cfg, the production mmu.s, c128.inc, and the test mailbox,
proven by a capacity-checking skeleton in x128:
- 8K bottom common RAM, shared code at $1300, private zero page at bank 0
page $1A via P0, bank-1 tables at $2000-$BFFF, test mailbox at $1BF0
- ld65 rejects overflows of the ZP, COMMON, MAIN, SWSTACK, and TABLES areas
- a CIA #2 timer NMI taken under bank 1 with the private zero page returns
cleanly through the NMI guard (closes the E01-S03 NMI risk)
- decision D117 records the map; RESTORE is ignored while compiling
Also pin newLang/ to LF in .gitattributes. A branch switch under
core.autocrlf had rewritten the byte-exact fixtures with CRLF.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vim-user-guide.pdf has no NUL bytes, so git auto-detected it as text and
core.autocrlf rewrote its line endings on checkout, corrupting it. Mark
PDF, PNG, PRG, BIN, and D64/D71/D81 files binary so they are never converted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nova128 is an object-oriented language with an on-machine C128 compiler.
This adds the spec, decisions, architecture, backlog, and story claims,
plus the grammar fixtures (E00-S02), disk-image builder (E07-S01), and
the x128-verified platform probes:
- E01-S01 minimal native PRG
- E01-S02 MMU/common-RAM probe. With bottom common on, a P0/P1 pointer
aimed at bank 1 lands in bank 0 at the translated page. The verifier
traces every MMU write in the probe window.
- E01-S03 KERNAL wrapper (kcall). CHROUT, drive status, and a
device-not-present failure work from bank 0 and bank 1 mappings.
A/X/Y/C/ST are preserved and the MMU state is restored exactly.
- E01-S04 40/80-column display and clock probe
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NOTES records the dd/p, A/I/O/o, :q/:q! and missing-file checks that pass
on the work disk, and that \x03 in -keybuf arrives as RUN/STOP so a script
can leave insert mode.
Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
The single-row painter became vml.s at $C000: one sys() paints all 24
rows, memmove and line-index fix-ups run in ML, and the keyboard buffer
is popped with IRQs masked. dall() repaints only the cursor row or the
whole screen, so j went from 17 to 0-3 jiffies. Loading now checks the
drive error channel and splits lines over 80 columns. The temporary
jiffy counters used to measure the speedup are removed; the numbers are
in NOTES.md.
Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
Power C on the C64 calls ML as sys(addr, &a, &x, &y); the bank argument
from the manual's C128 library page made sys() jump to $000F and crash.
The ML row painter now runs. Quitting resets through $FCE2 because Power C
owns BASIC's zero-page pointers. Notes and Power C skill updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>